@danielkalen/simplybind
Version:
Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.
247 lines (158 loc) • 7.06 kB
text/coffeescript
suite "Event", ()->
test "A number can be provided in the selector with a # prefix to indicate which argument index of the event emitter callback should be used as the binding's value", ()->
emptyObj = {}
receiver = 'default':emptyObj, 'custom':emptyObj
invokeCount = 'default':0, 'custom':0
SimplyBind('event:focus').of(eventEmitterA)
.to('default').of receiver
.and.to ()-> invokeCount.default++
SimplyBind('event:focus#1').of(eventEmitterA)
.to('custom').of receiver
.and.to ()-> invokeCount.custom++
expect(receiver.default).to.equal emptyObj
expect(receiver.custom).to.equal emptyObj
expect(invokeCount.default).to.equal 0
expect(invokeCount.custom).to.equal 0
eventEmitterA.emit 'focus', eventEmitterA
expect(if isBrowser then receiver.default.target else receiver.default).to.equal eventEmitterA
expect(receiver.custom).to.be.undefined
expect(invokeCount.default).to.equal 1
expect(invokeCount.custom).to.equal 1
restartSandbox()
test "Custom events will behave exactly like regular events", ()->
emptyObj = {}
receiver = 'default':emptyObj, 'custom':emptyObj
invokeCount = 'default':0, 'custom':0
SimplyBind('event:somethingCustom').of(eventEmitterA)
.to('default').of receiver
.and.to ()-> invokeCount.default++
SimplyBind('event:somethingCustom#1').of(eventEmitterA)
.to('custom').of receiver
.and.to ()-> invokeCount.custom++
expect(receiver.default).to.equal emptyObj
expect(receiver.custom).to.equal emptyObj
expect(invokeCount.default).to.equal 0
expect(invokeCount.custom).to.equal 0
eventEmitterA.emit 'somethingCustom', eventEmitterA
expect(if isBrowser then receiver.default.target else receiver.default).to.equal eventEmitterA
expect(receiver.custom).to.be.undefined
expect(invokeCount.default).to.equal 1
expect(invokeCount.custom).to.equal 1
restartSandbox()
test "Custom listener/emitter methods can be used", ()->
emitCount = 0
receiveCount = 0
eventEmitterA.customListener 'someEvent', ()-> emitCount++
SimplyBind('prop2').of(objectA)
.to('event:someEvent', {emitMethod:'customEmitter', listenMethod:'customListener'}).of(eventEmitterA).bothWays ()-> ++receiveCount
expect(emitCount).to.equal 1
expect(receiveCount).to.equal 0
objectA.prop2 = 'whatever'
expect(emitCount).to.equal 2
eventEmitterA.customEmitter 'someEvent'
expect(receiveCount).to.equal 1
expect(objectA.prop2).to.equal 1
expect(emitCount).to.equal 3
objectA.prop2 = 'whatever again'
expect(emitCount).to.equal 4
eventEmitterA.customEmitter 'someEvent'
expect(receiveCount).to.equal 2
expect(objectA.prop2).to.equal 2
restartSandbox()
test "Default listener/emitter methods will be used if custom listener/emitter methods don't exist on the target object", ()->
emitCount = 0
receiveCount = 0
eventEmitterA.customListener 'click', ()-> emitCount++
SimplyBind('prop2').of(objectA)
.to('event:click', {listenMethod:'nonexistentListener', emitMethod:'nonexistentDispatcher'}).of(eventEmitterA).bothWays ()-> ++receiveCount
expect(emitCount).to.equal 1
expect(receiveCount).to.equal 0
objectA.prop2 = 'whatever'
expect(emitCount).to.equal 2
eventEmitterA.customEmitter 'click'
expect(receiveCount).to.equal 1
expect(objectA.prop2).to.equal 1
expect(emitCount).to.equal 3
objectA.prop2 = 'whatever again'
expect(emitCount).to.equal 4
eventEmitterA.customEmitter 'click'
expect(receiveCount).to.equal 2
expect(objectA.prop2).to.equal 2
restartSandbox()
test "Default listener/emitter methods should match browser's events API for DOM nodes and nodeJS's event API for all others", ()-> if not isBrowser then else
receiveCount = browser:0, node:0
emitCount = browser:0, node:0
customMethods = {listenMethod:'nonexistentListener', emitMethod:'nonexistentDispatcher'}
nodeEmitter = new EventEmitter
nodeEmitter.on 'click', ()-> receiveCount.node++
eventEmitterA.on 'click', ()-> receiveCount.browser++
SimplyBind('prop2').of(objectA)
.to('event:click', customMethods).of(nodeEmitter).bothWays ()-> ++emitCount.node
.and.to('event:click', customMethods).of(eventEmitterA).bothWays ()-> ++emitCount.browser
expect(receiveCount.node, 'receiveCount.node').to.equal 1
expect(receiveCount.browser, 'receiveCount.browser').to.equal 1
expect(emitCount.node, 'emitCount.node').to.equal 0
expect(emitCount.browser, 'emitCount.browser').to.equal 0
objectA.prop2 = 'whatever'
expect(receiveCount.node, 'receiveCount.node').to.equal 2
expect(receiveCount.browser, 'receiveCount.browser').to.equal 2
nodeEmitter.emit 'click'
eventEmitterA.emit 'click'
expect(emitCount.node, 'emitCount.node').to.equal 1
expect(emitCount.browser, 'emitCount.browser').to.equal 1
expect(objectA.prop2, 'objectA.prop2').to.equal 1
expect(receiveCount.node, 'receiveCount.node').to.equal 4
expect(receiveCount.browser, 'receiveCount.browser').to.equal 4
objectA.prop2 = 'whatever again'
expect(receiveCount.node, 'receiveCount.node').to.equal 5
expect(receiveCount.browser, 'receiveCount.browser').to.equal 5
nodeEmitter.emit 'click'
eventEmitterA.emit 'click'
expect(emitCount.node, 'emitCount.node').to.equal 2
expect(emitCount.browser, 'emitCount.browser').to.equal 2
expect(objectA.prop2, 'objectA.prop2').to.equal 2
restartSandbox()
test "Binding events to the DOM document should work as expected", ()-> if not isBrowser then else
receiveCount = 0
emitCount = 0
document.addEventListener 'click', ()-> receiveCount++
Interface =
SimplyBind('prop2').of(objectA)
.to('event:click').of(document).bothWays ()-> ++emitCount
expect(receiveCount).to.equal 1
expect(emitCount).to.equal 0
objectA.prop2 = 'whatever'
expect(receiveCount).to.equal 2
HTMLElement::emit.call document, 'click'
expect(emitCount).to.equal 1
expect(receiveCount).to.equal 3
expect(objectA.prop2).to.equal 1
objectA.prop2 = 'whatever again'
expect(receiveCount).to.equal 4
HTMLElement::emit.call document, 'click'
expect(emitCount).to.equal 2
expect(objectA.prop2).to.equal 2
Interface.unBind(true)
restartSandbox()
test "Binding events to the DOM window should work as expected", ()-> if not isBrowser then else
receiveCount = 0
emitCount = 0
window.addEventListener 'click', ()-> receiveCount++
Interface =
SimplyBind('prop2').of(objectA)
.to('event:click').of(window).bothWays ()-> ++emitCount
expect(receiveCount).to.equal 1
expect(emitCount).to.equal 0
objectA.prop2 = 'whatever'
expect(receiveCount).to.equal 2
HTMLElement::emit.call window, 'click'
expect(emitCount).to.equal 1
expect(receiveCount).to.equal 3
expect(objectA.prop2).to.equal 1
objectA.prop2 = 'whatever again'
expect(receiveCount).to.equal 4
HTMLElement::emit.call window, 'click'
expect(emitCount).to.equal 2
expect(objectA.prop2).to.equal 2
Interface.unBind(true)
restartSandbox()