1// Copyright 2013 the V8 project authors. All rights reserved. 2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24description("KDE JS Test"); 25// 15.4 Array Objects 26// (c) 2001 Harri Porten <porten@kde.org> 27 28shouldBe("Array().length", "0"); 29shouldBe("(new Array()).length", "0"); 30shouldBe("(new Array(3)).length", "3"); 31shouldBe("(new Array(11, 22)).length", "2"); 32shouldBe("(new Array(11, 22))[0]", "11"); 33shouldBe("Array(11, 22)[1]", "22"); 34shouldBeUndefined("(new Array(11, 22))[3]"); 35shouldBe("String(new Array(11, 22))", "'11,22'"); 36shouldBe("var a = []; a[0] = 33; a[0]", "33"); 37shouldBe("var a = []; a[0] = 33; a.length", "1"); 38shouldBe("var a = [11, 22]; a.length = 1; String(a);", "'11'"); 39shouldBe("var a = [11, 22]; a.length = 1; a.length;", "1"); 40 41// range checks 42var caught = false; 43var ename = ""; 44try { 45 [].length = -1; 46} catch (e) { 47 // expect Range Error 48 caught = true; 49 ename = e.name; 50} 51 52shouldBeTrue("caught;"); 53shouldBe("ename", "'RangeError'"); 54 55caught = false; 56ename = ""; 57try { 58 new Array(Infinity); 59} catch (e) { 60 // expect Range Error 61 caught = true; 62 ename = e.name; 63} 64shouldBeTrue("caught;"); 65shouldBe("ename", "'RangeError'"); 66 67shouldBeUndefined("var a = [11, 22]; a.length = 1; a[1];"); 68shouldBe("Array().toString()", "''"); 69shouldBe("Array(3).toString()", "',,'"); 70shouldBe("Array(11, 22).toString()", "'11,22'"); 71shouldBe("String(Array(11, 22).concat(33))", "'11,22,33'"); 72shouldBe("String(Array(2).concat(33, 44))", "',,33,44'"); 73shouldBe("String(Array(2).concat(Array(2)))", "',,,'"); 74shouldBe("String(Array(11,22).concat(Array(33,44)))", "'11,22,33,44'"); 75shouldBe("String(Array(1,2).concat(3,Array(4,5)))", "'1,2,3,4,5'"); 76shouldBe("var a = new Array(1,2,3); delete a[1]; String(a.concat(4))", "'1,,3,4'"); 77 78shouldBe("[1,2,3,4].slice(1, 3).toString()", "'2,3'"); 79shouldBe("[1,2,3,4].slice(-3, -1).toString()", "'2,3'"); 80shouldBe("[1,2].slice(-9, 0).length", "0"); 81shouldBe("[1,2].slice(1).toString()", "'2'"); 82shouldBe("[1,2].slice().toString()", "'1,2'"); 83 84// 2nd set. 85shouldBe("(new Array('a')).length", "1"); 86shouldBe("(new Array('a'))[0]", "'a'"); 87shouldBeUndefined("(new Array('a'))[1]"); 88 89shouldBe("Array('a').length", "1"); 90shouldBe("Array('a')[0]", "'a'"); 91 92shouldBe("String(Array())", "''"); 93shouldBe("String(Array('a','b'))", "'a,b'"); 94 95shouldBe("[].length", "0"); 96shouldBe("['a'].length", "1"); 97shouldBe("['a'][0]", "'a'"); 98shouldBe("['a',,'c'][2]", "'c'"); 99shouldBe("['a',undefined,'c'][1]", "undefined"); 100shouldBe("['a',,'c'][1]", "undefined"); 101shouldBe("1 in ['a',,'c']", "false"); 102shouldBe("1 in ['a',undefined,'c']", "true"); 103 104var arrayWithDeletion = ['a','b','c']; 105delete arrayWithDeletion[1]; 106shouldBe("1 in arrayWithDeletion", "false"); 107 108function forInSum(_a) { 109 var s = ''; 110 for (i in _a) 111 s += _a[i]; 112 return s; 113} 114 115shouldBe("forInSum([])", "''"); 116shouldBe("forInSum(Array())", "''"); 117shouldBe("forInSum(Array('a'))", "'a'"); 118shouldBe("forInSum([,undefined,'x','aa'])", "'undefinedxaa'"); 119 120var a0 = []; 121shouldBe("forInSum(a0)", "''"); 122 123var a1 = [ 'a' ]; 124shouldBe("forInSum(a1)", "'a'"); 125 126shouldBe("String([].sort())", "''") 127shouldBe("String([3,1,'2'].sort())", "'1,2,3'"); 128shouldBe("String([,'x','aa'].sort())", "'aa,x,'"); 129shouldBe("String([,undefined,'x','aa'].sort())", "'aa,x,,'"); 130shouldBe("2 in [,undefined,'x','aa'].sort()", "true"); 131shouldBe("3 in [,undefined,'x','aa'].sort()", "false"); 132 133// sort by length 134function comp(a, b) { 135 var la = String(a).length; 136 var lb = String(b).length; 137 if (la < lb) 138 return -1; 139 else if (la > lb) 140 return 1; 141 else 142 return 0; 143} 144shouldBe("var a = ['aa', 'b', 'cccc', 'ddd']; String(a.sort(comp))", "'b,aa,ddd,cccc'"); 145 146// +/-Infinity as function return value 147shouldBe("[0, Infinity].sort(function(a, b) { return a - b }).toString()", "'0,Infinity'"); 148 149// Array.unshift() 150shouldBe("[].unshift('a')", "1"); 151shouldBe("['c'].unshift('a', 'b')", "3"); 152shouldBe("var a = []; a.unshift('a'); String(a)", "'a'"); 153shouldBe("var a = ['c']; a.unshift('a', 'b'); String(a)", "'a,b,c'"); 154 155// Array.splice() 156shouldBe("String(['a', 'b', 'c'].splice(1, 2, 'x', 'y'))", "'b,c'"); 157 158var maxint = Math.pow(2,32)-1; 159var arr = new Array(); 160 161// 2^32 should not be treated as a valid array index, i.e. 162// setting the property on the array should not result in 163// the length being modified 164 165arr.length = 40; 166arr[maxint] = "test"; 167shouldBe("arr.length","40"); 168shouldBe("arr[maxint]","\"test\""); 169delete arr[maxint]; 170shouldBe("arr.length","40"); 171shouldBe("arr[maxint]","undefined"); 172arr[maxint-1] = "test2"; 173shouldBe("arr.length","maxint"); 174shouldBe("arr[maxint-1]","\"test2\""); 175 176// Floating point numbers also should not be treated as valid array indices. 177arr.length = 40; 178arr[55.5] = "test"; // does fit in a JSImmediate number 179arr[65.11111111111111111111111111111] = "test"; // does not fit in a JSImmediate number 180shouldBe("arr.length","40"); 181shouldBe("arr[55.5]","\"test\""); 182shouldBe("arr[65.11111111111111111111111111111]","\"test\""); 183delete arr[55.5]; 184delete arr[65.11111111111111111111111111111]; 185shouldBe("arr.length","40"); 186shouldBe("arr[55.5]","undefined"); 187shouldBe("arr[65.11111111111111111111111111111]","undefined"); 188 189arr = new Array('a','b','c'); 190arr.__proto__ = { 1: 'x' }; 191var propnames = new Array(); 192for (i in arr) 193 propnames.push(i); 194propnames.sort(); 195shouldBe("propnames.length","3"); 196shouldBe("propnames[0]","'0'"); 197shouldBe("propnames[1]","'1'"); 198shouldBe("propnames[2]","'2'"); 199 200function testToString() { 201 // backup 202 var backupNumberToString = Number.prototype.toString; 203 var backupNumberToLocaleString = Number.prototype.toLocaleString; 204 var backupRegExpToString = RegExp.prototype.toString; 205 var backupRegExpToLocaleString = RegExp.prototype.toLocaleString; 206 207 // change functions 208 Number.prototype.toString = function() { return "toString"; } 209 Number.prototype.toLocaleString = function() { return "toLocaleString"; } 210 RegExp.prototype.toString = function() { return "toString2"; } 211 RegExp.prototype.toLocaleString = function() { return "toLocaleString2"; } 212 213 // the tests 214 shouldBe("[1].toString()", "'1'"); 215 shouldBe("[1].toLocaleString()", "'toLocaleString'"); 216 Number.prototype.toLocaleString = "invalid"; 217 shouldBe("[1].toLocaleString()", "'1'"); 218 shouldBe("[/r/].toString()", "'toString2'"); 219 shouldBe("[/r/].toLocaleString()", "'toLocaleString2'"); 220 RegExp.prototype.toLocaleString = "invalid"; 221 shouldBe("[/r/].toLocaleString()", "'toString2'"); 222 223 var caught = false; 224 try { 225 [{ toString : 0 }].toString(); 226 } catch (e) { 227 caught = true; 228 } 229 shouldBeTrue("caught"); 230 231 // restore 232 Number.prototype.toString = backupNumberToString; 233 Number.prototype.toLocaleString = backupNumberToLocaleString; 234 RegExp.prototype.toString = backupRegExpToString; 235 RegExp.prototype.toLocaleString = backupRegExpToLocaleString; 236} 237