mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 03:34:08 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			251 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2008 the V8 project authors. All rights reserved.
 | |
| // Redistribution and use in source and binary forms, with or without
 | |
| // modification, are permitted provided that the following conditions are
 | |
| // met:
 | |
| //
 | |
| //     * Redistributions of source code must retain the above copyright
 | |
| //       notice, this list of conditions and the following disclaimer.
 | |
| //     * Redistributions in binary form must reproduce the above
 | |
| //       copyright notice, this list of conditions and the following
 | |
| //       disclaimer in the documentation and/or other materials provided
 | |
| //       with the distribution.
 | |
| //     * Neither the name of Google Inc. nor the names of its
 | |
| //       contributors may be used to endorse or promote products derived
 | |
| //       from this software without specific prior written permission.
 | |
| //
 | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| /**
 | |
|  * @fileoverview Test concat on small and large arrays
 | |
|  */
 | |
| 
 | |
| 
 | |
| (function testStringWrapperConcat() {
 | |
|   var concat = Array.prototype.concat;
 | |
|   var str = new String('abcd');
 | |
|   assertEquals([1,2,3,new String('abcd')], [1, 2, 3].concat(str));
 | |
|   assertEquals([new String("abcd")], concat.call(str));
 | |
| 
 | |
|   var array = [1, 2, 3];
 | |
|   array.__proto__ = str;
 | |
|   array.length = 4;
 | |
|   assertEquals([1,2,3,'d'], concat.call(array));
 | |
| })()
 | |
| 
 | |
| var poses;
 | |
| 
 | |
| poses = [140, 4000000000];
 | |
| while (pos = poses.shift()) {
 | |
|   var a = new Array(pos);
 | |
|   var array_proto = [];
 | |
|   a.__proto__ = array_proto;
 | |
|   assertEquals(pos, a.length);
 | |
|   a.push('foo');
 | |
|   assertEquals(pos + 1, a.length);
 | |
|   var b = ['bar'];
 | |
|   var c = a.concat(b);
 | |
|   assertEquals(pos + 2, c.length);
 | |
|   assertEquals("undefined", typeof(c[pos - 1]));
 | |
|   assertEquals("foo", c[pos]);
 | |
|   assertEquals("bar", c[pos + 1]);
 | |
| 
 | |
|   // Can we fool the system by putting a number in a string?
 | |
|   var onetwofour = "124";
 | |
|   a[onetwofour] = 'doo';
 | |
|   assertEquals(a[124], 'doo');
 | |
|   c = a.concat(b);
 | |
|   assertEquals(c[124], 'doo');
 | |
| 
 | |
|   // If we put a number in the prototype, then the spec says it should be
 | |
|   // copied on concat.
 | |
|   array_proto["123"] = 'baz';
 | |
|   assertEquals(a[123], 'baz');
 | |
| 
 | |
|   c = a.concat(b);
 | |
|   assertEquals(pos + 2, c.length);
 | |
|   assertEquals("baz", c[123]);
 | |
|   assertEquals("undefined", typeof(c[pos - 1]));
 | |
|   assertEquals("foo", c[pos]);
 | |
|   assertEquals("bar", c[pos + 1]);
 | |
| 
 | |
|   // When we take the number off the prototype it disappears from a, but
 | |
|   // the concat put it in c itself.
 | |
|   array_proto["123"] = undefined;
 | |
|   assertEquals("undefined", typeof(a[123]));
 | |
|   assertEquals("baz", c[123]);
 | |
| 
 | |
|   // If the element of prototype is shadowed, the element on the instance
 | |
|   // should be copied, but not the one on the prototype.
 | |
|   array_proto[123] = 'baz';
 | |
|   a[123] = 'xyz';
 | |
|   assertEquals('xyz', a[123]);
 | |
|   c = a.concat(b);
 | |
|   assertEquals('xyz', c[123]);
 | |
| 
 | |
|   // Non-numeric properties on the prototype or the array shouldn't get
 | |
|   // copied.
 | |
|   array_proto.moe = 'joe';
 | |
|   a.ben = 'jerry';
 | |
|   assertEquals(a["moe"], 'joe');
 | |
|   assertEquals(a["ben"], 'jerry');
 | |
|   c = a.concat(b);
 | |
|   // ben was not copied
 | |
|   assertEquals("undefined", typeof(c.ben));
 | |
| 
 | |
|   // When we take moe off the prototype it disappears from all arrays.
 | |
|   array_proto.moe = undefined;
 | |
|   assertEquals("undefined", typeof(c.moe));
 | |
| 
 | |
|   // Negative indices don't get concated.
 | |
|   a[-1] = 'minus1';
 | |
|   assertEquals("minus1", a[-1]);
 | |
|   assertEquals("undefined", typeof(a[0xffffffff]));
 | |
|   c = a.concat(b);
 | |
|   assertEquals("undefined", typeof(c[-1]));
 | |
|   assertEquals("undefined", typeof(c[0xffffffff]));
 | |
|   assertEquals(c.length, a.length + 1);
 | |
| }
 | |
| 
 | |
| poses = [140, 4000000000];
 | |
| while (pos = poses.shift()) {
 | |
|   var a = new Array(pos);
 | |
|   assertEquals(pos, a.length);
 | |
|   a.push('foo');
 | |
|   assertEquals(pos + 1, a.length);
 | |
|   var b = ['bar'];
 | |
|   var c = a.concat(b);
 | |
|   assertEquals(pos + 2, c.length);
 | |
|   assertEquals("undefined", typeof(c[pos - 1]));
 | |
|   assertEquals("foo", c[pos]);
 | |
|   assertEquals("bar", c[pos + 1]);
 | |
| 
 | |
|   // Can we fool the system by putting a number in a string?
 | |
|   var onetwofour = "124";
 | |
|   a[onetwofour] = 'doo';
 | |
|   assertEquals(a[124], 'doo');
 | |
|   c = a.concat(b);
 | |
|   assertEquals(c[124], 'doo');
 | |
| 
 | |
|   // If we put a number in the prototype, then the spec says it should be
 | |
|   // copied on concat.
 | |
|   Array.prototype["123"] = 'baz';
 | |
|   assertEquals(a[123], 'baz');
 | |
| 
 | |
|   c = a.concat(b);
 | |
|   assertEquals(pos + 2, c.length);
 | |
|   assertEquals("baz", c[123]);
 | |
|   assertEquals("undefined", typeof(c[pos - 1]));
 | |
|   assertEquals("foo", c[pos]);
 | |
|   assertEquals("bar", c[pos + 1]);
 | |
| 
 | |
|   // When we take the number off the prototype it disappears from a, but
 | |
|   // the concat put it in c itself.
 | |
|   Array.prototype["123"] = undefined;
 | |
|   assertEquals("undefined", typeof(a[123]));
 | |
|   assertEquals("baz", c[123]);
 | |
| 
 | |
|   // If the element of prototype is shadowed, the element on the instance
 | |
|   // should be copied, but not the one on the prototype.
 | |
|   Array.prototype[123] = 'baz';
 | |
|   a[123] = 'xyz';
 | |
|   assertEquals('xyz', a[123]);
 | |
|   c = a.concat(b);
 | |
|   assertEquals('xyz', c[123]);
 | |
| 
 | |
|   // Non-numeric properties on the prototype or the array shouldn't get
 | |
|   // copied.
 | |
|   Array.prototype.moe = 'joe';
 | |
|   a.ben = 'jerry';
 | |
|   assertEquals(a["moe"], 'joe');
 | |
|   assertEquals(a["ben"], 'jerry');
 | |
|   c = a.concat(b);
 | |
|   // ben was not copied
 | |
|   assertEquals("undefined", typeof(c.ben));
 | |
|   // moe was not copied, but we can see it through the prototype
 | |
|   assertEquals("joe", c.moe);
 | |
| 
 | |
|   // When we take moe off the prototype it disappears from all arrays.
 | |
|   Array.prototype.moe = undefined;
 | |
|   assertEquals("undefined", typeof(c.moe));
 | |
| 
 | |
|   // Negative indices don't get concated.
 | |
|   a[-1] = 'minus1';
 | |
|   assertEquals("minus1", a[-1]);
 | |
|   assertEquals("undefined", typeof(a[0xffffffff]));
 | |
|   c = a.concat(b);
 | |
|   assertEquals("undefined", typeof(c[-1]));
 | |
|   assertEquals("undefined", typeof(c[0xffffffff]));
 | |
|   assertEquals(c.length, a.length + 1);
 | |
| 
 | |
| }
 | |
| 
 | |
| a = [];
 | |
| c = a.concat('Hello');
 | |
| assertEquals(1, c.length);
 | |
| assertEquals("Hello", c[0]);
 | |
| assertEquals("Hello", c.toString());
 | |
| 
 | |
| // Check that concat preserves holes.
 | |
| var holey = [void 0,'a',,'c'].concat(['d',,'f',[0,,2],void 0])
 | |
| assertEquals(9, holey.length);  // hole in embedded array is ignored
 | |
| for (var i = 0; i < holey.length; i++) {
 | |
|   if (i == 2 || i == 5) {
 | |
|     assertFalse(i in holey);
 | |
|   } else {
 | |
|     assertTrue(i in holey);
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Polluted prototype from prior tests.
 | |
| delete Array.prototype[123];
 | |
| 
 | |
| // Check that concat reads getters in the correct order.
 | |
| var arr1 = [,2];
 | |
| var arr2 = [1,3];
 | |
| var r1 = [].concat(arr1, arr2);  // [,2,1,3]
 | |
| assertEquals([,2,1,3], r1);
 | |
| 
 | |
| // Make first array change length of second array.
 | |
| Object.defineProperty(arr1, 0, {get: function() {
 | |
|       arr2.push("X");
 | |
|       return undefined;
 | |
|     }, configurable: true})
 | |
| var r2 = [].concat(arr1, arr2);  // [undefined,2,1,3,"X"]
 | |
| assertEquals([undefined,2,1,3,"X"], r2);
 | |
| 
 | |
| // Make first array change length of second array massively.
 | |
| arr2.length = 2;
 | |
| Object.defineProperty(arr1, 0, {get: function() {
 | |
|       arr2[500000] = "X";
 | |
|       return undefined;
 | |
|     }, configurable: true})
 | |
| var r3 = [].concat(arr1, arr2);  // [undefined,2,1,3,"X"]
 | |
| var expected = [undefined,2,1,3];
 | |
| expected[500000 + 2] = "X";
 | |
| 
 | |
| assertEquals(expected, r3);
 | |
| 
 | |
| var arr3 = [];
 | |
| var trace = [];
 | |
| var expectedTrace = []
 | |
| function mkGetter(i) { return function() { trace.push(i); }; }
 | |
| arr3.length = 10000;
 | |
| for (var i = 0; i < 100; i++) {
 | |
|   Object.defineProperty(arr3, i * i, {get: mkGetter(i)});
 | |
|   expectedTrace[i] = i;
 | |
|   expectedTrace[100 + i] = i;
 | |
| }
 | |
| var r4 = [0].concat(arr3, arr3);
 | |
| assertEquals(1 + arr3.length * 2, r4.length);
 | |
| assertEquals(expectedTrace, trace);
 |