Backed out 3 changesets (bug 1901078, bug 1749048) for causing interface related...
[gecko.git] / js / src / tests / non262 / Reflect / apply.js
blobfbd9db2a4b50407ff3cb8419ffd21ec5f8e0fdb1
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.
14 var hits = 0;
15 var bogusArgumentList = {get length() { hit++; throw "FAIL";}};
16 assertThrowsInstanceOf(() => Reflect.apply({callable: false}, null, bogusArgumentList),
17                        TypeError);
18 assertEq(hits, 0);
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,
23                        undefined,
24                        [104, 101, 108, 108, 111]),
25          "hello");
27 // Builtin methods:
28 assertEq(Reflect.apply(RegExp.prototype.exec,
29                        /ab/,
30                        ["confabulation"]).index,
31          4);
33 // Builtin methods of primitive objects:
34 assertEq(Reflect.apply("".charAt,
35                        "ponies",
36                        [3]),
37          "i");
39 // Bound functions:
40 assertEq(Reflect.apply(function () { return this; }.bind(Math),
41                        Function,
42                        []),
43          Math);
44 assertEq(Reflect.apply(Array.prototype.concat.bind([1, 2], [3]),
45                        [4, 5],
46                        [[6, 7, 8]]).join(),
47          "1,2,3,6,7,8");
49 // Generator functions:
50 function* g(arg) { yield "pass" + arg; }
51 assertEq(Reflect.apply(g,
52                        undefined,
53                        ["word"]).next().value,
54          "password");
56 // Proxies:
57 function f() { return 13; }
58 assertEq(Reflect.apply(new Proxy(f, {}),
59                        undefined,
60                        []),
61          13);
63 // Cross-compartment wrappers:
64 var gw = newGlobal();
65 assertEq(Reflect.apply(gw.parseInt,
66                        undefined,
67                        ["45"]),
68          45);
69 assertEq(Reflect.apply(gw.Symbol.for,
70                        undefined,
71                        ["moon"]),
72          Symbol.for("moon"));
74 gw.eval("function q() { return q; }");
75 assertEq(Reflect.apply(gw.q,
76                        undefined,
77                        []),
78          gw.q);
81 // Exceptions are propagated.
82 var nope = new Error("nope");
83 function fail() {
84     throw nope;
86 assertThrowsValue(() => Reflect.apply(fail, undefined, []),
87                   nope);
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, []),
94                   gxw);
96 // The thisArgument is passed to the target function as the 'this' value.
97 var obj = {};
98 hits = 0;
99 assertEq(Reflect.apply(function () { hits++; assertEq(this, obj); },
100                        obj,
101                        []),
102          undefined);
103 assertEq(hits, 1);
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, []),
109              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
114 // object.
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);
119     return "ok";
121 for (var value of testValues) {
122     assertEq(Reflect.apply(nonStrictThis,
123                            value,
124                            ["[object " + typeof value + "]"]),
125              "ok");
128 // For more Reflect.apply tests, see target.js and argumentsList.js.
130 reportCompare(0, 0);