File indexing completed on 2024-04-28 15:28:37
0001 // 15.4 Array Objects 0002 // (c) 2001 Harri Porten <porten@kde.org> 0003 0004 shouldBe("Array().length", "0"); 0005 shouldBe("(new Array()).length", "0"); 0006 shouldBe("(new Array(3)).length", "3"); 0007 shouldBe("(new Array(11, 22)).length", "2"); 0008 shouldBe("(new Array(11, 22))[0]", "11"); 0009 shouldBe("Array(11, 22)[1]", "22"); 0010 shouldBeUndefined("(new Array(11, 22))[3]"); 0011 shouldBe("String(new Array(11, 22))", "'11,22'"); 0012 shouldBe("var a = []; a[0] = 33; a[0]", "33"); 0013 shouldBe("var a = []; a[0] = 33; a.length", "1"); 0014 shouldBe("var a = [11, 22]; a.length = 1; String(a);", "'11'"); 0015 shouldBe("var a = [11, 22]; a.length = 1; a.length;", "1"); 0016 0017 // range checks 0018 var caught = false; 0019 var ename = ""; 0020 try { 0021 [].length = -1; 0022 } catch (e) { 0023 // expect Range Error 0024 caught = true; 0025 ename = e.name; 0026 } 0027 0028 shouldBeTrue("caught;"); 0029 shouldBe("ename", "'RangeError'"); 0030 0031 caught = false; 0032 ename = ""; 0033 try { 0034 new Array(Infinity); 0035 } catch (e) { 0036 // expect Range Error 0037 caught = true; 0038 ename = e.name; 0039 } 0040 shouldBeTrue("caught;"); 0041 shouldBe("ename", "'RangeError'"); 0042 0043 shouldBeUndefined("var a = [11, 22]; a.length = 1; a[1];"); 0044 shouldBe("Array().toString()", "''"); 0045 shouldBe("Array(3).toString()", "',,'"); 0046 shouldBe("Array(11, 22).toString()", "'11,22'"); 0047 shouldBe("String(Array(11, 22).concat(33))", "'11,22,33'"); 0048 shouldBe("String(Array(2).concat(33, 44))", "',,33,44'"); 0049 shouldBe("String(Array(2).concat(Array(2)))", "',,,'"); 0050 shouldBe("String(Array(11,22).concat(Array(33,44)))", "'11,22,33,44'"); 0051 shouldBe("String(Array(1,2).concat(3,Array(4,5)))", "'1,2,3,4,5'"); 0052 shouldBe("var a = new Array(1,2,3); delete a[1]; String(a.concat(4))", "'1,,3,4'"); 0053 0054 shouldBe("[1,2,3,4].slice(1, 3).toString()", "'2,3'"); 0055 shouldBe("[1,2,3,4].slice(-3, -1).toString()", "'2,3'"); 0056 shouldBe("[1,2].slice(-9, 0).length", "0"); 0057 shouldBe("[1,2].slice(1).toString()", "'2'"); 0058 shouldBe("[1,2].slice().toString()", "'1,2'"); 0059 0060 // 2nd set. 0061 shouldBe("(new Array('a')).length", "1"); 0062 shouldBe("(new Array('a'))[0]", "'a'"); 0063 shouldBeUndefined("(new Array('a'))[1]"); 0064 0065 shouldBe("Array('a').length", "1"); 0066 shouldBe("Array('a')[0]", "'a'"); 0067 0068 shouldBe("String(Array())", "''"); 0069 shouldBe("String(Array('a','b'))", "'a,b'"); 0070 0071 shouldBe("[].length", "0"); 0072 shouldBe("['a'].length", "1"); 0073 shouldBe("['a'][0]", "'a'"); 0074 shouldBe("['a',,'c'][2]", "'c'"); 0075 0076 function forInSum(_a) { 0077 var s = ''; 0078 for (i in _a) 0079 s += _a[i]; 0080 return s; 0081 } 0082 0083 shouldBe("forInSum([])", "''"); 0084 shouldBe("forInSum(Array())", "''"); 0085 shouldBe("forInSum(Array('a'))", "'a'"); 0086 0087 var a0 = []; 0088 shouldBe("forInSum(a0)", "''"); 0089 0090 var a1 = [ 'a' ]; 0091 shouldBe("forInSum(a1)", "'a'"); 0092 0093 shouldBe("String([3,1,'2'].sort())", "'1,2,3'"); 0094 shouldBe("String([,'x','aa'].sort())", "'aa,x,'"); // don't assume 'x'>undefined ! 0095 0096 // sort by length 0097 function comp(a, b) { 0098 var la = String(a).length; 0099 var lb = String(b).length; 0100 if (la < lb) 0101 return -1; 0102 else if (la > lb) 0103 return 1; 0104 else 0105 return 0; 0106 } 0107 shouldBe("var a = ['aa', 'b', 'cccc', 'ddd']; String(a.sort(comp))", "'b,aa,ddd,cccc'"); 0108 0109 // +/-Infinity as function return value 0110 shouldBe("[0, Infinity].sort(function(a, b) { return a - b }).toString()", 0111 "'0,Infinity'"); 0112 0113 // Array.unshift() 0114 shouldBe("[].unshift('a')", "1"); 0115 shouldBe("['c'].unshift('a', 'b')", "3"); 0116 shouldBe("var a = []; a.unshift('a'); String(a)", "'a'"); 0117 shouldBe("var a = ['c']; a.unshift('a', 'b'); String(a)", "'a,b,c'"); 0118 0119 // Array.splice() 0120 shouldBe("String(['a', 'b', 'c'].splice(1, 2, 'x', 'y'))", "'b,c'"); 0121 0122 var maxint = Math.pow(2,32)-1; 0123 var arr = new Array(); 0124 0125 // 2^32 should not be treated as a valid array index, i.e. 0126 // setting the property on the array should not result in 0127 // the length being modified 0128 0129 arr.length = 40; 0130 arr[maxint] = "test"; 0131 shouldBe("arr.length","40"); 0132 shouldBe("arr[maxint]","\"test\""); 0133 delete arr[maxint]; 0134 shouldBe("arr.length","40"); 0135 shouldBe("arr[maxint]","undefined"); 0136 arr[maxint-1] = "test2"; 0137 shouldBe("arr.length","maxint"); 0138 shouldBe("arr[maxint-1]","\"test2\""); 0139 0140 arr = new Array('a','b','c'); 0141 arr.__proto__ = { 1: 'x' }; 0142 var propnames = new Array(); 0143 for (i in arr) 0144 propnames.push(i); 0145 propnames.sort(); 0146 shouldBe("propnames.length","3"); 0147 shouldBe("propnames[0]","'0'"); 0148 shouldBe("propnames[1]","'1'"); 0149 shouldBe("propnames[2]","'2'"); 0150 0151 // JavaScript 1.6 extension 0152 if (Array.prototype.lastIndexOf) { 0153 shouldBe("Array.prototype.lastIndexOf.length", "1"); 0154 shouldBe("['a', 'b', 'b', 'c'].lastIndexOf('x')", "-1"); 0155 shouldBe("['a', 'b', 'b', 'c'].lastIndexOf('b')", "2"); 0156 shouldBe("['a', 'b', 'b', 'c'].lastIndexOf('b', 1)", "1"); 0157 shouldBe("['a', 'b', 'b', 'c'].lastIndexOf()", "-1"); 0158 shouldBe("[].lastIndexOf('a')", "-1"); 0159 shouldBe("[true, false].lastIndexOf(0)", "-1"); 0160 } else { 0161 testFailed("Missing Array.prototype.lastIndexOf implementation"); 0162 } 0163 0164 var arr2 = ['a', 'b', 2, 'd', 'e'], result = ''; 0165 var arr3 = [5, 2, 8, 7, 3, 11, 6]; 0166 function cat(element, index, array) { result += element; } 0167 function rcat(element, index, array) { result = element + result; } 0168 function greaterThan(element, index, array) { return element > this; } 0169 function lessThan(element, index, array) { return element < this; } 0170 function greaterThan10(element, index, array) { return element > 10; } 0171 function lessThan12(element, index, array) { /*print([element, index, array]);*/ return element < 12; } 0172 0173 shouldBe("Array.prototype.forEach.length", "1"); 0174 result = ''; shouldBe("arr2.forEach(cat), result", "'ab2de'"); 0175 result = ''; shouldBe("arr2.forEach(rcat), result", "'ed2ba'"); 0176 0177 shouldBe("Array.prototype.every.length", "1"); 0178 shouldBeFalse("arr3.every(greaterThan, 10)"); 0179 shouldBeTrue("arr3.every(greaterThan, 1)"); 0180 shouldBeFalse("arr3.every(lessThan, 8)"); 0181 shouldBeTrue("arr3.every(lessThan, 12)"); 0182 shouldBeFalse("arr3.every(greaterThan10)"); 0183 shouldBeTrue("arr3.every(lessThan12)"); 0184 0185 shouldBe("Array.prototype.some.length", "1"); 0186 shouldBeFalse("arr3.some(greaterThan, 11)"); 0187 shouldBeTrue("arr3.some(greaterThan, 7)"); 0188 shouldBeFalse("arr3.some(lessThan, 2)"); 0189 shouldBeTrue("arr3.some(lessThan, 4)"); 0190 0191 function testToString() { 0192 // backup 0193 var backupNumberToString = Number.prototype.toString; 0194 var backupNumberToLocaleString = Number.prototype.toLocaleString; 0195 var backupRegExpToString = RegExp.prototype.toString; 0196 var backupRegExpToLocaleString = RegExp.prototype.toLocaleString; 0197 0198 // change functions 0199 Number.prototype.toString = function() { return "toString"; } 0200 Number.prototype.toLocaleString = function() { return "toLocaleString"; } 0201 RegExp.prototype.toString = function() { return "toString2"; } 0202 RegExp.prototype.toLocaleString = function() { return "toLocaleString2"; } 0203 0204 // the tests 0205 shouldBe("[1].toString()", "'1'"); 0206 shouldBe("[1].toLocaleString()", "'toLocaleString'"); 0207 Number.prototype.toLocaleString = "invalid"; 0208 shouldBe("[1].toLocaleString()", "'1'"); 0209 shouldBe("[/r/].toString()", "'toString2'"); 0210 shouldBe("[/r/].toLocaleString()", "'toLocaleString2'"); 0211 RegExp.prototype.toLocaleString = "invalid"; 0212 shouldBe("[/r/].toLocaleString()", "'toString2'"); 0213 0214 var caught = false; 0215 try { 0216 [{ toString : 0 }].toString(); 0217 } catch (e) { 0218 caught = true; 0219 } 0220 shouldBeTrue("caught"); 0221 0222 // restore 0223 Number.prototype.toString = backupNumberToString; 0224 Number.prototype.toLocaleString = backupNumberToLocaleString; 0225 RegExp.prototype.toString = backupRegExpToString; 0226 RegExp.prototype.toLocaleString = backupRegExpToLocaleString; 0227 } 0228 0229 testToString(); 0230 0231 // sort() within sort() reentrancy issue (JSC test array-sort-reentrance.js) 0232 var numbers1 = [1, 2, 3, 4, 5, 6, 7]; 0233 var numbers2 = numbers1.slice(); 0234 function compareFn1(a, b) { 0235 return b - a; 0236 } 0237 function compareFn2(a, b) { 0238 numbers1.sort(compareFn1); 0239 return b - a; 0240 } 0241 numbers2.sort(compareFn2); 0242 0243 // Sparse arrays [0] access bug --- test for non-crashing actually 0244 A = []; 0245 A[20000] = 42; 0246 shouldBe('A[0]', 'undefined'); 0247 0248 // Make sure we properly inherit DontEnum of ours when customizing it 0249 Array.prototype.toString = "glarch"; 0250 var res = ""; 0251 for (var p in []) 0252 res += p; 0253 shouldBe("res", "''"); 0254