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