1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --harmony-reflect
6
7// TODO(neis): Test with proxies.
8
9
10
11////////////////////////////////////////////////////////////////////////////////
12// (Auxiliaries)
13
14
15"use strict";
16
17var global = this;
18
19var sym = Symbol("gaga");
20
21var objects = [
22  {},
23  [],
24  function() {},
25  function() {
26    return arguments;
27  }(),
28  function() {
29    'use strict';
30    return arguments;
31  }(),
32  Object(1),
33  Object(true),
34  Object('bla'),
35  new Date,
36  new RegExp,
37  new Set,
38  new Map,
39  new WeakMap,
40  new WeakSet,
41  new ArrayBuffer(10),
42  new Int32Array(5),
43  Object,
44  Function,
45  Date,
46  RegExp,
47  global
48];
49
50function prepare(target) {
51  target["bla"] = true;
52  target[4] = 42;
53  target[sym] = "foo";
54  target["noconf"] = 43;
55  Object.defineProperty(target, "noconf",
56      { configurable: false });
57  Object.defineProperty(target, "nowrite",
58      { writable: false, configurable: true, value: 44 });
59  Object.defineProperty(target, "getter",
60      { get: function () {return this.bla}, configurable: true });
61  Object.defineProperty(target, "setter",
62      { set: function (x) {this.gaga = x}, configurable: true });
63  Object.defineProperty(target, "setter2",
64      { set: function (x) {}, configurable: true });
65}
66
67
68
69////////////////////////////////////////////////////////////////////////////////
70// Reflect.get
71
72
73(function testReflectGetArity() {
74  assertEquals(2, Reflect.get.length);
75})();
76
77
78(function testReflectGetOnNonObject() {
79  assertThrows(function() { Reflect.get(); }, TypeError);
80  assertThrows(function() { Reflect.get(42, "bla"); }, TypeError);
81  assertThrows(function() { Reflect.get(null, "bla"); }, TypeError);
82})();
83
84
85(function testReflectGetKeyConversion() {
86  var target = {bla: 42};
87  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
88  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
89  assertEquals(42, Reflect.get(target, a));
90  assertThrowsEquals(function() { Reflect.get(target, b); }, "gaga");
91})();
92
93
94(function testReflectGetOnObject() {
95  var receiver = {bla: false};
96  for (let target of objects) {
97    prepare(target);
98    assertEquals(true, Reflect.get(target, "bla"));
99    assertEquals(true, Reflect.get(target, "bla", target));
100    assertEquals(true, Reflect.get(target, "bla", receiver));
101    assertEquals(42, Reflect.get(target, 4));
102    assertEquals(42, Reflect.get(target, 4, target));
103    assertEquals(42, Reflect.get(target, 4, receiver));
104    assertEquals(42, Reflect.get(target, "4"));
105    assertEquals(42, Reflect.get(target, "4", target));
106    assertEquals(42, Reflect.get(target, "4", receiver));
107    assertEquals("foo", Reflect.get(target, sym));
108    assertEquals("foo", Reflect.get(target, sym, target));
109    assertEquals("foo", Reflect.get(target, sym, receiver));
110    assertEquals(43, Reflect.get(target, "noconf"));
111    assertEquals(43, Reflect.get(target, "noconf", target));
112    assertEquals(43, Reflect.get(target, "noconf", receiver));
113    assertEquals(true, Reflect.get(target, "getter"));
114    assertEquals(true, Reflect.get(target, "getter", target));
115    assertEquals(false, Reflect.get(target, "getter", receiver));
116    assertEquals(undefined, Reflect.get(target, "setter"));
117    assertEquals(undefined, Reflect.get(target, "setter", target));
118    assertEquals(undefined, Reflect.get(target, "setter", receiver));
119    assertEquals(undefined, Reflect.get(target, "foo"));
120    assertEquals(undefined, Reflect.get(target, "foo", target));
121    assertEquals(undefined, Reflect.get(target, "foo", receiver));
122    assertEquals(undefined, Reflect.get(target, 666));
123    assertEquals(undefined, Reflect.get(target, 666, target));
124    assertEquals(undefined, Reflect.get(target, 666, receiver));
125
126    let proto = target.__proto__;
127    target.__proto__ = { get foo() {return this.bla} };
128    assertEquals(true, Reflect.get(target, "foo"));
129    assertEquals(true, Reflect.get(target, "foo", target));
130    assertEquals(false, Reflect.get(target, "foo", receiver));
131    target.__proto__ = proto;
132  }
133})();
134
135
136
137////////////////////////////////////////////////////////////////////////////////
138// Reflect.set
139
140
141(function testReflectSetArity() {
142  assertEquals(3, Reflect.set.length);
143})();
144
145
146(function testReflectSetOnNonObject() {
147  assertThrows(function() { Reflect.set(); }, TypeError);
148  assertThrows(function() { Reflect.set(42, "bla"); }, TypeError);
149  assertThrows(function() { Reflect.set(null, "bla"); }, TypeError);
150})();
151
152
153(function testReflectSetKeyConversion() {
154  var target = {};
155  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
156  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
157  assertTrue(Reflect.set(target, a, 42));
158  assertEquals(42, target.bla);
159  assertThrowsEquals(function() { Reflect.set(target, b, 42); }, "gaga");
160})();
161
162
163(function testReflectSetOnObject() {
164  var receiver = {bla: false};
165  var value = 34234;
166  for (let target of objects) {
167    prepare(target);
168    assertTrue(Reflect.set(target, "bla", value));
169    assertEquals(value, target.bla);
170
171    prepare(target);
172    assertTrue(Reflect.set(target, "bla", value, target));
173    assertEquals(value, target.bla);
174
175    prepare(target);
176    assertTrue(Reflect.set(target, "bla", value, receiver));
177    assertEquals(true, target.bla);
178    assertEquals(value, receiver.bla);
179    receiver.bla = false;
180
181    prepare(target);
182    assertTrue(Reflect.set(target, 4, value));
183    assertEquals(value, target[4]);
184
185    prepare(target);
186    assertTrue(Reflect.set(target, 4, value, target));
187    assertEquals(value, target[4]);
188
189    prepare(target);
190    assertTrue(Reflect.set(target, 4, value, receiver));
191    assertEquals(42, target[4]);
192    assertEquals(value, receiver[4]);
193    delete receiver[4];
194
195    prepare(target);
196    assertTrue(Reflect.set(target, sym, value));
197    assertEquals(value, target[sym]);
198
199    prepare(target);
200    assertTrue(Reflect.set(target, sym, value, target));
201    assertEquals(value, target[sym]);
202
203    prepare(target);
204    assertTrue(Reflect.set(target, sym, value, receiver));
205    assertEquals("foo", target[sym]);
206    assertEquals(value, receiver[sym]);
207    delete receiver[sym];
208
209    prepare(target);
210    assertTrue(Reflect.set(target, "noconf", value));
211    assertEquals(value, target.noconf);
212
213    prepare(target);
214    assertTrue(Reflect.set(target, "noconf", value, target));
215    assertEquals(value, target.noconf);
216
217    prepare(target);
218    assertTrue(Reflect.set(target, "noconf", value, receiver));
219    assertEquals(43, target.noconf);
220    assertEquals(value, receiver.noconf);
221    delete receiver.noconf;
222
223    assertTrue(Reflect.set(target, "setter", value));
224    assertEquals(value, target.gaga)
225    delete target.gaga;
226
227    assertTrue(Reflect.set(target, "setter", value, target));
228    assertEquals(value, target.gaga)
229    delete target.gaga;
230
231    assertTrue(Reflect.set(target, "setter", value, receiver));
232    assertFalse("gaga" in target);
233    assertEquals(value, receiver.gaga);
234    delete receiver.gaga;
235
236    assertFalse(Reflect.set(target, "nowrite", value));
237    assertEquals(44, target.nowrite);
238
239    assertFalse(Reflect.set(target, "nowrite", value, target));
240    assertEquals(44, target.nowrite);
241
242    assertFalse(Reflect.set(target, "nowrite", value, receiver));
243    assertEquals(44, target.nowrite);
244    assertFalse("nowrite" in receiver);
245
246    // Data vs Non-Writable
247    assertFalse(Reflect.set({}, "nowrite", value, target));
248
249    // Data vs Accessor
250    assertFalse(Reflect.set({}, "unknown", 0, {set unknown(x) {}}));
251    assertFalse(Reflect.set(target, "unknown", value, {set unknown(x) {}}));
252    assertFalse(Reflect.set(target, "bla", value, {set bla(x) {}}));
253    assertFalse(Reflect.set(target, "bla", value, {get bla() {}}));
254
255    // Accessor vs Data
256    assertTrue(Reflect.set({set bla(x) {}}), "bla", value, target);
257    assertFalse(Reflect.set({get bla() {}}, "bla", value, target));
258
259    // Data vs Non-Object
260    assertFalse(Reflect.set({}, "bla", value, null));
261    assertFalse(Reflect.set({bla: 42}, "bla", value, null));
262
263    // Accessor vs Non-Object
264    assertTrue(Reflect.set(target, "setter2", value, null));
265    assertFalse(Reflect.set(target, "getter", value, null));
266
267    let receiver2 = {};
268    Object.defineProperty(receiver2, "bla",
269        {configurable: false, writable: true, value: true});
270    Object.defineProperty(receiver2, "not_in_target",
271        {configurable: false, writable: true, value: true});
272    assertTrue(Reflect.set(target, "bla", value, receiver2));
273    assertTrue(Reflect.set(target, "not_in_target", value, receiver2));
274  }
275})();
276
277
278
279////////////////////////////////////////////////////////////////////////////////
280// Reflect.has
281
282
283(function testReflectHasArity() {
284  assertEquals(2, Reflect.has.length);
285})();
286
287
288(function testReflectHasOnNonObject() {
289  assertThrows(function() { Reflect.has(); }, TypeError);
290  assertThrows(function() { Reflect.has(42, "bla"); }, TypeError);
291  assertThrows(function() { Reflect.has(null, "bla"); }, TypeError);
292})();
293
294
295(function testReflectHasKeyConversion() {
296  var target = {bla: 42};
297  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
298  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
299  assertTrue(Reflect.has(target, a));
300  assertThrowsEquals(function() { Reflect.has(target, b); }, "gaga");
301})();
302
303
304(function testReflectHasOnObject() {
305  for (let target of objects) {
306    prepare(target);
307    assertTrue(Reflect.has(target, "bla"));
308    assertTrue(Reflect.has(target, 4));
309    assertTrue(Reflect.has(target, "4"));
310    assertTrue(Reflect.has(target, sym));
311    assertTrue(Reflect.has(target, "noconf"));
312    assertTrue(Reflect.has(target, "getter"));
313    assertTrue(Reflect.has(target, "setter"));
314    assertFalse(Reflect.has(target, "foo"));
315    assertFalse(Reflect.has(target, 666));
316
317    let proto = target.__proto__;
318    target.__proto__ = { get foo() {return this.bla} };
319    assertEquals(true, Reflect.has(target, "foo"));
320    target.__proto__ = proto;
321  }
322})();
323
324
325
326////////////////////////////////////////////////////////////////////////////////
327// Reflect.defineProperty
328
329
330(function testReflectDefinePropertyArity() {
331  assertEquals(3, Reflect.defineProperty.length);
332})();
333
334
335(function testReflectDefinePropertyOnNonObject() {
336  assertThrows(function() { Reflect.defineProperty(); }, TypeError);
337  assertThrows(function() { Reflect.defineProperty(42, "bla"); }, TypeError);
338  assertThrows(function() { Reflect.defineProperty(null, "bla"); }, TypeError);
339  assertThrows(function() { Reflect.defineProperty({}, "bla"); }, TypeError);
340  assertThrows(function() { Reflect.defineProperty({}, "bla", 42); },
341      TypeError);
342  assertThrows(function() { Reflect.defineProperty({}, "bla", null); },
343      TypeError);
344})();
345
346
347(function testReflectDefinePropertyKeyConversion() {
348  var target = {};
349  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
350  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
351  assertTrue(Reflect.defineProperty(target, a, {value: 42}));
352  assertEquals(target.bla, 42);
353  assertThrowsEquals(function() { Reflect.defineProperty(target, b); }, "gaga");
354})();
355
356
357// See reflect-define-property.js for further tests.
358
359
360
361////////////////////////////////////////////////////////////////////////////////
362// Reflect.deleteProperty
363
364
365(function testReflectDeletePropertyArity() {
366  assertEquals(2, Reflect.deleteProperty.length);
367})();
368
369
370(function testReflectDeletePropertyOnNonObject() {
371  assertThrows(function() { Reflect.deleteProperty(); }, TypeError);
372  assertThrows(function() { Reflect.deleteProperty(42, "bla"); }, TypeError);
373  assertThrows(function() { Reflect.deleteProperty(null, "bla"); }, TypeError);
374})();
375
376
377(function testReflectDeletePropertyKeyConversion() {
378  var target = {bla: 42};
379  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
380  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
381  assertTrue(Reflect.deleteProperty(target, a));
382  assertThrowsEquals(function() { Reflect.deleteProperty(target, b); }, "gaga");
383})();
384
385
386(function testReflectDeletePropertyOnObject() {
387  for (let target of objects) {
388    prepare(target);
389    assertTrue(Reflect.deleteProperty(target, "bla"));
390    assertEquals(undefined, Object.getOwnPropertyDescriptor(target, "bla"));
391    if (target instanceof Int32Array) {
392      assertFalse(Reflect.deleteProperty(target, 4));
393    } else {
394      assertTrue(Reflect.deleteProperty(target, 4));
395      assertEquals(undefined, Object.getOwnPropertyDescriptor(target, 4));
396    }
397    assertTrue(Reflect.deleteProperty(target, sym));
398    assertEquals(undefined, Object.getOwnPropertyDescriptor(target, sym));
399    assertFalse(Reflect.deleteProperty(target, "noconf"));
400    assertEquals(43, target.noconf);
401    assertTrue(Reflect.deleteProperty(target, "getter"));
402    assertTrue(Reflect.deleteProperty(target, "setter"));
403    assertTrue(Reflect.deleteProperty(target, "foo"));
404    assertTrue(Reflect.deleteProperty(target, 666));
405
406    let proto = target.__proto__;
407    target.__proto__ = { get foo() {return this.bla} };
408    assertEquals(true, Reflect.deleteProperty(target, "foo"));
409    target.__proto__ = proto;
410  }
411})();
412
413
414
415////////////////////////////////////////////////////////////////////////////////
416// Reflect.getPrototypeOf
417
418
419(function testReflectGetPrototypeOfArity() {
420  assertEquals(1, Reflect.getPrototypeOf.length);
421})();
422
423
424(function testReflectGetPrototypeOnNonObject() {
425  assertThrows(function() { Reflect.getPrototypeOf(); }, TypeError);
426  assertThrows(function() { Reflect.getPrototypeOf(42); }, TypeError);
427  assertThrows(function() { Reflect.getPrototypeOf(null); }, TypeError);
428})();
429
430
431// See reflect-get-prototype-of.js for further tests.
432
433
434
435////////////////////////////////////////////////////////////////////////////////
436// Reflect.setPrototypeOf
437
438
439(function testReflectSetPrototypeOfArity() {
440  assertEquals(2, Reflect.setPrototypeOf.length);
441})();
442
443
444(function testReflectSetPrototypeOfOnNonObject() {
445  assertThrows(function() { Reflect.setPrototypeOf(undefined, {}); },
446      TypeError);
447  assertThrows(function() { Reflect.setPrototypeOf(42, {}); }, TypeError);
448  assertThrows(function() { Reflect.setPrototypeOf(null, {}); }, TypeError);
449
450  assertThrows(function() { Reflect.setPrototypeOf({}, undefined); },
451      TypeError);
452  assertThrows(function() { Reflect.setPrototypeOf({}, 42); }, TypeError);
453  assertTrue(Reflect.setPrototypeOf({}, null));
454})();
455
456
457// See reflect-set-prototype-of.js for further tests.
458
459
460
461////////////////////////////////////////////////////////////////////////////////
462// Reflect.isExtensible
463
464
465(function testReflectIsExtensibleArity() {
466  assertEquals(1, Reflect.isExtensible.length);
467})();
468
469
470(function testReflectIsExtensibleOnNonObject() {
471  assertThrows(function() { Reflect.isExtensible(); }, TypeError);
472  assertThrows(function() { Reflect.isExtensible(42); }, TypeError);
473  assertThrows(function() { Reflect.isExtensible(null); }, TypeError);
474})();
475
476
477(function testReflectIsExtensibleOnObject() {
478  // This should be the last test on [objects] as it modifies them irreversibly.
479  for (let target of objects) {
480    prepare(target);
481    if (target instanceof Int32Array) continue;  // issue v8:4460
482    assertTrue(Reflect.isExtensible(target));
483    Object.preventExtensions(target);
484    assertFalse(Reflect.isExtensible(target));
485  }
486})();
487
488
489
490////////////////////////////////////////////////////////////////////////////////
491// Reflect.enumerate
492
493
494(function testReflectEnumerateArity() {
495  assertEquals(1, Reflect.enumerate.length);
496})();
497
498
499(function testReflectEnumerateOnNonObject() {
500  assertThrows(function() { Reflect.enumerate(); }, TypeError);
501  assertThrows(function() { Reflect.enumerate(42); }, TypeError);
502  assertThrows(function() { Reflect.enumerate(null); }, TypeError);
503})();
504
505
506// See reflect-enumerate*.js for further tests.
507
508
509
510////////////////////////////////////////////////////////////////////////////////
511// Reflect.getOwnPropertyDescriptor
512
513
514(function testReflectGetOwnPropertyDescriptorArity() {
515  assertEquals(2, Reflect.getOwnPropertyDescriptor.length);
516})();
517
518
519(function testReflectGetOwnPropertyDescriptorOnNonObject() {
520  assertThrows(function() { Reflect.getOwnPropertyDescriptor(); }, TypeError);
521  assertThrows(function() { Reflect.getOwnPropertyDescriptor(42); },
522      TypeError);
523  assertThrows(function() { Reflect.getOwnPropertyDescriptor(null); },
524      TypeError);
525})();
526
527
528(function testReflectGetOwnPropertyDescriptorKeyConversion() {
529  var target = {bla: 42};
530  var a = { [Symbol.toPrimitive]: function() { return "bla" } };
531  var b = { [Symbol.toPrimitive]: function() { throw "gaga" } };
532  assertEquals(42, Reflect.getOwnPropertyDescriptor(target, a).value);
533  assertThrowsEquals(() => Reflect.getOwnPropertyDescriptor(target, b), "gaga");
534})();
535
536
537// See reflect-get-own-property-descriptor.js for further tests.
538
539
540
541////////////////////////////////////////////////////////////////////////////////
542// Reflect.ownKeys
543
544
545(function testReflectOwnKeysArity() {
546  assertEquals(1, Reflect.ownKeys.length);
547})();
548
549
550(function testReflectOwnKeysOnNonObject() {
551  assertThrows(function() { Reflect.ownKeys(); }, TypeError);
552  assertThrows(function() { Reflect.ownKeys(42); }, TypeError);
553  assertThrows(function() { Reflect.ownKeys(null); }, TypeError);
554})();
555
556
557(function testReflectOwnKeysOnObject(){
558  assertEquals(["z", "y", "x"], Reflect.ownKeys({z: 3, y: 2, x: 1}));
559  assertEquals(["length"], Reflect.ownKeys([]));
560
561  var s1 = Symbol("foo");
562  var s2 = Symbol("bar");
563  var obj = { [s1]: 0, "bla": 0, 42: 0, "0": 0,
564      [s2]: 0, "-1": 0, "88": 0, "aaa": 0 };
565  assertEquals(["0", "42", "88", "bla", "-1", "aaa", s1, s2],
566      Reflect.ownKeys(obj));
567})();
568
569
570// See reflect-own-keys.js for further tests.
571
572
573
574////////////////////////////////////////////////////////////////////////////////
575// Reflect.preventExtensions
576
577
578(function testReflectPreventExtensionsArity() {
579  assertEquals(1, Reflect.preventExtensions.length);
580})();
581
582
583(function testReflectPreventExtensionsOnNonObject() {
584  assertThrows(function() { Reflect.preventExtensions(); }, TypeError);
585  assertThrows(function() { Reflect.preventExtensions(42); }, TypeError);
586  assertThrows(function() { Reflect.preventExtensions(null); }, TypeError);
587})();
588
589
590// See reflect-prevent-extensions.js for further tests.
591
592// TODO(neis): Need proxies to test the situation where
593// [[preventExtensions]] returns false.
594