mirror of
				https://github.com/tc39/test262.git
				synced 2025-11-04 05:33:50 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			187 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Copyright 2014 the V8 project authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style license that can be
 | 
						|
// found in the LICENSE file.
 | 
						|
 | 
						|
(function() {
 | 
						|
 | 
						|
assertEquals(1, Array.from.length);
 | 
						|
 | 
						|
function assertArrayLikeEquals(value, expected, type) {
 | 
						|
  assertInstanceof(value, type);
 | 
						|
  assertEquals(expected.length, value.length);
 | 
						|
  for (var i=0; i<value.length; ++i) {
 | 
						|
    assertEquals(expected[i], value[i]);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// Assert that constructor is called with "length" for array-like objects
 | 
						|
var myCollectionCalled = false;
 | 
						|
function MyCollection(length) {
 | 
						|
  myCollectionCalled = true;
 | 
						|
  assertEquals(1, arguments.length);
 | 
						|
  assertEquals(5, length);
 | 
						|
}
 | 
						|
 | 
						|
Array.from.call(MyCollection, {length: 5});
 | 
						|
assertTrue(myCollectionCalled);
 | 
						|
 | 
						|
// Assert that calling mapfn with / without thisArg in sloppy and strict modes
 | 
						|
// works as expected.
 | 
						|
var global = this;
 | 
						|
function non_strict(){ assertEquals(global, this); }
 | 
						|
function strict(){ "use strict"; assertEquals(void 0, this); }
 | 
						|
function strict_null(){ "use strict"; assertEquals(null, this); }
 | 
						|
Array.from([1], non_strict);
 | 
						|
Array.from([1], non_strict, void 0);
 | 
						|
Array.from([1], non_strict, null);
 | 
						|
Array.from([1], strict);
 | 
						|
Array.from([1], strict, void 0);
 | 
						|
Array.from([1], strict_null, null);
 | 
						|
 | 
						|
function testArrayFrom(thisArg, constructor) {
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, [], undefined), [],
 | 
						|
      constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, NaN), [], constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, Infinity), [], constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, 10000000), [], constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, 'test'), ['t', 'e', 's', 't'],
 | 
						|
      constructor);
 | 
						|
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg,
 | 
						|
      { length: 1, '0': { 'foo': 'bar' } }), [{'foo': 'bar'}], constructor);
 | 
						|
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg,
 | 
						|
      { length: -1, '0': { 'foo': 'bar' } }), [], constructor);
 | 
						|
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg,
 | 
						|
      [ 'foo', 'bar', 'baz' ]), ['foo', 'bar', 'baz'], constructor);
 | 
						|
 | 
						|
  var kSet = new Set(['foo', 'bar', 'baz']);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, kSet), ['foo', 'bar', 'baz'],
 | 
						|
      constructor);
 | 
						|
 | 
						|
  var kMap = new Map(['foo', 'bar', 'baz'].entries());
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, kMap),
 | 
						|
      [[0, 'foo'], [1, 'bar'], [2, 'baz']], constructor);
 | 
						|
 | 
						|
 | 
						|
  function* generator() {
 | 
						|
    yield 'a';
 | 
						|
    yield 'b';
 | 
						|
    yield 'c';
 | 
						|
  }
 | 
						|
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, generator()),
 | 
						|
                        ['a', 'b', 'c'], constructor);
 | 
						|
 | 
						|
  // Mozilla:
 | 
						|
  // Array.from on a string handles surrogate pairs correctly.
 | 
						|
  var gclef = "\uD834\uDD1E"; // U+1D11E MUSICAL SYMBOL G CLEF
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, gclef), [gclef], constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, gclef + " G"),
 | 
						|
      [gclef, " ", "G"], constructor);
 | 
						|
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, 'test', function(x) {
 | 
						|
    return this.filter(x);
 | 
						|
  }, {
 | 
						|
    filter: function(x) { return x.toUpperCase(); }
 | 
						|
  }), ['T', 'E', 'S', 'T'], constructor);
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, 'test', function(x) {
 | 
						|
    return x.toUpperCase();
 | 
						|
  }), ['T', 'E', 'S', 'T'], constructor);
 | 
						|
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, null); }, TypeError);
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, undefined); }, TypeError);
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, [], null); }, TypeError);
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, [], "noncallable"); },
 | 
						|
               TypeError);
 | 
						|
 | 
						|
  var nullIterator = {};
 | 
						|
  nullIterator[Symbol.iterator] = null;
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, nullIterator), [],
 | 
						|
                        constructor);
 | 
						|
 | 
						|
  var nonObjIterator = {};
 | 
						|
  nonObjIterator[Symbol.iterator] = function() { return "nonObject"; };
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, nonObjIterator); },
 | 
						|
               TypeError);
 | 
						|
 | 
						|
  assertThrows(function() { Array.from.call(thisArg, [], null); }, TypeError);
 | 
						|
 | 
						|
  // Ensure iterator is only accessed once, and only invoked once
 | 
						|
  var called = false;
 | 
						|
  var arr = [1, 2, 3];
 | 
						|
  var obj = {};
 | 
						|
 | 
						|
  // Test order --- only get iterator method once
 | 
						|
  function testIterator() {
 | 
						|
    assertFalse(called, "@@iterator should be called only once");
 | 
						|
    called = true;
 | 
						|
    assertEquals(obj, this);
 | 
						|
    return arr[Symbol.iterator]();
 | 
						|
  }
 | 
						|
  var getCalled = false;
 | 
						|
  Object.defineProperty(obj, Symbol.iterator, {
 | 
						|
    get: function() {
 | 
						|
      assertFalse(getCalled, "@@iterator should be accessed only once");
 | 
						|
      getCalled = true;
 | 
						|
      return testIterator;
 | 
						|
    },
 | 
						|
    set: function() {
 | 
						|
      assertUnreachable("@@iterator should not be set");
 | 
						|
    }
 | 
						|
  });
 | 
						|
  assertArrayLikeEquals(Array.from.call(thisArg, obj), [1, 2, 3], constructor);
 | 
						|
}
 | 
						|
 | 
						|
function Other() {}
 | 
						|
 | 
						|
var boundFn = (function() {}).bind(Array, 27);
 | 
						|
 | 
						|
testArrayFrom(Array, Array);
 | 
						|
testArrayFrom(null, Array);
 | 
						|
testArrayFrom({}, Array);
 | 
						|
testArrayFrom(Object, Object);
 | 
						|
testArrayFrom(Other, Other);
 | 
						|
testArrayFrom(Math.cos, Array);
 | 
						|
testArrayFrom(Math.cos.bind(Math), Array);
 | 
						|
testArrayFrom(boundFn, boundFn);
 | 
						|
 | 
						|
// Assert that [[DefineOwnProperty]] is used in ArrayFrom, meaning a
 | 
						|
// setter isn't called, and a failed [[DefineOwnProperty]] will throw.
 | 
						|
var setterCalled = 0;
 | 
						|
function exotic() {
 | 
						|
  Object.defineProperty(this,  '0', {
 | 
						|
    get: function() { return 2; },
 | 
						|
    set: function() { setterCalled++; }
 | 
						|
  });
 | 
						|
}
 | 
						|
// Non-configurable properties can't be overwritten with DefineOwnProperty
 | 
						|
assertThrows(function () { Array.from.call(exotic, [1]); }, TypeError);
 | 
						|
// The setter wasn't called
 | 
						|
assertEquals(0, setterCalled);
 | 
						|
 | 
						|
// Non-callable iterators should cause a TypeError before calling the target
 | 
						|
// constructor.
 | 
						|
items = {};
 | 
						|
items[Symbol.iterator] = 7;
 | 
						|
function TestError() {}
 | 
						|
function ArrayLike() { throw new TestError() }
 | 
						|
assertThrows(function() { Array.from.call(ArrayLike, items); }, TypeError);
 | 
						|
 | 
						|
// Check that array properties defined are writable, enumerable, configurable
 | 
						|
function ordinary() { }
 | 
						|
var x = Array.from.call(ordinary, [2]);
 | 
						|
var xlength = Object.getOwnPropertyDescriptor(x, 'length');
 | 
						|
assertEquals(1, xlength.value);
 | 
						|
assertEquals(true, xlength.writable);
 | 
						|
assertEquals(true, xlength.enumerable);
 | 
						|
assertEquals(true, xlength.configurable);
 | 
						|
var x0 = Object.getOwnPropertyDescriptor(x, 0);
 | 
						|
assertEquals(2, x0.value);
 | 
						|
assertEquals(true, xlength.writable);
 | 
						|
assertEquals(true, xlength.enumerable);
 | 
						|
assertEquals(true, xlength.configurable);
 | 
						|
 | 
						|
})();
 |