@danielkalen/simplybind
Version:
Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.
214 lines (153 loc) • 6.44 kB
text/coffeescript
suite "Array", ()->
test "Can bind an array property using 'array:' descriptor and update subscribers when calling the .push, .pop, .shift, .unshift, .splice, .reverse, and .sort methods", ()->
mutations = 0
SimplyBind('array:list').of(objectA).to('prop4').of(objectB).and.to ()-> mutations++
expect(objectB.prop4.length).to.equal 10
expect(mutations).to.equal 1
objectA.list.push 11
expect(objectB.prop4.length).to.equal 11
expect(mutations).to.equal 2
objectA.list.shift()
objectA.list.shift()
expect(objectB.prop4.length).to.equal 9
expect(mutations).to.equal 4
objectA.list.unshift 2
objectA.list.unshift 1
expect(objectB.prop4.length).to.equal 11
expect(mutations).to.equal 6
objectA.list.pop()
objectA.list.pop()
expect(objectB.prop4.length).to.equal 9
expect(mutations).to.equal 8
objectA.list.splice 0, 5
expect(objectB.prop4.length).to.equal 4
expect(mutations).to.equal 9
objectA.list.reverse()
expect(objectB.prop4.length).to.equal 4
expect(mutations).to.equal 10
objectA.list.sort()
expect(objectB.prop4.length).to.equal 4
expect(mutations).to.equal 11
objectA.list.sort ()->
1
expect(objectB.prop4.length).to.equal 4
expect(mutations).to.equal 12
restartSandbox()
test "If the array binding receives an update of another array, it will discard the previous array and make the new array 'live'", ()->
invokeCount = 0
originalArray = objectA.list
SimplyBind('array:list').of(objectA).to('prop4').of(objectB).and.to ()-> invokeCount++
expect(objectB.prop4).to.equal(originalArray)
expect(invokeCount).to.equal 1
objectB.prop4 = 'reset'
originalArray.sort()
expect(objectB.prop4).to.equal(originalArray)
expect(invokeCount).to.equal 2
objectA.list = [1,2,3,4,5,6,7]
newArray = objectA.list
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 3
originalArray.sort()
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 3
newArray.sort()
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 4
newArray.push 8
originalArray.push 8
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 5
newArray.shift()
originalArray.shift()
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 6
newArray.unshift 1
originalArray.unshift 1
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 7
newArray.pop()
originalArray.pop()
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 8
newArray.splice 0, 5
originalArray.splice 0, 5
expect(objectB.prop4).to.equal(newArray)
expect(invokeCount).to.equal 9
restartSandbox()
test "If the array binding receives an update of another array, it will clone the new array and set it as the binding's value", ()->
invokeCount = 0
originalArray = objectA.list
newArray = [1,2,3,4]
SimplyBind('array:list').of(objectA).to ()-> invokeCount++
expect(objectA.list).to.equal(originalArray)
expect(invokeCount).to.equal(1)
originalArray.sort()
expect(objectA.list).to.equal(originalArray)
expect(invokeCount).to.equal(2)
objectA.list = newArray
expect(objectA.list).not.to.equal(originalArray)
expect(objectA.list).not.to.equal(newArray)
expect(objectA.list).not.to.eql(originalArray)
expect(Object.values objectA.list).to.eql(newArray)
expect(invokeCount).to.equal(3)
originalArray.sort()
expect(objectA.list).not.to.equal(originalArray)
expect(objectA.list).not.to.equal(newArray)
expect(objectA.list).not.to.eql(originalArray)
expect(Object.values objectA.list).to.eql(newArray)
expect(invokeCount).to.equal(3)
newArray.sort()
expect(objectA.list).not.to.equal(originalArray)
expect(objectA.list).not.to.equal(newArray)
expect(objectA.list).not.to.eql(originalArray)
expect(Object.values objectA.list).to.eql(newArray)
expect(invokeCount).to.equal(3)
objectA.list.sort()
expect(objectA.list).not.to.equal(originalArray)
expect(objectA.list).not.to.equal(newArray)
expect(objectA.list).not.to.eql(originalArray)
expect(Object.values objectA.list).to.eql(newArray)
expect(invokeCount).to.equal(4)
restartSandbox()
test "Will update subscribers with a clone when options.sendArrayCopies is on", ()->
receivedValues = copies:{current:null, prev:null}, noCopies:{current:null, prev:null}
SimplyBind('array:list').of(objectA).to (currentArray, prevArray)->
receivedValues.noCopies.current = currentArray
receivedValues.noCopies.prev = prevArray
expect(receivedValues.noCopies.current).to.equal(objectA.list)
expect(receivedValues.noCopies.prev).to.be.undefined
objectA.list.sort()
expect(receivedValues.noCopies.current).to.be.instanceOf(Array)
expect(receivedValues.noCopies.current).to.equal(objectA.list)
expect(receivedValues.noCopies.prev).to.equal(objectA.list)
SimplyBind('array:list', sendArrayCopies:true).of(objectB).to (currentArray, prevArray)->
receivedValues.copies.current = currentArray
receivedValues.copies.prev = prevArray
prevCurrent = receivedValues.copies.current
expect(receivedValues.copies.current).to.be.instanceOf(Array)
expect(receivedValues.copies.current).to.eql(Object.values objectA.list)
expect(receivedValues.copies.current).not.to.equal(objectA.list)
expect(receivedValues.copies.prev).to.be.undefined
objectB.list.sort()
expect(receivedValues.copies.current).to.eql(Object.values objectA.list)
expect(receivedValues.copies.current).not.to.equal(objectA.list)
expect(receivedValues.copies.current).not.to.equal(prevCurrent)
expect(receivedValues.copies.prev).to.equal(prevCurrent)
restartSandbox()
test "If an array binding receives a value that isn't an array it'll be normalized to an array", ()->
invokeCount = 0
SimplyBind('array:list').of(objectA).to ()-> invokeCount++
expect(objectA.list).to.be.instanceOf Array
expect(objectA.list.length).to.equal 10
expect(invokeCount).to.equal 1
objectA.list = 'value'
expect(objectA.list).to.be.instanceOf Array
expect(objectA.list.length).to.equal 1
expect(objectA.list[0]).to.equal 'value'
expect(invokeCount).to.equal 2
objectA.list = [1,2,3]
expect(objectA.list).to.be.instanceOf Array
expect(objectA.list.length).to.equal 3
expect(Object.values objectA.list).to.eql [1,2,3]
expect(invokeCount).to.equal 3
restartSandbox()