1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.junit.jupiter.api.Test;
20
21
22
23
24
25
26
27 public class ReflectTest extends WebDriverTestCase {
28
29
30
31
32 @Test
33 @Alerts("[object Reflect]")
34 public void testToString() throws Exception {
35 test("log(Reflect.toString())");
36 }
37
38
39
40
41 @Test
42 @Alerts("1")
43 public void apply() throws Exception {
44 test("log(Reflect.apply(Math.floor, undefined, [1.75]))");
45 }
46
47
48
49
50 @Test
51 @Alerts({"1", "true", "4", "arg1", "2", "undefined", "null"})
52 public void applyDetails() throws Exception {
53 final String js =
54 "var o = {};\n"
55 + "var count = 0;\n"
56 + "var results, args;\n"
57
58 + "function fn() {\n"
59 + " count++;\n"
60 + " results = {\n"
61 + " thisArg: this,\n"
62 + " args: arguments\n"
63 + " };\n"
64 + "}\n"
65
66 + "Reflect.apply(fn, o, ['arg1', 2, , null]);\n"
67
68 + "log(count);\n"
69 + "log(results.thisArg === o);\n"
70 + "log(results.args.length);\n"
71 + "log(results.args[0]);\n"
72 + "log(results.args[1]);\n"
73 + "log(results.args[2]);\n"
74 + "log(results.args[3]);\n";
75 test(js);
76 }
77
78
79
80
81 @Test
82 @Alerts("TypeError")
83 public void applyMissingArgs() throws Exception {
84 final String js =
85 "try {\n"
86 + " Reflect.apply();\n"
87 + "} catch(e) {\n"
88 + " logEx(e);\n"
89 + "}";
90 test(js);
91 }
92
93
94
95
96 @Test
97 @Alerts("TypeError")
98 public void applyTargetNotFunction() throws Exception {
99 final String js =
100 "try {\n"
101 + " Reflect.apply({}, undefined, [1.75]);\n"
102 + "} catch(e) {\n"
103 + " logEx(e);\n"
104 + "}";
105 test(js);
106 }
107
108
109
110
111 @Test
112 @Alerts("TypeError")
113 public void applyArgumentsListNotFunction() throws Exception {
114 final String js =
115 "var s1 = Symbol('1');"
116 + "try {\n"
117 + " Reflect.apply(Math.floor, undefined, s1);\n"
118 + "} catch(e) {\n"
119 + " logEx(e);\n"
120 + "}";
121 test(js);
122 }
123
124
125
126
127 @Test
128 @Alerts({"true", "1776"})
129 public void construct() throws Exception {
130 final String js =
131 "var d = Reflect.construct(Date, [1776, 6, 4]);\n"
132 + "log(d instanceof Date);\n"
133 + "log(d.getFullYear());";
134 test(js);
135 }
136
137
138
139
140 @Test
141 @Alerts({"true", "42"})
142 public void defineProperty() throws Exception {
143 final String js =
144 "var o = {};\n"
145
146 + "log(Reflect.defineProperty(o, 'p', { value: 42 }));\n"
147 + "log(o.p);";
148 test(js);
149 }
150
151
152
153
154 @Test
155 @Alerts({"true", "true", "undefined"})
156 public void definePropertyWithoutValue() throws Exception {
157 final String js =
158 "var o = {};\n"
159
160 + "log(Reflect.defineProperty(o, 'p', {}));\n"
161 + "log(Reflect.has(o, 'p'));\n"
162 + "log(o.p);";
163
164 test(js);
165 }
166
167
168
169
170 @Test
171 @Alerts({"false", "undefined"})
172 public void definePropertyFreezed() throws Exception {
173 final String js =
174 "var o = {};\n"
175 + "Object.freeze(o);\n"
176
177 + "log(Reflect.defineProperty(o, 'p', { value: 42 }));\n"
178 + "log(o.p);";
179 test(js);
180 }
181
182
183
184
185 @Test
186 @Alerts({"[get,set,enumerable,configurable]", "false", "true", "true", "true"})
187 public void getOwnPropertyDescriptor() throws Exception {
188 final String js =
189 "var o1 = {};\n"
190 + "var fn = function() {};\n"
191 + "Object.defineProperty(o1, 'p', {\n"
192 + " get: fn,\n"
193 + " configurable: true\n"
194 + "});\n"
195
196 + "var result = Reflect.getOwnPropertyDescriptor(o1, 'p');\n"
197
198 + "log('[' + Object.getOwnPropertyNames(result) + ']');\n"
199 + "log(result.enumerable);\n"
200 + "log(result.configurable);\n"
201 + "log(result.get === fn);\n"
202 + "log(result.set === undefined);";
203 test(js);
204 }
205
206
207
208
209 @Test
210 @Alerts({"true", "false", "false"})
211 public void isExtensible() throws Exception {
212 final String js =
213 "var o1 = {};\n"
214
215 + "log(Reflect.isExtensible(o1));\n"
216
217 + "Reflect.preventExtensions(o1);\n"
218 + "log(Reflect.isExtensible(o1));\n"
219
220 + "var o2 = Object.seal({});\n"
221 + "log(Reflect.isExtensible(o2));\n";
222
223 test(js);
224 }
225
226
227
228
229 @Test
230 @Alerts({"p1,p2", "length"})
231 public void ownKeys() throws Exception {
232 final String js =
233 "var o1 = {\n"
234 + " p1: 42,\n"
235 + " p2: 'one'\n"
236 + "};\n"
237
238 + "var a1 = [];\n"
239
240 + "log(Reflect.ownKeys(o1));\n"
241 + "log(Reflect.ownKeys(a1));";
242 test(js);
243 }
244
245
246
247
248 @Test
249 @Alerts({"0", "6", "8", "55", "773", "str", "-1", "str2", "Symbol(foo)", "Symbol(bar)"})
250 public void ownKeys2() throws Exception {
251 final String js =
252 " var obj = {};\n"
253 + " var s1 = Symbol.for('foo');\n"
254 + " var s2 = Symbol.for('bar');\n"
255
256 + " obj[s1] = 0;\n"
257 + " obj['str'] = 0;\n"
258 + " obj[773] = 0;\n"
259 + " obj['55'] = 0;\n"
260 + " obj[0] = 0;\n"
261 + " obj['-1'] = 0;\n"
262 + " obj[8] = 0;\n"
263 + " obj['6'] = 0;\n"
264 + " obj[s2] = 0;\n"
265 + " obj['str2'] = 0;\n"
266
267 + " for (const key of Reflect.ownKeys(obj)){\n"
268 + " log(String(key));\n;"
269 + " }\n";
270
271 test(js);
272 }
273
274
275
276
277 @Test
278 @Alerts("0")
279 public void ownKeysEmptyObj() throws Exception {
280 final String js =
281 "log(Reflect.ownKeys({}).length)";
282 test(js);
283 }
284
285
286
287
288 @Test
289 @Alerts("0")
290 public void ownKeysDeleteObj() throws Exception {
291 final String js =
292 "var o = { d: 42 };\n"
293 + "delete o.d;\n"
294 + "log(Reflect.ownKeys(o).length);";
295 test(js);
296 }
297
298
299
300
301 @Test
302 @Alerts("length")
303 public void ownKeysEmptyArray() throws Exception {
304 final String js =
305 "log(Reflect.ownKeys([]));";
306 test(js);
307 }
308
309
310
311
312 @Test
313 @Alerts("2,length")
314 public void ownKeysArray() throws Exception {
315 final String js =
316 "log(Reflect.ownKeys([, , 2]));";
317 test(js);
318 }
319
320
321
322
323 @Test
324 @Alerts("p1,p2")
325 public void ownKeysNotEnumerable() throws Exception {
326 final String js =
327 "var o = {};\n"
328 + "Object.defineProperty(o, 'p1', { value: 42, enumerable: false });\n"
329 + "Object.defineProperty(o, 'p2', { get: function() {}, enumerable: false });\n"
330
331 + "log(Reflect.ownKeys(o));";
332 test(js);
333 }
334
335
336
337
338 @Test
339 @Alerts({"true", "false", "true"})
340 public void has() throws Exception {
341 final String js =
342 "var o1 = { p: 42 }\n"
343 + "log(Reflect.has(o1, 'p'));\n"
344 + "log(Reflect.has(o1, 'p2'));\n"
345 + "log(Reflect.has(o1, 'toString'));";
346 test(js);
347 }
348
349
350
351
352 @Test
353 @Alerts({"function () { [native code] }", "true", "false", "true", "true"})
354 public void has2() throws Exception {
355 final String js =
356 " log(Reflect.has.__proto__);\n"
357
358 + " log(Reflect.has({x: 0}, 'x'));\n"
359 + " log(Reflect.has({x: 0}, 'y'));\n"
360 + " log(Reflect.has({x: 0}, 'toString'));\n"
361
362 + " log((Reflect ? Reflect.has : log)({x: 0}, 'x'));\n";
363
364 test(js);
365 }
366
367
368
369
370 @Test
371 @Alerts({"true", "false"})
372 public void hasSymbol() throws Exception {
373 final String js =
374 "var s1 = Symbol('1');\n"
375 + "var s2 = Symbol('1');\n"
376 + "var o = {};\n"
377 + "o[s1] = 42;\n"
378
379 + "log(Reflect.has(o, s1));\n"
380 + "log(Reflect.has(o, 2));";
381 test(js);
382 }
383
384
385
386
387 @Test
388 @Alerts("function")
389 public void hasProto() throws Exception {
390 final String js =
391 "var o1 = { p: 42 }\n"
392 + "log(typeof Reflect.has.__proto__);";
393 test(js);
394 }
395
396
397
398
399 @Test
400 @Alerts({"42", "true", "true", "true"})
401 public void getOwnPropertyDescriptorSymbol() throws Exception {
402 final String js =
403 "var s = Symbol('sym');\n"
404 + "var o = {};\n"
405 + "o[s] = 42;\n"
406
407 + "var result = Reflect.getOwnPropertyDescriptor(o, s);\n"
408
409 + "log(result.value);\n"
410 + "log(result.enumerable);\n"
411 + "log(result.configurable);\n"
412 + "log(result.writable);";
413 test(js);
414 }
415
416
417
418
419 @Test
420 @Alerts("true")
421 public void getOwnPropertyDescriptorUndefinedProperty() throws Exception {
422 final String js =
423 "var o = Object.create({p: 1});\n"
424 + "log(undefined == Reflect.getOwnPropertyDescriptor(o, 'p'));\n";
425 test(js);
426 }
427
428
429
430
431 @Test
432 @Alerts("one")
433 public void getPropertyByInt() throws Exception {
434 final String js =
435 "var a = ['zero', 'one']\n"
436 + "log(Reflect.get(a, 1));";
437 test(js);
438 }
439
440
441
442
443
444 @Test
445 @Alerts({"value 1", "undefined", "foo", "42", "undefined"})
446 public void getProperty() throws Exception {
447 final String js =
448 "var o = {};\n"
449 + "o.p1 = 'value 1';\n"
450
451 + "log(Reflect.get(o, 'p1'));\n"
452
453 + "Object.defineProperty(o, 'p2', { get: undefined });\n"
454 + "log(Reflect.get(o, 'p2'));\n"
455
456 + "Object.defineProperty(o, 'p3', { get: function() { return 'foo'; } });\n"
457 + "log(Reflect.get(o, 'p3'));\n"
458
459 + "var o2 = Object.create({ p: 42 });\n"
460 + "log(Reflect.get(o2, 'p'));\n"
461
462 + "log(Reflect.get(o2, 'u'));";
463
464 test(js);
465 }
466
467
468
469
470 @Test
471 @Alerts({"true", "true", "false"})
472 public void setPrototypeOf() throws Exception {
473 final String js =
474 "var o1 = {};\n"
475
476 + "log(Reflect.setPrototypeOf(o1, Object.prototype));\n"
477 + "log(Reflect.setPrototypeOf(o1, null));\n"
478
479 + "var o2 = {};\n"
480
481 + "log(Reflect.setPrototypeOf(Object.freeze(o2), null));";
482 test(js);
483 }
484
485
486
487
488 @Test
489 @Alerts("false")
490 public void setPrototypeOfCycle() throws Exception {
491 final String js =
492 "var o1 = {};\n"
493 + "log(Reflect.setPrototypeOf(o1, o1));";
494 test(js);
495 }
496
497
498
499
500 @Test
501 @Alerts({"true", "true", "false"})
502 public void setPrototypeOfCycleComplex() throws Exception {
503 final String js =
504 "var o1 = {};\n"
505 + "var o2 = {};\n"
506 + "var o3 = {};\n"
507
508 + "log(Reflect.setPrototypeOf(o1, o2));\n"
509 + "log(Reflect.setPrototypeOf(o2, o3));\n"
510 + "log(Reflect.setPrototypeOf(o3, o1));";
511 test(js);
512 }
513
514
515
516
517 @Test
518 @Alerts({"true", "true", "true"})
519 public void setPrototypeOfSame() throws Exception {
520 final String js =
521 "var o1 = {};\n"
522 + "Object.preventExtensions(o1);\n"
523
524 + "var o2 = Object.create(null);\n"
525 + "Object.preventExtensions(o2);\n"
526
527 + "var proto = {};\n"
528 + "var o3 = Object.create(proto);\n"
529 + "Object.preventExtensions(o3);\n"
530
531 + "log(Reflect.setPrototypeOf(o1, Object.prototype));\n"
532 + "log(Reflect.setPrototypeOf(o2, null));\n"
533 + "log(Reflect.setPrototypeOf(o3, proto));";
534 test(js);
535 }
536
537 private void test(final String js) throws Exception {
538 final String html = DOCTYPE_HTML
539 + "<html><head>\n"
540 + "<body>\n"
541 + "<script>\n"
542 + LOG_TITLE_FUNCTION
543 + " if (typeof Reflect != 'undefined') {\n"
544 + js
545 + " } else { log('no Reflect'); }\n"
546 + "</script>\n"
547 + "</body></html>";
548
549 loadPageVerifyTitle2(html);
550 }
551 }