| "use strict"; |
| |
| description("Verify Array.prototype.join() properties"); |
| |
| debug("Function properties"); |
| shouldBeEqualToString("typeof Array.prototype.join", "function"); |
| shouldBeEqualToString("Array.prototype.join.name", "join"); |
| shouldBe("Array.prototype.join.length", "1"); |
| shouldBeTrue("Object.getOwnPropertyDescriptor(Array.prototype, 'join').configurable"); |
| shouldBeFalse("Object.getOwnPropertyDescriptor(Array.prototype, 'join').enumerable"); |
| shouldBeTrue("Object.getOwnPropertyDescriptor(Array.prototype, 'join').writable"); |
| |
| debug("Int32 Array"); |
| shouldBeEqualToString("[1, 2, 3].join()", "1,2,3"); |
| shouldBeEqualToString("[1, 2, 3].join('')", "123"); |
| shouldBeEqualToString("[1, 2, 3].join('柰')", "1柰2柰3"); |
| |
| debug("Double Array"); |
| shouldBeEqualToString("[Math.PI, Math.E, 6.626].join()", "3.141592653589793,2.718281828459045,6.626"); |
| shouldBeEqualToString("[Math.PI, Math.E, 6.626].join('')", "3.1415926535897932.7182818284590456.626"); |
| shouldBeEqualToString("[Math.PI, Math.E, 6.626].join('柰')", "3.141592653589793柰2.718281828459045柰6.626"); |
| |
| debug("Contiguous Array"); |
| shouldBeEqualToString("[1, 'WebKit', { toString: () => { return 'IsIncredible'} }].join()", "1,WebKit,IsIncredible"); |
| shouldBeEqualToString("[1, 'WebKit', { toString: () => { return 'IsIncredible'} }].join('')", "1WebKitIsIncredible"); |
| shouldBeEqualToString("[1, 'WebKit', { toString: () => { return 'IsIncredible'} }].join('柰')", "1柰WebKit柰IsIncredible"); |
| |
| debug("Sparse Array"); |
| var smallSparseArray = new Array; |
| smallSparseArray[-1] = "Oops"; |
| smallSparseArray[0] = "WebKit"; |
| smallSparseArray[42] = 15; |
| shouldBeEqualToString("smallSparseArray.join()", "WebKit,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15"); |
| shouldBeEqualToString("smallSparseArray.join('')", "WebKit15"); |
| shouldBeEqualToString("smallSparseArray.join('柰')", "WebKit柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰柰15"); |
| |
| var largeSparseArray1 = new Array; |
| largeSparseArray1[100001] = 42; |
| largeSparseArray1[0] = "WebKit"; |
| largeSparseArray1[Number.MAX_SAFE_INTEGER] = { valueOf: () => { return 'IsCool'} }; |
| shouldBeEqualToString("largeSparseArray1.join('')", "WebKit42"); |
| |
| var largeSparseArray2 = new Array; |
| largeSparseArray2[100001] = 42; |
| largeSparseArray2[42] = "WebKit"; |
| largeSparseArray2[1024] = ""; |
| shouldBeEqualToString("largeSparseArray2.join('')", "WebKit42"); |
| |
| debug("Out of memory"); |
| // 4194303 * 4096 > Max String Length. |
| let oversizedArray = new Array(4096); |
| let sharedString = "A".repeat(1048576); |
| oversizedArray.fill(sharedString); |
| shouldThrow("oversizedArray.join('')", "'RangeError: Out of memory'"); |
| |
| debug("ToLength is called first on \"this\", followed by ToString on the separator. Followed by ToString on each element."); |
| var callSequence = []; |
| var lengthObject = { |
| toString: () => { callSequence.push("length.toString"); return "FAIL!"; }, |
| valueOf: () => { callSequence.push("length.valueOf"); return 2; } |
| }; |
| var index0Object = { |
| toString: () => { callSequence.push("index0.toString"); return "WebKit0"; }, |
| valueOf: () => { callSequence.push("index0.valueOf"); return "FAIL!"; } |
| }; |
| var index1Object = { |
| toString: () => { callSequence.push("index0.toString"); return "WebKit1"; }, |
| valueOf: () => { callSequence.push("index0.valueOf"); return "FAIL!"; } |
| }; |
| var calleeObject = { |
| toString: () => { callSequence.push("callee.toString"); return "FAIL!"; }, |
| valueOf: () => { callSequence.push("calle.valueOf"); return "FAIL!"; }, |
| get length () { callSequence.push("calle.length"); return lengthObject; }, |
| get 0 () { callSequence.push("calle.get 0"); return index0Object; }, |
| get 1 () { callSequence.push("calle.get 1"); return index1Object; } |
| }; |
| var separatorObject = { |
| toString: () => { callSequence.push("separator.toString"); return "柰"; }, |
| valueOf: () => { callSequence.push("separator.valueOf"); return "FAIL!"; } |
| }; |
| |
| shouldBeEqualToString("Array.prototype.join.call(calleeObject, separatorObject)", "WebKit0柰WebKit1"); |
| shouldBeEqualToString("callSequence.join(', ')", "calle.length, length.valueOf, separator.toString, calle.get 0, index0.toString, calle.get 1, index0.toString"); |
| |
| |
| debug("We use ToLength on the object's length, not ToInt32 or ToUInt32."); |
| var lengthyObject = { |
| get 0 () { throw "Fail! Accessed 0."; }, |
| get 1 () { throw "Fail! Accessed 1."; } |
| } |
| lengthyObject.length = -1; |
| shouldBeEqualToString("Array.prototype.join.call(lengthyObject)", ""); |
| lengthyObject.length = -4294967294; |
| shouldBeEqualToString("Array.prototype.join.call(lengthyObject)", ""); |
| lengthyObject.length = -4294967295; |
| shouldBeEqualToString("Array.prototype.join.call(lengthyObject)", ""); |