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()

















