UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

245 lines (164 loc) 6.67 kB
suite ".transform()", ()-> suiteSetup(restartSandbox) test "Will apply a transformation to the value before updating the dependent", ()-> dispatcher = 'value': 'current' transformFn = (newValue, currentValue)-> newValue+'+'+currentValue objectA.prop = '' if isBrowser inputA.value = '' regA.textContent = '' regA.setAttribute 'someattr', '' SimplyBind('value').of(dispatcher) .to('prop').of(objectA).transform(transformFn) if isBrowser SimplyBind('value').of(dispatcher) .to('value').of(inputA).transform(transformFn) .and.to('textContent').of(regA).transform(transformFn) .and.to('attr:someattr').of(regA).transform(transformFn) values = ()-> if not isBrowser then [objectA.prop] else [objectA.prop, inputA.value, regA.textContent, regA.getAttribute 'someattr'] for value in values() expect(value).to.equal 'current+current' dispatcher.value = 'new' for value in values() expect(value).to.equal 'new+current+current' dispatcher.value = 'newer' for value in values() expect(value).to.equal 'newer+new+current+current' restartSandbox() test "Will apply transformations to event bindings", ()-> if not isBrowser then @skip() else resultHolder = 'event':null SimplyBind('event:someEvent').of(eventEmitterA) .to('event').of(resultHolder) .transform (event)-> event.type eventEmitterA.emit 'someEvent' expect(resultHolder.event).to.equal 'someEvent' test "Will receive the subject object as the third argument", ()-> dispatcher = 'prop':1 receivers = [objectA, objectB, objectC] index = 0 SimplyBind('prop').of(dispatcher) .to('prop').of(objectA) .and.to('prop').of(objectB) .and.to('prop').of(objectC) .transformAll (current, prev, target)-> expect(target).to.equal(receivers[index++]) return current expect(index).to.equal(3) restartSandbox() test "Will cause a re-update only to the last proxied dependent", ()-> invokeCount = 'A':0 'B':0 'C':0 SimplyBind('prop1').of(objectA) .to ()-> invokeCount.A++ .transform (v)-> v+v .and.to ()-> invokeCount.B++ .transform (v)-> v+v .and.to ()-> invokeCount.C++ .transform (v)-> v+v expect(invokeCount.A).to.equal 2 expect(invokeCount.B).to.equal 2 expect(invokeCount.C).to.equal 2 objectA.prop1 = !objectA.prop1 expect(invokeCount.A).to.equal 3 expect(invokeCount.B).to.equal 3 expect(invokeCount.C).to.equal 3 test "Promise transforms can be used instead of regular return values if SimplyBind.options.promiseTransforms is on", (done)-> objectA.prop2 = 'current' SimplyBind('prop1', {'updateOnBind':false}).of(objectA) .to (result)-> expect(result.then).not.to.be.undefined .transform ()-> new Promise ()-> SimplyBind('prop2', {'promiseTransforms':true}).of(objectA) .to('prop2').of(objectB) .transform (newValue, currentValue)-> new Promise (resolve)-> resolve(newValue+'+'+currentValue) setTimeout ()-> expect(objectB.prop2).to.equal 'current+current' objectA.prop2 = 'new' setTimeout ()-> expect(objectB.prop2).to.equal 'new+current+current' restartSandbox() done() , 0 , 0 test "A transform will only be used for the last declared dependent", ()-> dispatcher = 'value': 'test' objectA.prop1 = '' objectB.prop1 = '' SimplyBind('value').of(dispatcher) .to('prop1').of(objectA) .and.to('prop1').of(objectB) .transform (value)-> value.toUpperCase() expect(objectA.prop1).to.equal 'test' expect(objectB.prop1).to.equal 'TEST' restartSandbox() test "Only a single transform can be used for a binding and if two transforms are added, only the last one will be used", ()-> dispatcher = 'value': 'tEsT' objectA.prop1 = '' SimplyBind('value').of(dispatcher) .to('prop1').of(objectA) .transform (value)-> value.toUpperCase() .transform (value)-> value.toLowerCase() expect(objectA.prop1).to.equal 'test' restartSandbox() test "A transform will be used both ways when .bothWays() is called after the .transform declaration", ()-> dispatcher = 'value': 'test' objectA.prop = '' SimplyBind('value').of(dispatcher) .to('prop').of(objectA) .transform (value)-> value.toUpperCase() .bothWays() expect(dispatcher.value).to.equal 'test' expect(objectA.prop).to.equal 'TEST' dispatcher.value = 'from dispatcher' expect(dispatcher.value).to.equal 'from dispatcher' expect(objectA.prop).to.equal 'FROM DISPATCHER' objectA.prop = 'from objectA' expect(dispatcher.value).to.equal 'FROM OBJECTA' expect(objectA.prop).to.equal 'from objectA' restartSandbox() test "A transform will be used both ways when .bothWays() is called before the .transform declaration", ()-> dispatcher = 'value': 'test' objectA.prop = '' SimplyBind('value').of(dispatcher) .to('prop').of(objectA).bothWays() .transform (value)-> value.toUpperCase() expect(dispatcher.value).to.equal 'test' expect(objectA.prop).to.equal 'TEST' dispatcher.value = 'from dispatcher' expect(dispatcher.value).to.equal 'from dispatcher' expect(objectA.prop).to.equal 'FROM DISPATCHER' objectA.prop = 'from objectA' expect(dispatcher.value).to.equal 'FROM OBJECTA' expect(objectA.prop).to.equal 'from objectA' restartSandbox() test "A different transform will be used backwards if a function is passed to .bothWays() as the first argument", ()-> dispatcher = 'value': 'test' objectA.prop = '' SimplyBind('value').of(dispatcher) .to('prop').of(objectA) .transform (value)-> value.toUpperCase() .bothWays (value)-> value.toLowerCase() expect(dispatcher.value).to.equal 'test' expect(objectA.prop).to.equal 'TEST' dispatcher.value = 'From Dispatcher' expect(dispatcher.value).to.equal 'From Dispatcher' expect(objectA.prop).to.equal 'FROM DISPATCHER' objectA.prop = 'From ObjectA' expect(dispatcher.value).to.equal 'from objecta' expect(objectA.prop).to.equal 'From ObjectA' test "No transform will be used backwards if a false value is passed to .bothWays() as the first argument", ()-> dispatcher = 'value': 'test' objectA.prop = '' SimplyBind('value').of(dispatcher) .to('prop').of(objectA) .transform (value)-> value.toUpperCase() .bothWays(false) expect(dispatcher.value).to.equal 'test' expect(objectA.prop).to.equal 'TEST' dispatcher.value = 'From Dispatcher' expect(dispatcher.value).to.equal 'From Dispatcher' expect(objectA.prop).to.equal 'FROM DISPATCHER' objectA.prop = 'From ObjectA' expect(dispatcher.value).to.equal 'From ObjectA' expect(objectA.prop).to.equal 'From ObjectA'