UNPKG

node-red-contrib-leap-motion

Version:

Node-Red nodes for leap motion

603 lines (525 loc) 19.4 kB
describe('Controller', function(){ describe('#new', function(){ it('should allow passing in options', function(done) { var controller = fakeController({enableGestures:true}) controller.connection.send = function(message) { if (message == '{"enableGestures":true}') { done(); } } controller.connect() }) }); describe('#connect', function(){ it('should pump frames', function(done) { var controller = fakeController() var count = 0 controller.on('disconnect', done); controller.on('frame', function(frame) { count++; if (count == 3) { controller.disconnect() } }) controller.on('ready', function() { controller.processFrame(fakeFrame()) controller.processFrame(fakeFrame()) controller.processFrame(fakeFrame()) }) controller.connect() }) it('should respond to streaming', function () { var controller = fakeController() assert.equal(controller.streaming(), false); controller.connect() controller.on('streamingStarted', function () { assert.equal(controller.streaming(), true); controller.disconnect() }); controller.on('streamingStopped', function () { assert.equal(controller.streaming(), false); }); }); it('should respond to connected', function(){ var controller = fakeController() assert.equal(controller.connected(), false); controller.connect() controller.on('ready', function() { assert.equal(controller.connected(), true); }); }); }); describe('#disconnect', function() { it('should fire a "disconnect" event', function(done) { var controller = fakeController() controller.on('disconnect', done); controller.on('ready', function() { controller.disconnect() }) controller.connect() }) }) describe('accumulating gestures', function() { it('should accumulate gestures', function(done) { var controller = fakeController({suppressAnimationLoop: true, frameEventName: 'animationFrame'}) var count = 0 controller.on('animationFrame', function(frame) { assert.equal(7, frame.gestures.length); controller.disconnect(); done(); }); controller.on('ready', function() { controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture()]}))); controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture(), fakeGesture()]}))); controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture(), fakeGesture(), fakeGesture(), fakeGesture()]}))); setTimeout(function() { controller.emit('animationFrame', controller.lastConnectionFrame) }, 50) }); controller.connect() }); }); describe('frame events', function(){ it('should fire hand events for frames', function(done){ this.timeout(500); var controller = fakeController(); var handCount = 0; controller.on('hand', function(hand){ handCount++; console.assert(hand.fingers, hand, "is invalid"); if (handCount == 2){ done(); } }); controller.processFrame(fakeFrame({hands: 2})); }); it('should allow frame and hand event binding as options', function(done){ this.timeout(500); var frameCount = 0; var handCount = 0; var controller = fakeController({ frame: function(frame){ frameCount++; console.assert(frame.hands, frame, "is invalid"); }, hand: function(hand){ handCount++; console.assert(hand.fingers, hand, "is invalid"); if (handCount == 2 && frameCount == 1){ done(); } } }); controller.processFrame(fakeFrame({hands: 2})); }); it('should work with leap.loop', function(done){ this.timeout(500); Leap.loopController = fakeController(); Leap.loop({ hand: function(){ done(); Leap.loopController = null; } }); Leap.loopController.processFrame(fakeFrame({hands: 1})); }); it('should work with leap.loop and options', function(done){ this.timeout(500); Leap.loopController = fakeController(); Leap.loop({background: true}, { hand: function(){ done(); Leap.loopController = null; } }); Leap.loopController.processFrame(fakeFrame({hands: 1})); }); it('should work with leap.loop and no arguments', function(done){ this.timeout(500); Leap.plugin('test', function(){ return { frame: function(){ console.log('frame'); done(); Leap.loopController = null; } } }); Leap.loopController = fakeController(); Leap.loop().use('test'); Leap.Controller._pluginFactories = {}; Leap.loopController.processFrame(fakeFrame({hands: 1})); }); }); describe('device events', function() { it('should fire deviceAttached/Removed ', function(done) { var controller = fakeController({version: 5}); var count = 0; controller.on('protocol', function(protocol) { assert.equal(5, protocol.version); controller.disconnect(); done(); }); controller.on('ready', function(protocol) { controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: false, attached: true}}})); controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: false, attached: false}}})); }); var assertFalseFunc = function(deviceInfo) { assert.equal(true,false); //I'm sure there's a better way to do this... }; controller.on('deviceStreaming', assertFalseFunc); controller.on('deviceStopped', assertFalseFunc); controller.on('streamingStarted', assertFalseFunc); controller.on('streamingStopped', assertFalseFunc); controller.on('deviceAttached', function(deviceInfo) { count++; }); controller.on('deviceRemoved', function(deviceInfo) { assert.equal('peripheral', deviceInfo.type); assert.equal(count, 1); }); controller.connect(); }); it('should fire both deviceAttached AND deviceStreaming', function(done) { var controller = fakeController({version: 5}); var count = 0; controller.on('protocol', function(protocol) { assert.equal(5, protocol.version); controller.disconnect(); }); controller.on('ready', function(protocol) { controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: true, attached: true}}})); }); //This shouldn't happen since we're emulating a pre-existing device controller.on('deviceConnected', function() { assert.equal(true,false); }); controller.on('deviceAttached', function(deviceInfo) { assert.equal(count, 0); count++; }); controller.on('deviceStreaming', function(deviceInfo) { assert.equal(count, 1); count++; }); controller.on('streamingStarted', function(deviceInfo) { assert.equal(count, 2); done(); }); controller.connect(); }); it('Should fire deviceConnected & deviceRemoved', function(done) { var controller = fakeController({version: 5}); var count = 0; controller.on('protocol', function(protocol) { assert.equal(5, protocol.version); controller.disconnect(); }); controller.on('ready', function(protocol) { controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: false, attached: true}}})); controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: true, attached: true}}})); controller.connection.handleData(JSON.stringify({event: {type:'deviceEvent', state: { type: 'peripheral', streaming: false, attached: false}}})); }); controller.on('deviceConnected', function() { assert.equal(count, 0); count++; }); controller.on('deviceDisconnected', function() { assert.equal(count, 1); done(); }); controller.connect(); }); }); describe('version warning [browser-only]', function(){ it ('should fire no warning by default', function(done){ this.timeout(500); var controller = fakeController({version: 6}).connect(); controller.on('ready', function(){ assert(controller.checkOutOfDate() == false, 'Should not show version warning dialog'); done(); }); }); it ('should fire warning when out of date', function(done){ this.timeout(500); var controller = fakeController({version: 5}).connect(); controller.on('ready', function(){ assert(controller.checkOutOfDate() == true, 'Should show version warning dialog'); done(); }); }); }); describe('plugins', function(){ Leap.Controller._pluginFactories = {} it('should register plugins', function(){ Leap.Controller.plugin('testPlugin', fakePluginFactory()); assert.equal(Leap.Controller.plugins()[0], 'testPlugin'); Leap.Controller._pluginFactories = {} }); it('should decorate frames', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' } })); var controller = fakeController() controller.use('testPlugin') controller.on('frame', function(frame){ assert.equal(frame.foo, 'bar') }); controller.connect(); controller.processFrame(fakeFrame()) Leap.Controller._pluginFactories = {} }); it('should list plugins being used', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory()); var scope = {color: 'blue'}; var plugins = fakeController() .use('testPlugin', scope) .plugins; assert.equal(plugins.testPlugin, scope); Leap.Controller._pluginFactories = {} }); it('should merge options when re-using', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory()); var scope = {color: 'blue'}; var plugins = fakeController() .use('testPlugin', scope) .use('testPlugin', {color: 'red'}) .plugins; assert.equal(plugins.testPlugin, scope); assert.equal(scope.color, 'red'); Leap.Controller._pluginFactories = {} }); it('should list plugins being used after stopping using a plugin', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory()); var plugins = fakeController() .use('testPlugin') .stopUsing('testPlugin') .plugins; assert.equal(plugins.testPlugin, undefined); Leap.Controller._pluginFactories = {} }); describe('use', function () { it('should accept plugin factories directly', function () { var controller = fakeController() controller.use(function (options) { assert.equal(options.x, 2) return {} }, {x: 2}) }); }); it('should decorate hands, fingers, and pointables', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' }, hand: function(hand){ hand.idWithExclamation = hand.id + '!' }, finger: function(finger){ finger.testFinger = true }, pointable: function(pointable){ pointable.testPointable = true } })); var controller = fakeController() controller.use('testPlugin') controller.on('frame', function(frame){ assert.equal(frame.hands[0].idWithExclamation, '0!') assert.equal(frame.fingers[0].testFinger, true) assert.equal(frame.pointables[0].testPointable, true) }); controller.connect(); controller.processFrame(fakeFrame({hands: 1, fingers: 1})) Leap.Controller._pluginFactories = {} }); it('should stop decorating hands, fingers, and pointables', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' }, hand: function(hand){ hand.idWithExclamation = hand.id + '!' }, finger: function(finger){ finger.testFinger = true }, pointable: function(pointable){ pointable.testPointable = true } })); var controller = fakeController(); controller.use('testPlugin') controller.on('frame', function(frame){ assert.equal(frame.hands[0].idWithExclamation, undefined) assert.equal(frame.fingers[0].testFinger, undefined) assert.equal(frame.pointables[0].testPointable, undefined) }); controller.connect(); controller.stopUsing('testPlugin'); controller.processFrame(fakeFrame({hands: 1, fingers: 1})) Leap.Controller._pluginFactories = {} }); it('should extend frame, hand, and pointable prototypes', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory({ frame: { testFn: function(){ return 'frame'; } }, hand: { testFn: function(){ return 'hand'; } }, pointable: { testFn: function(){ return 'pointable'; } }, finger: { testFnFinger: function(){ return 'finger'; } } })); var controller = fakeController() controller.use('testPlugin') // our test doubles are not actual instances of the class, so we test the prototype assert.equal(Leap.Frame.prototype.testFn(), 'frame'); assert.equal(Leap.Frame.Invalid.testFn(), 'frame'); assert.equal(Leap.Hand.prototype.testFn(), 'hand'); assert.equal(Leap.Hand.Invalid.testFn(), 'hand'); assert.equal(Leap.Pointable.prototype.testFn(), 'pointable'); assert.equal(Leap.Pointable.Invalid.testFn(), 'pointable'); assert.equal(Leap.Finger.prototype.testFnFinger(), 'finger'); assert.equal(Leap.Finger.Invalid.testFnFinger(), 'finger'); Leap.Controller._pluginFactories = {} }); it('should use registered plugins when the flag is set', function(){ Leap.Controller._pluginFactories = {} Leap.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' } })); var controller = fakeController({useAllPlugins: true}) controller.on('frame', function(frame){ assert.equal(frame.foo, 'bar') }); controller.connect(); controller.processFrame(fakeFrame()) Leap.Controller._pluginFactories = {} }); it('should stop extending frame, hand, and pointable prototypes', function(){ Leap.Controller._pluginFactories = {} Leap.Controller.plugin('testPlugin', fakePluginFactory({ frame: { testFn: function(){ return 'frame'; } }, hand: { testFn: function(){ return 'hand'; } }, pointable: { testFn: function(){ return 'pointable'; } }, finger: { testFnFinger: function(){ return 'pointable'; } } })); var controller = fakeController(); controller.use('testPlugin'); controller.stopUsing('testPlugin'); // our test doubles are not actual instances of the class, so we test the prototype assert.equal(Leap.Frame.prototype.testFn, undefined); assert.equal(Leap.Frame.Invalid.testFn, undefined); assert.equal(Leap.Hand.prototype.testFn, undefined); assert.equal(Leap.Hand.Invalid.testFn, undefined); assert.equal(Leap.Pointable.prototype.testFn, undefined); assert.equal(Leap.Pointable.Invalid.testFn, undefined); assert.equal(Leap.Finger.prototype.testFnFinger, undefined); assert.equal(Leap.Finger.Invalid.testFnFinger, undefined); Leap.Controller._pluginFactories = {} }); it('should use registered plugins when the flag is set', function(){ Leap.Controller._pluginFactories = {} Leap.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' } })); var controller = fakeController({useAllPlugins: true}) controller.on('frame', function(frame){ assert.equal(frame.foo, 'bar') }); controller.connect(); controller.processFrame(fakeFrame()) Leap.Controller._pluginFactories = {} }); }); describe('method chaining', function(){ it('should return a controller from .connect()', function(){ var controller = fakeController(); assert.equal(controller.connect(), controller); }); it('should return a controller from .on()', function(){ var controller = fakeController(); assert.equal(controller.on('frame', function(){}), controller); }); it('should return a controller from .use()', function(){ Leap.Controller._pluginFactories = {} Leap.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' } })); var controller = new Leap.Controller assert.equal(controller.use('testPlugin'), controller); Leap.Controller._pluginFactories = {} }); it('should return a controller from .stopUsing()', function(){ Leap.Controller._pluginFactories = {} Leap.plugin('testPlugin', fakePluginFactory({ frame: function(frame){ frame.foo = 'bar' } })); var controller = new Leap.Controller controller.use('testPlugin'); assert.equal(controller.stopUsing('testPlugin'), controller); Leap.Controller._pluginFactories = {} }); it('should return a controller from .disconnect()', function(){ var controller = new Leap.Controller; assert.equal(controller.disconnect(), controller); }); it('should return a controller from .setBackground()', function(){ var controller = new Leap.Controller; assert.equal(controller.setBackground(true), controller); }); it('should return a controller from .optimizeHMD()', function(){ var controller = new Leap.Controller; assert.equal(controller.setOptimizeHMD(true), controller); }); }) })