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