// 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. // Flags: --harmony-reflect (function testReflectApplyArity() { assertEquals(3, Reflect.apply.length); })(); (function testReflectApplyNonConstructor() { assertThrows(function() { new Reflect.apply(function(){}, null, []); }, TypeError); })(); (function testAppliedReceiverSloppy() { function returnThis() { return this; } var receiver = {}; assertSame(this, Reflect.apply(returnThis, void 0, [])); assertSame(this, Reflect.apply(returnThis, null, [])); assertSame(this, Reflect.apply(returnThis, this, [])); assertSame(receiver, Reflect.apply(returnThis, receiver, [])); // Wrap JS values assertSame(String.prototype, Object.getPrototypeOf(Reflect.apply(returnThis, "str", []))); assertSame(Number.prototype, Object.getPrototypeOf(Reflect.apply(returnThis, 123, []))); assertSame(Boolean.prototype, Object.getPrototypeOf(Reflect.apply(returnThis, true, []))); assertSame(Symbol.prototype, Object.getPrototypeOf( Reflect.apply(returnThis, Symbol("test"), []))); })(); (function testAppliedReceiverStrict() { function returnThis() { 'use strict'; return this; } var receiver = {}; assertSame(void 0, Reflect.apply(returnThis, void 0, [])); assertSame(this, Reflect.apply(returnThis, this, [])); assertSame(receiver, Reflect.apply(returnThis, receiver, [])); // Don't wrap value types var regexp = /123/; var symbol = Symbol("test"); assertSame("str", Reflect.apply(returnThis, "str", [])); assertSame(123, Reflect.apply(returnThis, 123, [])); assertSame(true, Reflect.apply(returnThis, true, [])); assertSame(regexp, Reflect.apply(returnThis, regexp, [])); assertSame(symbol, Reflect.apply(returnThis, symbol, [])); })(); (function testAppliedArgumentsLength() { function returnLengthStrict() { 'use strict'; return arguments.length; } function returnLengthSloppy() { return arguments.length; } assertEquals(0, Reflect.apply(returnLengthStrict, this, [])); assertEquals(0, Reflect.apply(returnLengthSloppy, this, [])); assertEquals(0, Reflect.apply(returnLengthStrict, this, {})); assertEquals(0, Reflect.apply(returnLengthSloppy, this, {})); for (var i = 0; i < 256; ++i) { assertEquals(i, Reflect.apply(returnLengthStrict, this, new Array(i))); assertEquals(i, Reflect.apply(returnLengthSloppy, this, new Array(i))); assertEquals(i, Reflect.apply(returnLengthStrict, this, { length: i })); assertEquals(i, Reflect.apply(returnLengthSloppy, this, { length: i })); } })(); (function testAppliedArgumentsLengthThrows() { function noopStrict() { 'use strict'; } function noopSloppy() { } function MyError() {} var argsList = {}; Object.defineProperty(argsList, "length", { get: function() { throw new MyError(); } }); assertThrows(function() { Reflect.apply(noopStrict, this, argsList); }, MyError); assertThrows(function() { Reflect.apply(noopSloppy, this, argsList); }, MyError); })(); (function testAppliedArgumentsElementThrows() { function noopStrict() { 'use strict'; } function noopSloppy() { } function MyError() {} var argsList = { length: 1 }; Object.defineProperty(argsList, "0", { get: function() { throw new MyError(); } }); assertThrows(function() { Reflect.apply(noopStrict, this, argsList); }, MyError); assertThrows(function() { Reflect.apply(noopSloppy, this, argsList); }, MyError); })(); (function testAppliedNonFunctionStrict() { 'use strict'; assertThrows(function() { Reflect.apply(void 0); }, TypeError); assertThrows(function() { Reflect.apply(null); }, TypeError); assertThrows(function() { Reflect.apply(123); }, TypeError); assertThrows(function() { Reflect.apply("str"); }, TypeError); assertThrows(function() { Reflect.apply(Symbol("x")); }, TypeError); assertThrows(function() { Reflect.apply(/123/); }, TypeError); assertThrows(function() { Reflect.apply(NaN); }, TypeError); assertThrows(function() { Reflect.apply({}); }, TypeError); assertThrows(function() { Reflect.apply([]); }, TypeError); })(); (function testAppliedNonFunctionSloppy() { assertThrows(function() { Reflect.apply(void 0); }, TypeError); assertThrows(function() { Reflect.apply(null); }, TypeError); assertThrows(function() { Reflect.apply(123); }, TypeError); assertThrows(function() { Reflect.apply("str"); }, TypeError); assertThrows(function() { Reflect.apply(Symbol("x")); }, TypeError); assertThrows(function() { Reflect.apply(/123/); }, TypeError); assertThrows(function() { Reflect.apply(NaN); }, TypeError); assertThrows(function() { Reflect.apply({}); }, TypeError); assertThrows(function() { Reflect.apply([]); }, TypeError); })(); (function testAppliedArgumentsNonList() { function noopStrict() { 'use strict'; } function noopSloppy() {} var R = void 0; assertThrows(function() { Reflect.apply(noopStrict, R, null); }, TypeError); assertThrows(function() { Reflect.apply(noopSloppy, R, null); }, TypeError); assertThrows(function() { Reflect.apply(noopStrict, R, 1); }, TypeError); assertThrows(function() { Reflect.apply(noopSloppy, R, 1); }, TypeError); assertThrows(function() { Reflect.apply(noopStrict, R, "BAD"); }, TypeError); assertThrows(function() { Reflect.apply(noopSloppy, R, "BAD"); }, TypeError); assertThrows(function() { Reflect.apply(noopStrict, R, true); }, TypeError); assertThrows(function() { Reflect.apply(noopSloppy, R, true); }, TypeError); var sym = Symbol("x"); assertThrows(function() { Reflect.apply(noopStrict, R, sym); }, TypeError); assertThrows(function() { Reflect.apply(noopSloppy, R, sym); }, TypeError); })(); (function testAppliedArgumentValue() { function returnFirstStrict(a) { 'use strict'; return a; } function returnFirstSloppy(a) { return a; } function returnLastStrict(a) { 'use strict'; return arguments[arguments.length - 1]; } function returnLastSloppy(a) { return arguments[arguments.length - 1]; } function returnSumStrict() { 'use strict'; var sum = arguments[0]; for (var i = 1; i < arguments.length; ++i) { sum += arguments[i]; } return sum; } function returnSumSloppy() { var sum = arguments[0]; for (var i = 1; i < arguments.length; ++i) { sum += arguments[i]; } return sum; } assertEquals("OK!", Reflect.apply(returnFirstStrict, this, ["OK!"])); assertEquals("OK!", Reflect.apply(returnFirstSloppy, this, ["OK!"])); assertEquals("OK!", Reflect.apply(returnFirstStrict, this, { 0: "OK!", length: 1 })); assertEquals("OK!", Reflect.apply(returnFirstSloppy, this, { 0: "OK!", length: 1 })); assertEquals("OK!", Reflect.apply(returnLastStrict, this, [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"])); assertEquals("OK!", Reflect.apply(returnLastSloppy, this, [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"])); assertEquals("OK!", Reflect.apply(returnLastStrict, this, { 9: "OK!", length: 10 })); assertEquals("OK!", Reflect.apply(returnLastSloppy, this, { 9: "OK!", length: 10 })); assertEquals("TEST", Reflect.apply(returnSumStrict, this, ["T", "E", "S", "T"])); assertEquals("TEST!!", Reflect.apply(returnSumStrict, this, ["T", "E", "S", "T", "!", "!"])); assertEquals(10, Reflect.apply(returnSumStrict, this, { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 })); assertEquals("TEST", Reflect.apply(returnSumSloppy, this, ["T", "E", "S", "T"])); assertEquals("TEST!!", Reflect.apply(returnSumSloppy, this, ["T", "E", "S", "T", "!", "!"])); assertEquals(10, Reflect.apply(returnSumSloppy, this, { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 })); })();