1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/licenses/publicdomain/ */
4 // Reflect.apply calls functions.
5 assertEq(Reflect.apply(Math.floor, undefined, [1.75]), 1);
7 // Reflect.apply requires a target object that's callable.
8 var nonCallable = [{}, [], (class clsX { constructor() {} })];
9 for (var value of nonCallable) {
10 assertThrowsInstanceOf(() => Reflect.apply(nonCallable), TypeError);
13 // When target is not callable, Reflect.apply does not try to get argumentList.length before throwing.
15 var bogusArgumentList = {get length() { hit++; throw "FAIL";}};
16 assertThrowsInstanceOf(() => Reflect.apply({callable: false}, null, bogusArgumentList),
20 // Reflect.apply works on a range of different callable objects.
21 // Builtin functions (we also tested Math.floor above):
22 assertEq(Reflect.apply(String.fromCharCode,
24 [104, 101, 108, 108, 111]),
28 assertEq(Reflect.apply(RegExp.prototype.exec,
30 ["confabulation"]).index,
33 // Builtin methods of primitive objects:
34 assertEq(Reflect.apply("".charAt,
40 assertEq(Reflect.apply(function () { return this; }.bind(Math),
44 assertEq(Reflect.apply(Array.prototype.concat.bind([1, 2], [3]),
49 // Generator functions:
50 function* g(arg) { yield "pass" + arg; }
51 assertEq(Reflect.apply(g,
53 ["word"]).next().value,
57 function f() { return 13; }
58 assertEq(Reflect.apply(new Proxy(f, {}),
63 // Cross-compartment wrappers:
65 assertEq(Reflect.apply(gw.parseInt,
69 assertEq(Reflect.apply(gw.Symbol.for,
74 gw.eval("function q() { return q; }");
75 assertEq(Reflect.apply(gw.q,
81 // Exceptions are propagated.
82 var nope = new Error("nope");
86 assertThrowsValue(() => Reflect.apply(fail, undefined, []),
89 // Exceptions thrown by cross-compartment wrappers are re-wrapped for the
90 // calling compartment.
91 var gxw = gw.eval("var x = new Error('x'); x");
92 gw.eval("function fail() { throw x; }");
93 assertThrowsValue(() => Reflect.apply(gw.fail, undefined, []),
96 // The thisArgument is passed to the target function as the 'this' value.
99 assertEq(Reflect.apply(function () { hits++; assertEq(this, obj); },
105 // Primitive values can be thisArgument.
106 function strictThis() { "use strict"; return this; }
107 for (var value of [null, undefined, 0, -0, NaN, Symbol("moon")]) {
108 assertEq(Reflect.apply(strictThis, value, []),
112 // If the target is a non-strict function and thisArgument is a primitive value
113 // other than null or undefined, then thisArgument is converted to a wrapper
115 var testValues = [true, 1e9, "ok", Symbol("ok")];
116 function nonStrictThis(expected) {
117 assertEq(typeof this, "object");
118 assertEq(Reflect.apply(Object.prototype.toString, this, []).toLowerCase(), expected);
121 for (var value of testValues) {
122 assertEq(Reflect.apply(nonStrictThis,
124 ["[object " + typeof value + "]"]),
128 // For more Reflect.apply tests, see target.js and argumentsList.js.