]> Lady’s Gitweb - Pisces/blob - object.test.js
Move arraylike functions into object.js
[Pisces] / object.test.js
1 // ♓🌟 Piscēs ∷ object.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022–2023 Lady [@ Lady’s Computer].
5 //
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
9
10 import {
11 assert,
12 assertEquals,
13 assertSpyCall,
14 assertSpyCalls,
15 assertStrictEquals,
16 assertThrows,
17 describe,
18 it,
19 spy,
20 } from "./dev-deps.js";
21 import {
22 defineOwnProperties,
23 defineOwnProperty,
24 deleteOwnProperty,
25 freeze,
26 frozenCopy,
27 getMethod,
28 getOwnPropertyDescriptor,
29 getOwnPropertyDescriptors,
30 getOwnPropertyKeys,
31 getOwnPropertyStrings,
32 getOwnPropertySymbols,
33 getPropertyValue,
34 getPrototype,
35 hasOwnProperty,
36 hasProperty,
37 isArraylikeObject,
38 isExtensibleObject,
39 isUnfrozenObject,
40 isUnsealedObject,
41 LazyLoader,
42 lengthOfArraylike,
43 namedEntries,
44 namedKeys,
45 namedValues,
46 objectCreate,
47 objectFromEntries,
48 preventExtensions,
49 PropertyDescriptor,
50 seal,
51 setPropertyValue,
52 setPropertyValues,
53 setPrototype,
54 toObject,
55 toPropertyKey,
56 } from "./object.js";
57
58 describe("LazyLoader", () => {
59 const symbol = Symbol("foo");
60 const prototype = {};
61 const etaoinMethod = spy(() => "success");
62 const shrdluMethod = spy(() => "success");
63 const cmfwypMethod = spy(() => "success");
64 const vbgkqjMethod = spy(() => "success");
65 const methodsObject = Object.create(
66 prototype,
67 {
68 etaoin: {
69 configurable: false,
70 enumerable: true,
71 value: etaoinMethod,
72 writable: false,
73 },
74 shrdlu: {
75 configurable: true,
76 enumerable: false,
77 value: shrdluMethod,
78 writable: false,
79 },
80 cmfwyp: {
81 configurable: true,
82 enumerable: false,
83 get() {
84 return cmfwypMethod;
85 },
86 },
87 vbgkqj: {
88 configurable: false,
89 enumerable: true,
90 get() {
91 return vbgkqjMethod;
92 },
93 set(_) {},
94 },
95 xzfiflffffi: { configurable: true, enumerable: false, set(_) {} },
96 [symbol]: {
97 configurable: true,
98 enumerable: false,
99 value: "failure",
100 writable: true,
101 },
102 },
103 );
104
105 it("[[Call]] throws an error", () => {
106 assertThrows(() => LazyLoader({}));
107 });
108
109 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
110 assertStrictEquals(
111 Object.getPrototypeOf(new LazyLoader(methodsObject)),
112 prototype,
113 );
114 });
115
116 it("[[Construct]] creates a new object with the desired properties", () => {
117 assertEquals(
118 Reflect.ownKeys(new LazyLoader(methodsObject)),
119 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol],
120 );
121 });
122
123 it("[[Construct]] creates a new object with configurable properties", () => {
124 assertEquals(
125 Object.fromEntries(
126 function* (ll) {
127 for (const key of Reflect.ownKeys(ll)) {
128 yield [
129 key,
130 Object.getOwnPropertyDescriptor(ll, key).configurable,
131 ];
132 }
133 }(new LazyLoader(methodsObject)),
134 ),
135 {
136 etaoin: true,
137 shrdlu: true,
138 cmfwyp: true,
139 vbgkqj: true,
140 xzfiflffffi: true,
141 [symbol]: true,
142 },
143 );
144 });
145
146 it("[[Construct]] creates a new object with the correct enumerability", () => {
147 assertEquals(
148 Object.fromEntries(
149 function* (ll) {
150 for (const key of Reflect.ownKeys(ll)) {
151 yield [
152 key,
153 Object.getOwnPropertyDescriptor(ll, key).enumerable,
154 ];
155 }
156 }(new LazyLoader(methodsObject)),
157 ),
158 {
159 etaoin: true,
160 shrdlu: false,
161 cmfwyp: false,
162 vbgkqj: true,
163 xzfiflffffi: false,
164 [symbol]: false,
165 },
166 );
167 });
168
169 it("[[Construct]] creates a new object with defined getters", () => {
170 assertEquals(
171 Object.fromEntries(
172 function* (ll) {
173 for (const key of Reflect.ownKeys(ll)) {
174 yield [
175 key,
176 Object.getOwnPropertyDescriptor(ll, key).get?.name,
177 ];
178 }
179 }(new LazyLoader(methodsObject)),
180 ),
181 {
182 etaoin: "get etaoin",
183 shrdlu: "get shrdlu",
184 cmfwyp: "get cmfwyp",
185 vbgkqj: "get vbgkqj",
186 xzfiflffffi: "get xzfiflffffi",
187 [symbol]: `get [${symbol.description}]`,
188 },
189 );
190 });
191
192 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
193 assertEquals(
194 Object.fromEntries(
195 function* (ll) {
196 for (const key of Reflect.ownKeys(ll)) {
197 yield [
198 key,
199 Object.getOwnPropertyDescriptor(ll, key).set?.name,
200 ];
201 }
202 }(new LazyLoader(methodsObject)),
203 ),
204 {
205 etaoin: undefined,
206 shrdlu: undefined,
207 cmfwyp: undefined,
208 vbgkqj: undefined,
209 xzfiflffffi: undefined,
210 [symbol]: `set [${symbol.description}]`,
211 },
212 );
213 });
214
215 it("[[Construct]] creates a new object with correct getter behaviour", () => {
216 const ll = new LazyLoader(methodsObject);
217 ll.etaoin;
218 assertEquals(
219 Object.getOwnPropertyDescriptor(ll, "etaoin"),
220 {
221 configurable: false,
222 enumerable: true,
223 value: "success",
224 writable: false,
225 },
226 );
227 assertSpyCalls(etaoinMethod, 1);
228 assertSpyCall(etaoinMethod, 0, {
229 args: [],
230 self: ll,
231 returned: "success",
232 });
233 ll.shrdlu;
234 assertEquals(
235 Object.getOwnPropertyDescriptor(ll, "shrdlu"),
236 {
237 configurable: true,
238 enumerable: false,
239 value: "success",
240 writable: false,
241 },
242 );
243 assertSpyCalls(shrdluMethod, 1);
244 assertSpyCall(shrdluMethod, 0, {
245 args: [],
246 self: ll,
247 returned: "success",
248 });
249 ll.cmfwyp;
250 assertEquals(
251 Object.getOwnPropertyDescriptor(ll, "cmfwyp"),
252 {
253 configurable: true,
254 enumerable: false,
255 value: "success",
256 writable: false,
257 },
258 );
259 assertSpyCalls(cmfwypMethod, 1);
260 assertSpyCall(cmfwypMethod, 0, {
261 args: [],
262 self: ll,
263 returned: "success",
264 });
265 ll.vbgkqj;
266 assertEquals(
267 Object.getOwnPropertyDescriptor(ll, "vbgkqj"),
268 {
269 configurable: false,
270 enumerable: true,
271 value: "success",
272 writable: false,
273 },
274 );
275 assertSpyCalls(vbgkqjMethod, 1);
276 assertSpyCall(vbgkqjMethod, 0, {
277 args: [],
278 self: ll,
279 returned: "success",
280 });
281 assertThrows(() => ll.xzfiflffffi);
282 assertThrows(() => ll[symbol]);
283 });
284
285 it("[[Construct]] creates a new object with correct setter behaviour", () => {
286 const ll = new LazyLoader(methodsObject);
287 ll[symbol] = "success";
288 assertEquals(
289 Object.getOwnPropertyDescriptor(ll, symbol),
290 {
291 configurable: true,
292 enumerable: false,
293 value: "success",
294 writable: true,
295 },
296 );
297 });
298
299 describe(".length", () => {
300 it("[[Get]] returns the correct length", () => {
301 assertStrictEquals(LazyLoader.length, 1);
302 });
303 });
304
305 describe(".name", () => {
306 it("[[Get]] returns the correct name", () => {
307 assertStrictEquals(LazyLoader.name, "LazyLoader");
308 });
309 });
310 });
311
312 describe("PropertyDescriptor", () => {
313 it("[[Call]] throws an error", () => {
314 assertThrows(() => PropertyDescriptor({}));
315 });
316
317 it("[[Construct]] creates a new PropertyDescriptor", () => {
318 assertStrictEquals(
319 Object.getPrototypeOf(new PropertyDescriptor({})),
320 PropertyDescriptor.prototype,
321 );
322 });
323
324 it("[[Construct]] throws for primitives", () => {
325 assertThrows(() => new PropertyDescriptor("failure"));
326 });
327
328 describe(".length", () => {
329 it("[[Get]] returns the correct length", () => {
330 assertStrictEquals(PropertyDescriptor.length, 1);
331 });
332 });
333
334 describe(".name", () => {
335 it("[[Get]] returns the correct name", () => {
336 assertStrictEquals(
337 PropertyDescriptor.name,
338 "PropertyDescriptor",
339 );
340 });
341 });
342
343 describe("::complete", () => {
344 it("[[Call]] completes a generic descriptor", () => {
345 const desc = {};
346 PropertyDescriptor.prototype.complete.call(desc);
347 assertEquals(desc, {
348 configurable: false,
349 enumerable: false,
350 value: undefined,
351 writable: false,
352 });
353 });
354
355 it("[[Call]] completes a data descriptor", () => {
356 const desc = { value: undefined };
357 PropertyDescriptor.prototype.complete.call(desc);
358 assertEquals(desc, {
359 configurable: false,
360 enumerable: false,
361 value: undefined,
362 writable: false,
363 });
364 });
365
366 it("[[Call]] completes an accessor descriptor", () => {
367 const desc = { get: undefined };
368 PropertyDescriptor.prototype.complete.call(desc);
369 assertEquals(desc, {
370 configurable: false,
371 enumerable: false,
372 get: undefined,
373 set: undefined,
374 });
375 });
376
377 describe(".length", () => {
378 it("[[Get]] returns the correct length", () => {
379 assertStrictEquals(
380 PropertyDescriptor.prototype.complete.length,
381 0,
382 );
383 });
384 });
385
386 describe(".name", () => {
387 it("[[Get]] returns the correct name", () => {
388 assertStrictEquals(
389 PropertyDescriptor.prototype.complete.name,
390 "complete",
391 );
392 });
393 });
394 });
395
396 describe("::isAccessorDescriptor", () => {
397 it("[[Get]] returns false for a generic descriptor", () => {
398 assertStrictEquals(
399 Reflect.get(
400 PropertyDescriptor.prototype,
401 "isAccessorDescriptor",
402 {},
403 ),
404 false,
405 );
406 });
407
408 it("[[Get]] returns false for a data descriptor", () => {
409 assertStrictEquals(
410 Reflect.get(
411 PropertyDescriptor.prototype,
412 "isAccessorDescriptor",
413 { value: undefined },
414 ),
415 false,
416 );
417 });
418
419 it("[[Get]] returns true for an accessor descriptor", () => {
420 assertStrictEquals(
421 Reflect.get(
422 PropertyDescriptor.prototype,
423 "isAccessorDescriptor",
424 { get: undefined },
425 ),
426 true,
427 );
428 });
429
430 describe("[[GetOwnProperty]].get.length", () => {
431 it("[[Get]] returns the correct length", () => {
432 assertStrictEquals(
433 Object.getOwnPropertyDescriptor(
434 PropertyDescriptor.prototype,
435 "isAccessorDescriptor",
436 ).get.length,
437 0,
438 );
439 });
440 });
441
442 describe("[[GetOwnProperty]].get.name", () => {
443 it("[[Get]] returns the correct name", () => {
444 assertStrictEquals(
445 Object.getOwnPropertyDescriptor(
446 PropertyDescriptor.prototype,
447 "isAccessorDescriptor",
448 ).get.name,
449 "get isAccessorDescriptor",
450 );
451 });
452 });
453 });
454
455 describe("::isDataDescriptor", () => {
456 it("[[Get]] returns false for a generic descriptor", () => {
457 assertStrictEquals(
458 Reflect.get(
459 PropertyDescriptor.prototype,
460 "isDataDescriptor",
461 {},
462 ),
463 false,
464 );
465 });
466
467 it("[[Get]] returns true for a data descriptor", () => {
468 assertStrictEquals(
469 Reflect.get(
470 PropertyDescriptor.prototype,
471 "isDataDescriptor",
472 { value: undefined },
473 ),
474 true,
475 );
476 });
477
478 it("[[Get]] returns false for an accessor descriptor", () => {
479 assertStrictEquals(
480 Reflect.get(
481 PropertyDescriptor.prototype,
482 "isDataDescriptor",
483 { get: undefined },
484 ),
485 false,
486 );
487 });
488
489 describe("[[GetOwnProperty]].get.length", () => {
490 it("[[Get]] returns the correct length", () => {
491 assertStrictEquals(
492 Object.getOwnPropertyDescriptor(
493 PropertyDescriptor.prototype,
494 "isDataDescriptor",
495 ).get.length,
496 0,
497 );
498 });
499 });
500
501 describe("[[GetOwnProperty]].get.name", () => {
502 it("[[Get]] returns the correct name", () => {
503 assertStrictEquals(
504 Object.getOwnPropertyDescriptor(
505 PropertyDescriptor.prototype,
506 "isDataDescriptor",
507 ).get.name,
508 "get isDataDescriptor",
509 );
510 });
511 });
512 });
513
514 describe("::isFullyPopulated", () => {
515 it("[[Get]] returns false for a generic descriptor", () => {
516 assertStrictEquals(
517 Reflect.get(
518 PropertyDescriptor.prototype,
519 "isFullyPopulated",
520 {},
521 ),
522 false,
523 );
524 });
525
526 it("[[Get]] returns false for a non‐fully‐populated data descriptor", () => {
527 assertStrictEquals(
528 Reflect.get(
529 PropertyDescriptor.prototype,
530 "isFullyPopulated",
531 { value: undefined },
532 ),
533 false,
534 );
535 });
536
537 it("[[Get]] returns true for a fully‐populated data descriptor", () => {
538 assertStrictEquals(
539 Reflect.get(PropertyDescriptor.prototype, "isFullyPopulated", {
540 configurable: true,
541 enumerable: true,
542 value: undefined,
543 writable: true,
544 }),
545 true,
546 );
547 });
548
549 it("[[Get]] returns false for a non‐fully‐populated accessor descriptor", () => {
550 assertStrictEquals(
551 Reflect.get(
552 PropertyDescriptor.prototype,
553 "isFullyPopulated",
554 { get: undefined },
555 ),
556 false,
557 );
558 });
559
560 it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
561 assertStrictEquals(
562 Reflect.get(PropertyDescriptor.prototype, "isFullyPopulated", {
563 configurable: true,
564 enumerable: true,
565 get: undefined,
566 set: undefined,
567 }),
568 true,
569 );
570 });
571
572 describe("[[GetOwnProperty]].get.length", () => {
573 it("[[Get]] returns the correct length", () => {
574 assertStrictEquals(
575 Object.getOwnPropertyDescriptor(
576 PropertyDescriptor.prototype,
577 "isFullyPopulated",
578 ).get.length,
579 0,
580 );
581 });
582 });
583
584 describe("[[GetOwnProperty]].get.name", () => {
585 it("[[Get]] returns the correct name", () => {
586 assertStrictEquals(
587 Object.getOwnPropertyDescriptor(
588 PropertyDescriptor.prototype,
589 "isFullyPopulated",
590 ).get.name,
591 "get isFullyPopulated",
592 );
593 });
594 });
595 });
596
597 describe("::isGenericDescriptor", () => {
598 it("[[Get]] returns true for a generic descriptor", () => {
599 assertStrictEquals(
600 Reflect.get(
601 PropertyDescriptor.prototype,
602 "isGenericDescriptor",
603 {},
604 ),
605 true,
606 );
607 });
608
609 it("[[Get]] returns true for a data descriptor", () => {
610 assertStrictEquals(
611 Reflect.get(
612 PropertyDescriptor.prototype,
613 "isGenericDescriptor",
614 { value: undefined },
615 ),
616 false,
617 );
618 });
619
620 it("[[Get]] returns false for an accessor descriptor", () => {
621 assertStrictEquals(
622 Reflect.get(
623 PropertyDescriptor.prototype,
624 "isGenericDescriptor",
625 { get: undefined },
626 ),
627 false,
628 );
629 });
630
631 describe("[[GetOwnProperty]].get.length", () => {
632 it("[[Get]] returns the correct length", () => {
633 assertStrictEquals(
634 Object.getOwnPropertyDescriptor(
635 PropertyDescriptor.prototype,
636 "isGenericDescriptor",
637 ).get.length,
638 0,
639 );
640 });
641 });
642
643 describe("[[GetOwnProperty]].get.name", () => {
644 it("[[Get]] returns the correct name", () => {
645 assertStrictEquals(
646 Object.getOwnPropertyDescriptor(
647 PropertyDescriptor.prototype,
648 "isGenericDescriptor",
649 ).get.name,
650 "get isGenericDescriptor",
651 );
652 });
653 });
654 });
655
656 describe("~configurable", () => {
657 it("[[DefineOwnProperty]] coerces to a boolean", () => {
658 const desc = new PropertyDescriptor({});
659 Object.defineProperty(desc, "configurable", {});
660 assertStrictEquals(desc.configurable, false);
661 });
662
663 it("[[DefineOwnProperty]] throws for accessor properties", () => {
664 const desc = new PropertyDescriptor({});
665 assertThrows(() =>
666 Object.defineProperty(desc, "configurable", { get: undefined })
667 );
668 });
669
670 it("[[Set]] coerces to a boolean", () => {
671 const desc = new PropertyDescriptor({});
672 desc.configurable = undefined;
673 assertStrictEquals(desc.configurable, false);
674 });
675
676 it("[[Delete]] works", () => {
677 const desc = new PropertyDescriptor({ configurable: false });
678 delete desc.configurable;
679 assert(!("configurable" in desc));
680 });
681 });
682
683 describe("~enumerable", () => {
684 it("[[DefineOwnProperty]] coerces to a boolean", () => {
685 const desc = new PropertyDescriptor({});
686 Object.defineProperty(desc, "enumerable", {});
687 assertStrictEquals(desc.enumerable, false);
688 });
689
690 it("[[DefineOwnProperty]] throws for accessor properties", () => {
691 const desc = new PropertyDescriptor({});
692 assertThrows(() =>
693 Object.defineProperty(desc, "enumerable", { get: undefined })
694 );
695 });
696
697 it("[[Set]] coerces to a boolean", () => {
698 const desc = new PropertyDescriptor({});
699 desc.enumerable = undefined;
700 assertStrictEquals(desc.enumerable, false);
701 });
702
703 it("[[Delete]] works", () => {
704 const desc = new PropertyDescriptor({ enumerable: false });
705 delete desc.enumerable;
706 assert(!("enumerable" in desc));
707 });
708 });
709
710 describe("~get", () => {
711 it("[[DefineOwnProperty]] works", () => {
712 const desc = new PropertyDescriptor({});
713 Object.defineProperty(desc, "get", {});
714 assertStrictEquals(desc.get, undefined);
715 });
716
717 it("[[DefineOwnProperty]] throws for accessor properties", () => {
718 const desc = new PropertyDescriptor({});
719 assertThrows(() =>
720 Object.defineProperty(desc, "get", { get: undefined })
721 );
722 });
723
724 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
725 const desc = new PropertyDescriptor({});
726 assertThrows(
727 () => Object.defineProperty(desc, "get", { value: null }),
728 );
729 });
730
731 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
732 const desc = new PropertyDescriptor({ value: undefined });
733 assertThrows(() => Object.defineProperty(desc, "get", {}));
734 });
735
736 it("[[Set]] works", () => {
737 const desc = new PropertyDescriptor({});
738 const fn = () => {};
739 desc.get = fn;
740 assertStrictEquals(desc.get, fn);
741 });
742
743 it("[[Set]] throws if not callable or undefined", () => {
744 const desc = new PropertyDescriptor({});
745 assertThrows(() => desc.get = null);
746 });
747
748 it("[[Set]] throws if a data property is defined", () => {
749 const desc = new PropertyDescriptor({ value: undefined });
750 assertThrows(() => desc.get = undefined);
751 });
752
753 it("[[Delete]] works", () => {
754 const desc = new PropertyDescriptor({ get: undefined });
755 delete desc.get;
756 assert(!("get" in desc));
757 });
758 });
759
760 describe("~set", () => {
761 it("[[DefineOwnProperty]] works", () => {
762 const desc = new PropertyDescriptor({});
763 Object.defineProperty(desc, "set", {});
764 assertStrictEquals(desc.set, undefined);
765 });
766
767 it("[[DefineOwnProperty]] throws for accessor properties", () => {
768 const desc = new PropertyDescriptor({});
769 assertThrows(() =>
770 Object.defineProperty(desc, "set", { get: undefined })
771 );
772 });
773
774 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
775 const desc = new PropertyDescriptor({});
776 assertThrows(
777 () => Object.defineProperty(desc, "set", { value: null }),
778 );
779 });
780
781 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
782 const desc = new PropertyDescriptor({ value: undefined });
783 assertThrows(() => Object.defineProperty(desc, "set", {}));
784 });
785
786 it("[[Set]] works", () => {
787 const desc = new PropertyDescriptor({});
788 const fn = (_) => {};
789 desc.set = fn;
790 assertStrictEquals(desc.set, fn);
791 });
792
793 it("[[Set]] throws if not callable or undefined", () => {
794 const desc = new PropertyDescriptor({});
795 assertThrows(() => desc.set = null);
796 });
797
798 it("[[Set]] throws if a data property is defined", () => {
799 const desc = new PropertyDescriptor({ value: undefined });
800 assertThrows(() => desc.set = undefined);
801 });
802
803 it("[[Delete]] works", () => {
804 const desc = new PropertyDescriptor({ set: undefined });
805 delete desc.set;
806 assert(!("set" in desc));
807 });
808 });
809
810 describe("~value", () => {
811 it("[[DefineOwnProperty]] works", () => {
812 const desc = new PropertyDescriptor({});
813 Object.defineProperty(desc, "value", {});
814 assertStrictEquals(desc.value, undefined);
815 });
816
817 it("[[DefineOwnProperty]] throws for accessor properties", () => {
818 const desc = new PropertyDescriptor({});
819 assertThrows(() =>
820 Object.defineProperty(desc, "value", { get: undefined })
821 );
822 });
823
824 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
825 const desc = new PropertyDescriptor({ get: undefined });
826 assertThrows(() => Object.defineProperty(desc, "value", {}));
827 });
828
829 it("[[Set]] works", () => {
830 const desc = new PropertyDescriptor({});
831 desc.value = "success";
832 assertStrictEquals(desc.value, "success");
833 });
834
835 it("[[Set]] throws if an accessor property is defined", () => {
836 const desc = new PropertyDescriptor({ get: undefined });
837 assertThrows(() => desc.value = null);
838 });
839
840 it("[[Delete]] works", () => {
841 const desc = new PropertyDescriptor({ value: undefined });
842 delete desc.value;
843 assert(!("value" in desc));
844 });
845 });
846
847 describe("~writable", () => {
848 it("[[DefineOwnProperty]] coerces to a boolean", () => {
849 const desc = new PropertyDescriptor({});
850 Object.defineProperty(desc, "writable", {});
851 assertStrictEquals(desc.writable, false);
852 });
853
854 it("[[DefineOwnProperty]] throws for accessor properties", () => {
855 const desc = new PropertyDescriptor({});
856 assertThrows(() =>
857 Object.defineProperty(desc, "writable", { get: undefined })
858 );
859 });
860
861 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
862 const desc = new PropertyDescriptor({ get: undefined });
863 assertThrows(() => Object.defineProperty(desc, "writable", {}));
864 });
865
866 it("[[Set]] coerces to a boolean", () => {
867 const desc = new PropertyDescriptor({});
868 desc.writable = undefined;
869 assertStrictEquals(desc.writable, false);
870 });
871
872 it("[[Set]] throws if an accessor property is defined", () => {
873 const desc = new PropertyDescriptor({ get: undefined });
874 assertThrows(() => desc.writable = false);
875 });
876
877 it("[[Delete]] works", () => {
878 const desc = new PropertyDescriptor({ writable: false });
879 delete desc.writable;
880 assert(!("writable" in desc));
881 });
882 });
883 });
884
885 describe("defineOwnProperty", () => {
886 it("[[Call]] defines the property", () => {
887 const obj = {};
888 defineOwnProperty(obj, "etaoin", {});
889 assert("etaoin" in obj);
890 });
891
892 it("[[Call]] returns the provided object", () => {
893 const obj = {};
894 assertStrictEquals(defineOwnProperty(obj, "etaoin", {}), obj);
895 });
896
897 it("[[Construct]] throws an error", () => {
898 assertThrows(() => new defineOwnProperty(obj, "etaoin", {}));
899 });
900
901 describe(".length", () => {
902 it("[[Get]] returns the correct length", () => {
903 assertStrictEquals(defineOwnProperty.length, 3);
904 });
905 });
906
907 describe(".name", () => {
908 it("[[Get]] returns the correct name", () => {
909 assertStrictEquals(
910 defineOwnProperty.name,
911 "defineOwnProperty",
912 );
913 });
914 });
915 });
916
917 describe("defineOwnProperties", () => {
918 it("[[Call]] defines properties from the provided objects", () => {
919 const obj = {};
920 defineOwnProperties(obj, {
921 etaoin: {},
922 shrdlu: {},
923 }, { cmfwyp: {} });
924 assert("etaoin" in obj);
925 assert("shrdlu" in obj);
926 assert("cmfwyp" in obj);
927 });
928
929 it("[[Call]] overrides earlier declarations with later ones", () => {
930 const obj = { etaoin: undefined };
931 defineOwnProperties(obj, {
932 etaoin: { value: "failure" },
933 }, {
934 etaoin: { value: "success" },
935 });
936 assertStrictEquals(obj.etaoin, "success");
937 });
938
939 it("[[Call]] returns the provided object", () => {
940 const obj = {};
941 assertStrictEquals(defineOwnProperties(obj), obj);
942 });
943
944 it("[[Construct]] throws an error", () => {
945 assertThrows(() => new defineOwnProperties({}));
946 });
947
948 describe(".length", () => {
949 it("[[Get]] returns the correct length", () => {
950 assertStrictEquals(defineOwnProperties.length, 1);
951 });
952 });
953
954 describe(".name", () => {
955 it("[[Get]] returns the correct name", () => {
956 assertStrictEquals(
957 defineOwnProperties.name,
958 "defineOwnProperties",
959 );
960 });
961 });
962 });
963
964 describe("deleteOwnProperty", () => {
965 it("[[Call]] deletes the provided property on the provided object", () => {
966 const obj = { failure: undefined };
967 deleteOwnProperty(obj, "failure");
968 assert(!("failure" in obj));
969 });
970
971 it("[[Call]] does nothing if the property doesn’t exist", () => {
972 const obj = Object.freeze({});
973 deleteOwnProperty(obj, "failure");
974 assert(!("failure" in obj));
975 });
976
977 it("[[Call]] throws if the property can’t be deleted", () => {
978 const obj = Object.seal({ failure: undefined });
979 assertThrows(() => deleteOwnProperty(obj, "failure"));
980 });
981
982 it("[[Call]] returns the provided object", () => {
983 const obj = {};
984 assertStrictEquals(deleteOwnProperty(obj, ""), obj);
985 });
986
987 it("[[Construct]] throws an error", () => {
988 assertThrows(() => new deleteOwnProperty({}, ""));
989 });
990
991 describe(".length", () => {
992 it("[[Get]] returns the correct length", () => {
993 assertStrictEquals(deleteOwnProperty.length, 2);
994 });
995 });
996
997 describe(".name", () => {
998 it("[[Get]] returns the correct name", () => {
999 assertStrictEquals(deleteOwnProperty.name, "deleteOwnProperty");
1000 });
1001 });
1002 });
1003
1004 describe("freeze", () => {
1005 it("[[Call]] freezes the object", () => {
1006 const obj = {};
1007 freeze(obj);
1008 assert(Object.isFrozen(obj));
1009 });
1010
1011 it("[[Call]] returns the provided object", () => {
1012 const obj = {};
1013 assertStrictEquals(freeze(obj), obj);
1014 });
1015
1016 it("[[Construct]] throws an error", () => {
1017 assertThrows(() => new freeze({}));
1018 });
1019
1020 describe(".length", () => {
1021 it("[[Get]] returns the correct length", () => {
1022 assertStrictEquals(freeze.length, 1);
1023 });
1024 });
1025
1026 describe(".name", () => {
1027 it("[[Get]] returns the correct name", () => {
1028 assertStrictEquals(freeze.name, "freeze");
1029 });
1030 });
1031 });
1032
1033 describe("frozenCopy", () => {
1034 it("[[Call]] returns a frozen object", () => {
1035 assert(
1036 Object.isFrozen(
1037 frozenCopy(Object.create(null), {
1038 data: {
1039 configurable: true,
1040 enumerable: true,
1041 value: undefined,
1042 writable: true,
1043 },
1044 accessor: {
1045 configurable: true,
1046 enumerable: true,
1047 get: undefined,
1048 },
1049 }),
1050 ),
1051 );
1052 });
1053
1054 it("[[Call]] ignores non·enumerable properties", () => {
1055 assertEquals(
1056 frozenCopy(
1057 Object.create(null, {
1058 data: { value: undefined },
1059 accessor: { get: undefined },
1060 }),
1061 ),
1062 {},
1063 );
1064 });
1065
1066 it("[[Call]] preserves accessor properties", () => {
1067 const properties = {
1068 both: {
1069 configurable: false,
1070 enumerable: true,
1071 get: () => {},
1072 set: (_) => {},
1073 },
1074 empty: {
1075 configurable: false,
1076 enumerable: true,
1077 get: undefined,
1078 set: undefined,
1079 },
1080 getter: {
1081 configurable: false,
1082 enumerable: true,
1083 get: () => {},
1084 set: undefined,
1085 },
1086 setter: {
1087 configurable: false,
1088 enumerable: true,
1089 get: undefined,
1090 set: (_) => {},
1091 },
1092 };
1093 assertEquals(
1094 Object.getOwnPropertyDescriptors(
1095 frozenCopy(Object.create(null, properties)),
1096 ),
1097 properties,
1098 );
1099 });
1100
1101 it("[[Call]] does not copy properties on the prototype", () => {
1102 assert(
1103 !("failure" in
1104 frozenCopy(Object.create({ failure: undefined }), {
1105 data: {
1106 configurable: true,
1107 value: undefined,
1108 writable: true,
1109 },
1110 accessor: { configurable: true, get: undefined },
1111 })),
1112 );
1113 });
1114
1115 it("[[Call]] uses the species of the constructor", () => {
1116 const species = { prototype: {} };
1117 assertStrictEquals(
1118 Object.getPrototypeOf(
1119 frozenCopy({}, { [Symbol.species]: species }),
1120 ),
1121 species.prototype,
1122 );
1123 });
1124
1125 it("[[Call]] uses constructor if no species is defined", () => {
1126 const constructor = { [Symbol.species]: null, prototype: {} };
1127 assertStrictEquals(
1128 Object.getPrototypeOf(frozenCopy({}, constructor)),
1129 constructor.prototype,
1130 );
1131 });
1132
1133 it("[[Call]] uses the constructor on the object if none is provided", () => {
1134 const constructor = { [Symbol.species]: null, prototype: {} };
1135 assertStrictEquals(
1136 Object.getPrototypeOf(frozenCopy({ constructor })),
1137 constructor.prototype,
1138 );
1139 });
1140
1141 it("[[Call]] allows a null constructor", () => {
1142 assertStrictEquals(
1143 Object.getPrototypeOf(frozenCopy({}, null)),
1144 null,
1145 );
1146 });
1147
1148 it("[[Construct]] throws an error", () => {
1149 assertThrows(() => new frozenCopy({}));
1150 });
1151
1152 describe(".length", () => {
1153 it("[[Get]] returns the correct length", () => {
1154 assertStrictEquals(frozenCopy.length, 1);
1155 });
1156 });
1157
1158 describe(".name", () => {
1159 it("[[Get]] returns the correct name", () => {
1160 assertStrictEquals(frozenCopy.name, "frozenCopy");
1161 });
1162 });
1163 });
1164
1165 describe("getMethod", () => {
1166 it("[[Call]] gets a method", () => {
1167 const method = () => {};
1168 assertStrictEquals(getMethod({ method }, "method"), method);
1169 });
1170
1171 it("[[Call]] works for values coercible to objects", () => {
1172 assertEquals(getMethod("", "toString"), String.prototype.toString);
1173 });
1174
1175 it("[[Call]] throws for null and undefined", () => {
1176 assertThrows(() => getMethod(null, "valueOf"));
1177 assertThrows(() => getMethod(undefined, "valueOf"));
1178 });
1179
1180 it("[[Call]] throws if the resulting value isn’t callable", () => {
1181 assertThrows(() => getMethod({ "failure": true }, "failure"));
1182 });
1183
1184 it("[[Construct]] throws an error", () => {
1185 assertThrows(() => new getMethod({ method() {} }, "method"));
1186 });
1187
1188 describe(".length", () => {
1189 it("[[Get]] returns the correct length", () => {
1190 assertStrictEquals(getMethod.length, 2);
1191 });
1192 });
1193
1194 describe(".name", () => {
1195 it("[[Get]] returns the correct name", () => {
1196 assertStrictEquals(getMethod.name, "getMethod");
1197 });
1198 });
1199 });
1200
1201 describe("getOwnPropertyDescriptor", () => {
1202 it("[[Call]] gets the descriptor", () => {
1203 assertEquals(
1204 getOwnPropertyDescriptor({ success: true }, "success"),
1205 {
1206 configurable: true,
1207 enumerable: true,
1208 value: true,
1209 writable: true,
1210 },
1211 );
1212 });
1213
1214 it("[[Call]] returns undefined for non‐own properties", () => {
1215 assertStrictEquals(
1216 getOwnPropertyDescriptor({}, "valueOf"),
1217 undefined,
1218 );
1219 });
1220
1221 it("[[Construct]] throws an error", () => {
1222 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
1223 });
1224
1225 describe(".length", () => {
1226 it("[[Get]] returns the correct length", () => {
1227 assertStrictEquals(getOwnPropertyDescriptor.length, 2);
1228 });
1229 });
1230
1231 describe(".name", () => {
1232 it("[[Get]] returns the correct name", () => {
1233 assertStrictEquals(
1234 getOwnPropertyDescriptor.name,
1235 "getOwnPropertyDescriptor",
1236 );
1237 });
1238 });
1239 });
1240
1241 describe("getOwnPropertyDescriptors", () => {
1242 it("[[Call]] gets the descriptors", () => {
1243 assertEquals(
1244 getOwnPropertyDescriptors({ success: true, etaoin: "shrdlu" }),
1245 {
1246 success: {
1247 configurable: true,
1248 enumerable: true,
1249 value: true,
1250 writable: true,
1251 },
1252 etaoin: {
1253 configurable: true,
1254 enumerable: true,
1255 value: "shrdlu",
1256 writable: true,
1257 },
1258 },
1259 );
1260 });
1261
1262 it("[[Construct]] throws an error", () => {
1263 assertThrows(() => new getOwnPropertyDescriptors({}));
1264 });
1265
1266 describe(".length", () => {
1267 it("[[Get]] returns the correct length", () => {
1268 assertStrictEquals(getOwnPropertyDescriptors.length, 1);
1269 });
1270 });
1271
1272 describe(".name", () => {
1273 it("[[Get]] returns the correct name", () => {
1274 assertStrictEquals(
1275 getOwnPropertyDescriptors.name,
1276 "getOwnPropertyDescriptors",
1277 );
1278 });
1279 });
1280 });
1281
1282 describe("getOwnPropertyKeys", () => {
1283 it("[[Call]] gets own (but not inherited) property keys", () => {
1284 assertEquals(getOwnPropertyKeys({ success: true }), ["success"]);
1285 });
1286
1287 it("[[Call]] works for values coercible to objects", () => {
1288 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
1289 });
1290
1291 it("[[Call]] throws for null and undefined", () => {
1292 assertThrows(() => getOwnPropertyKeys(null));
1293 assertThrows(() => getOwnPropertyKeys(undefined));
1294 });
1295
1296 it("[[Construct]] throws an error", () => {
1297 assertThrows(() => new getOwnPropertyKeys({}));
1298 });
1299
1300 describe(".length", () => {
1301 it("[[Get]] returns the correct length", () => {
1302 assertStrictEquals(getOwnPropertyKeys.length, 1);
1303 });
1304 });
1305
1306 describe(".name", () => {
1307 it("[[Get]] returns the correct name", () => {
1308 assertStrictEquals(
1309 getOwnPropertyKeys.name,
1310 "getOwnPropertyKeys",
1311 );
1312 });
1313 });
1314 });
1315
1316 describe("getOwnPropertyStrings", () => {
1317 it("[[Call]] gets own string keys", () => {
1318 assertEquals(getOwnPropertyStrings({ success: true }), [
1319 "success",
1320 ]);
1321 });
1322
1323 it("[[Call]] works for values coercible to objects", () => {
1324 assertEquals(getOwnPropertyStrings("foo"), [
1325 "0",
1326 "1",
1327 "2",
1328 "length",
1329 ]);
1330 });
1331
1332 it("[[Call]] throws for null and undefined", () => {
1333 assertThrows(() => getOwnPropertyStrings(null));
1334 assertThrows(() => getOwnPropertyStrings(undefined));
1335 });
1336
1337 it("[[Construct]] throws an error", () => {
1338 assertThrows(() => new getOwnPropertyStrings({}));
1339 });
1340
1341 describe(".length", () => {
1342 it("[[Get]] returns the correct length", () => {
1343 assertStrictEquals(getOwnPropertyStrings.length, 1);
1344 });
1345 });
1346
1347 describe(".name", () => {
1348 it("[[Get]] returns the correct name", () => {
1349 assertStrictEquals(
1350 getOwnPropertyStrings.name,
1351 "getOwnPropertyStrings",
1352 );
1353 });
1354 });
1355 });
1356
1357 describe("getOwnPropertySymbols", () => {
1358 it("[[Call]] gets own symbol keys", () => {
1359 const sym = Symbol();
1360 assertEquals(getOwnPropertySymbols({ [sym]: true }), [sym]);
1361 });
1362
1363 it("[[Call]] works for values coercible to objects", () => {
1364 assertEquals(getOwnPropertySymbols("foo"), []);
1365 });
1366
1367 it("[[Call]] throws for null and undefined", () => {
1368 assertThrows(() => getOwnPropertySymbols(null));
1369 assertThrows(() => getOwnPropertySymbols(undefined));
1370 });
1371
1372 it("[[Construct]] throws an error", () => {
1373 assertThrows(() => new getOwnPropertySymbols({}));
1374 });
1375
1376 describe(".length", () => {
1377 it("[[Get]] returns the correct length", () => {
1378 assertStrictEquals(getOwnPropertySymbols.length, 1);
1379 });
1380 });
1381
1382 describe(".name", () => {
1383 it("[[Get]] returns the correct name", () => {
1384 assertStrictEquals(
1385 getOwnPropertySymbols.name,
1386 "getOwnPropertySymbols",
1387 );
1388 });
1389 });
1390 });
1391
1392 describe("getPropertyValue", () => {
1393 it("[[Call]] gets property values on the provided object", () => {
1394 assertStrictEquals(
1395 getPropertyValue({ success: true }, "success"),
1396 true,
1397 );
1398 });
1399
1400 it("[[Call]] works for values coercible to objects", () => {
1401 assertStrictEquals(
1402 getPropertyValue("", "toString"),
1403 String.prototype.toString,
1404 );
1405 });
1406
1407 it("[[Call]] throws for null and undefined", () => {
1408 assertThrows(() => getPropertyValue(null, "valueOf"));
1409 assertThrows(() => getPropertyValue(undefined, "valueOf"));
1410 });
1411
1412 it("[[Construct]] throws an error", () => {
1413 assertThrows(() => new getPropertyValue({}, "valueOf"));
1414 });
1415
1416 describe(".length", () => {
1417 it("[[Get]] returns the correct length", () => {
1418 assertStrictEquals(getPropertyValue.length, 2);
1419 });
1420 });
1421
1422 describe(".name", () => {
1423 it("[[Get]] returns the correct name", () => {
1424 assertStrictEquals(getPropertyValue.name, "getPropertyValue");
1425 });
1426 });
1427 });
1428
1429 describe("getPrototype", () => {
1430 it("[[Call]] gets object prototypes", () => {
1431 assertStrictEquals(getPrototype({}), Object.prototype);
1432 const proto = {};
1433 assertStrictEquals(getPrototype(Object.create(proto)), proto);
1434 });
1435
1436 it("[[Call]] gets null prototypes", () => {
1437 assertStrictEquals(getPrototype(Object.create(null)), null);
1438 });
1439
1440 it("[[Call]] gets prototypes for coercible primitives", () => {
1441 assertStrictEquals(getPrototype(1), Number.prototype);
1442 assertStrictEquals(getPrototype(Symbol()), Symbol.prototype);
1443 });
1444
1445 it("[[Call]] throws for null and undefined", () => {
1446 assertThrows(() => getPrototype(null));
1447 assertThrows(() => getPrototype(undefined));
1448 });
1449
1450 it("[[Construct]] throws an error", () => {
1451 assertThrows(() => new getPrototype({}));
1452 });
1453
1454 describe(".length", () => {
1455 it("[[Get]] returns the correct length", () => {
1456 assertStrictEquals(getPrototype.length, 1);
1457 });
1458 });
1459
1460 describe(".name", () => {
1461 it("[[Get]] returns the correct name", () => {
1462 assertStrictEquals(getPrototype.name, "getPrototype");
1463 });
1464 });
1465 });
1466
1467 describe("hasProperty", () => {
1468 it("[[Call]] gets whether a property exists on the provided object", () => {
1469 assertStrictEquals(
1470 hasProperty({ success: "etaoin" }, "success"),
1471 true,
1472 );
1473 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
1474 });
1475
1476 it("[[Call]] works for values coercible to objects", () => {
1477 assertStrictEquals(hasProperty("", "length"), true);
1478 assertStrictEquals(hasProperty("", "toString"), true);
1479 });
1480
1481 it("[[Call]] throws for null and undefined", () => {
1482 assertThrows(() => hasProperty(null, "valueOf"));
1483 assertThrows(() => hasProperty(undefined, "valueOf"));
1484 });
1485
1486 it("[[Construct]] throws an error", () => {
1487 assertThrows(() => new hasProperty({}, "valueOf"));
1488 });
1489
1490 describe(".length", () => {
1491 it("[[Get]] returns the correct length", () => {
1492 assertStrictEquals(hasProperty.length, 2);
1493 });
1494 });
1495
1496 describe(".name", () => {
1497 it("[[Get]] returns the correct name", () => {
1498 assertStrictEquals(hasProperty.name, "hasProperty");
1499 });
1500 });
1501 });
1502
1503 describe("hasOwnProperty", () => {
1504 it("[[Call]] gets whether an own property exists on the provided object", () => {
1505 assertStrictEquals(
1506 hasOwnProperty({ success: "etaoin" }, "success"),
1507 true,
1508 );
1509 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
1510 });
1511
1512 it("[[Call]] works for values coercible to objects", () => {
1513 assertStrictEquals(hasOwnProperty("", "length"), true);
1514 assertStrictEquals(hasOwnProperty("", "toString"), false);
1515 });
1516
1517 it("[[Call]] throws for null and undefined", () => {
1518 assertThrows(() => hasOwnProperty(null, "valueOf"));
1519 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
1520 });
1521
1522 it("[[Construct]] throws an error", () => {
1523 assertThrows(() => new hasOwnProperty({}, "valueOf"));
1524 });
1525
1526 describe(".length", () => {
1527 it("[[Get]] returns the correct length", () => {
1528 assertStrictEquals(hasOwnProperty.length, 2);
1529 });
1530 });
1531
1532 describe(".name", () => {
1533 it("[[Get]] returns the correct name", () => {
1534 assertStrictEquals(hasOwnProperty.name, "hasOwnProperty");
1535 });
1536 });
1537 });
1538
1539 describe("isArraylikeObject", () => {
1540 it("[[Call]] returns false for primitives", () => {
1541 assertStrictEquals(isArraylikeObject("failure"), false);
1542 });
1543
1544 it("[[Call]] returns false if length throws", () => {
1545 assertStrictEquals(
1546 isArraylikeObject({
1547 get length() {
1548 throw void {};
1549 },
1550 }),
1551 false,
1552 );
1553 });
1554
1555 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
1556 assertStrictEquals(isArraylikeObject({ length: 1n }), false);
1557 });
1558
1559 it("[[Call]] returns true if length is convertable to a number", () => {
1560 assertStrictEquals(isArraylikeObject({ length: -0 }), true);
1561 assertStrictEquals(isArraylikeObject({ length: 1 }), true);
1562 assertStrictEquals(isArraylikeObject({ length: -1.25 }), true);
1563 assertStrictEquals(
1564 isArraylikeObject({ length: 9007199254740992 }),
1565 true,
1566 );
1567 assertStrictEquals(isArraylikeObject({ length: Infinity }), true);
1568 assertStrictEquals(isArraylikeObject({ length: "success" }), true);
1569 });
1570
1571 it("[[Construct]] throws an error", () => {
1572 assertThrows(() => new isArraylikeObject({}));
1573 });
1574
1575 describe(".length", () => {
1576 it("[[Get]] returns the correct length", () => {
1577 assertStrictEquals(isArraylikeObject.length, 1);
1578 });
1579 });
1580
1581 describe(".name", () => {
1582 it("[[Get]] returns the correct name", () => {
1583 assertStrictEquals(
1584 isArraylikeObject.name,
1585 "isArraylikeObject",
1586 );
1587 });
1588 });
1589 });
1590
1591 describe("isExtensibleObject", () => {
1592 it("[[Call]] returns true for extensible objects", () => {
1593 assertStrictEquals(isExtensibleObject({}), true);
1594 });
1595
1596 it("[[Call]] returns false for coercible primitives", () => {
1597 assertStrictEquals(isExtensibleObject(1), false);
1598 assertStrictEquals(isExtensibleObject(Symbol()), false);
1599 });
1600
1601 it("[[Call]] returns false for non·extensible objects", () => {
1602 assertStrictEquals(
1603 isExtensibleObject(Object.preventExtensions({})),
1604 false,
1605 );
1606 });
1607
1608 it("[[Call]] returns false for null and undefined", () => {
1609 assertStrictEquals(isExtensibleObject(null), false);
1610 assertStrictEquals(isExtensibleObject(undefined), false);
1611 });
1612
1613 it("[[Construct]] throws an error", () => {
1614 assertThrows(() => new isExtensibleObject({}));
1615 });
1616
1617 describe(".length", () => {
1618 it("[[Get]] returns the correct length", () => {
1619 assertStrictEquals(isExtensibleObject.length, 1);
1620 });
1621 });
1622
1623 describe(".name", () => {
1624 it("[[Get]] returns the correct name", () => {
1625 assertStrictEquals(
1626 isExtensibleObject.name,
1627 "isExtensibleObject",
1628 );
1629 });
1630 });
1631 });
1632
1633 describe("isUnfrozenObject", () => {
1634 it("[[Call]] returns true for unfrozen objects", () => {
1635 assertStrictEquals(isUnfrozenObject({}), true);
1636 });
1637
1638 it("[[Call]] returns false for coercible primitives", () => {
1639 assertStrictEquals(isUnfrozenObject(1), false);
1640 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1641 });
1642
1643 it("[[Call]] returns false for frozen objects", () => {
1644 assertStrictEquals(isUnfrozenObject(Object.freeze({})), false);
1645 });
1646
1647 it("[[Call]] returns false for null and undefined", () => {
1648 assertStrictEquals(isUnfrozenObject(null), false);
1649 assertStrictEquals(isUnfrozenObject(undefined), false);
1650 });
1651
1652 it("[[Construct]] throws an error", () => {
1653 assertThrows(() => new isUnfrozenObject({}));
1654 });
1655
1656 describe(".length", () => {
1657 it("[[Get]] returns the correct length", () => {
1658 assertStrictEquals(isUnfrozenObject.length, 1);
1659 });
1660 });
1661
1662 describe(".name", () => {
1663 it("[[Get]] returns the correct name", () => {
1664 assertStrictEquals(isUnfrozenObject.name, "isUnfrozenObject");
1665 });
1666 });
1667 });
1668
1669 describe("isUnsealedObject", () => {
1670 it("[[Call]] returns true for unsealed objects", () => {
1671 assertStrictEquals(isUnsealedObject({}), true);
1672 });
1673
1674 it("[[Call]] returns false for coercible primitives", () => {
1675 assertStrictEquals(isUnsealedObject(1), false);
1676 assertStrictEquals(isUnsealedObject(Symbol()), false);
1677 });
1678
1679 it("[[Call]] returns false for sealed objects", () => {
1680 assertStrictEquals(isUnsealedObject(Object.seal({})), false);
1681 });
1682
1683 it("[[Call]] returns false for null and undefined", () => {
1684 assertStrictEquals(isUnsealedObject(null), false);
1685 assertStrictEquals(isUnsealedObject(undefined), false);
1686 });
1687
1688 it("[[Construct]] throws an error", () => {
1689 assertThrows(() => new isUnsealedObject({}));
1690 });
1691
1692 describe(".length", () => {
1693 it("[[Get]] returns the correct length", () => {
1694 assertStrictEquals(isUnsealedObject.length, 1);
1695 });
1696 });
1697
1698 describe(".name", () => {
1699 it("[[Get]] returns the correct name", () => {
1700 assertStrictEquals(isUnsealedObject.name, "isUnsealedObject");
1701 });
1702 });
1703 });
1704
1705 describe("lengthOfArraylike", () => {
1706 it("[[Call]] returns the length", () => {
1707 assertStrictEquals(
1708 lengthOfArraylike({ length: 9007199254740991 }),
1709 9007199254740991,
1710 );
1711 });
1712
1713 it("[[Call]] returns a non·nan result", () => {
1714 assertStrictEquals(lengthOfArraylike({ length: NaN }), 0);
1715 assertStrictEquals(lengthOfArraylike({ length: "failure" }), 0);
1716 });
1717
1718 it("[[Call]] returns an integral result", () => {
1719 assertStrictEquals(lengthOfArraylike({ length: 0.25 }), 0);
1720 assertStrictEquals(lengthOfArraylike({ length: 1.1 }), 1);
1721 });
1722
1723 it("[[Call]] returns a result greater than or equal to zero", () => {
1724 assertStrictEquals(lengthOfArraylike({ length: -0 }), 0);
1725 assertStrictEquals(lengthOfArraylike({ length: -1 }), 0);
1726 assertStrictEquals(lengthOfArraylike({ length: -Infinity }), 0);
1727 });
1728
1729 it("[[Call]] returns a result less than 2 ** 53", () => {
1730 assertStrictEquals(
1731 lengthOfArraylike({ length: 9007199254740992 }),
1732 9007199254740991,
1733 );
1734 assertStrictEquals(
1735 lengthOfArraylike({ length: Infinity }),
1736 9007199254740991,
1737 );
1738 });
1739
1740 it("[[Call]] does not require an object argument", () => {
1741 assertStrictEquals(lengthOfArraylike("string"), 6);
1742 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1743 });
1744
1745 it("[[Construct]] throws an error", () => {
1746 assertThrows(() => new lengthOfArraylike(""));
1747 });
1748
1749 describe(".length", () => {
1750 it("[[Get]] returns the correct length", () => {
1751 assertStrictEquals(lengthOfArraylike.length, 1);
1752 });
1753 });
1754
1755 describe(".name", () => {
1756 it("[[Get]] returns the correct name", () => {
1757 assertStrictEquals(lengthOfArraylike.name, "lengthOfArraylike");
1758 });
1759 });
1760 });
1761
1762 describe("namedEntries", () => {
1763 it("[[Call]] gets named entries", () => {
1764 assertEquals(namedEntries({ success: true }), [["success", true]]);
1765 });
1766
1767 it("[[Call]] works for values coercible to objects", () => {
1768 assertEquals(namedEntries("foo"), [
1769 ["0", "f"],
1770 ["1", "o"],
1771 ["2", "o"],
1772 ]);
1773 });
1774
1775 it("[[Call]] throws for null and undefined", () => {
1776 assertThrows(() => namedEntries(null));
1777 assertThrows(() => namedEntries(undefined));
1778 });
1779
1780 it("[[Construct]] throws an error", () => {
1781 assertThrows(() => new namedEntries({}));
1782 });
1783
1784 describe(".length", () => {
1785 it("[[Get]] returns the correct length", () => {
1786 assertStrictEquals(namedEntries.length, 1);
1787 });
1788 });
1789
1790 describe(".name", () => {
1791 it("[[Get]] returns the correct name", () => {
1792 assertStrictEquals(namedEntries.name, "namedEntries");
1793 });
1794 });
1795 });
1796
1797 describe("namedKeys", () => {
1798 it("[[Call]] gets named keys", () => {
1799 assertEquals(namedKeys({ success: true }), ["success"]);
1800 });
1801
1802 it("[[Call]] works for values coercible to objects", () => {
1803 assertEquals(namedKeys("foo"), [
1804 "0",
1805 "1",
1806 "2",
1807 ]);
1808 });
1809
1810 it("[[Call]] throws for null and undefined", () => {
1811 assertThrows(() => namedKeys(null));
1812 assertThrows(() => namedKeys(undefined));
1813 });
1814
1815 it("[[Construct]] throws an error", () => {
1816 assertThrows(() => new namedKeys({}));
1817 });
1818
1819 describe(".length", () => {
1820 it("[[Get]] returns the correct length", () => {
1821 assertStrictEquals(namedKeys.length, 1);
1822 });
1823 });
1824
1825 describe(".name", () => {
1826 it("[[Get]] returns the correct name", () => {
1827 assertStrictEquals(namedKeys.name, "namedKeys");
1828 });
1829 });
1830 });
1831
1832 describe("namedValues", () => {
1833 it("[[Call]] gets named values", () => {
1834 assertEquals(namedValues({ success: true }), [true]);
1835 });
1836
1837 it("[[Call]] works for values coercible to objects", () => {
1838 assertEquals(namedValues("foo"), [
1839 "f",
1840 "o",
1841 "o",
1842 ]);
1843 });
1844
1845 it("[[Call]] throws for null and undefined", () => {
1846 assertThrows(() => namedValues(null));
1847 assertThrows(() => namedValues(undefined));
1848 });
1849
1850 it("[[Construct]] throws an error", () => {
1851 assertThrows(() => new namedValues({}));
1852 });
1853
1854 describe(".length", () => {
1855 it("[[Get]] returns the correct length", () => {
1856 assertStrictEquals(namedValues.length, 1);
1857 });
1858 });
1859
1860 describe(".name", () => {
1861 it("[[Get]] returns the correct name", () => {
1862 assertStrictEquals(namedValues.name, "namedValues");
1863 });
1864 });
1865 });
1866
1867 describe("objectCreate", () => {
1868 it("[[Call]] creates an object", () => {
1869 const obj = objectCreate(null);
1870 assertStrictEquals(Object(obj), obj);
1871 });
1872
1873 it("[[Call]] correctly sets the prototype", () => {
1874 const proto = {};
1875 assertStrictEquals(
1876 Object.getPrototypeOf(objectCreate(proto)),
1877 proto,
1878 );
1879 assertStrictEquals(
1880 Object.getPrototypeOf(objectCreate(null)),
1881 null,
1882 );
1883 });
1884
1885 it("[[Call]] correctly sets own properties", () => {
1886 assertEquals(
1887 Object.getOwnPropertyDescriptors(
1888 objectCreate(null, { success: { value: true } }),
1889 ),
1890 {
1891 success: {
1892 configurable: false,
1893 enumerable: false,
1894 value: true,
1895 writable: false,
1896 },
1897 },
1898 );
1899 });
1900
1901 it("[[Call]] throws for coercible primitives", () => {
1902 assertThrows(() => objectCreate(1));
1903 assertThrows(() => objectCreate(Symbol()));
1904 });
1905
1906 it("[[Call]] throws for undefined", () => {
1907 assertThrows(() => objectCreate(undefined));
1908 });
1909
1910 it("[[Construct]] throws an error", () => {
1911 assertThrows(() => new objectCreate({}));
1912 });
1913
1914 describe(".length", () => {
1915 it("[[Get]] returns the correct length", () => {
1916 assertStrictEquals(objectCreate.length, 2);
1917 });
1918 });
1919
1920 describe(".name", () => {
1921 it("[[Get]] returns the correct name", () => {
1922 assertStrictEquals(objectCreate.name, "objectCreate");
1923 });
1924 });
1925 });
1926
1927 describe("objectFromEntries", () => {
1928 it("[[Call]] creates an object", () => {
1929 const obj = objectFromEntries([]);
1930 assertStrictEquals(Object(obj), obj);
1931 });
1932
1933 it("[[Call]] correctly sets the prototype", () => {
1934 assertStrictEquals(
1935 Object.getPrototypeOf(objectFromEntries([])),
1936 Object.prototype,
1937 );
1938 });
1939
1940 it("[[Call]] correctly sets own properties", () => {
1941 assertEquals(
1942 Object.entries(objectFromEntries([["success", true]])),
1943 [["success", true]],
1944 );
1945 });
1946
1947 it("[[Call]] throws if the argument is not a nested arraylike", () => {
1948 assertThrows(() => objectFromEntries(1));
1949 assertThrows(() => objectFromEntries(Symbol()));
1950 assertThrows(() => objectFromEntries(null));
1951 assertThrows(() => objectFromEntries(undefined));
1952 assertThrows(() => objectFromEntries({}));
1953 assertThrows(() => objectFromEntries([undefined]));
1954 });
1955
1956 it("[[Construct]] throws an error", () => {
1957 assertThrows(() => new objectFromEntries([]));
1958 });
1959
1960 describe(".length", () => {
1961 it("[[Get]] returns the correct length", () => {
1962 assertStrictEquals(objectFromEntries.length, 1);
1963 });
1964 });
1965
1966 describe(".name", () => {
1967 it("[[Get]] returns the correct name", () => {
1968 assertStrictEquals(objectFromEntries.name, "objectFromEntries");
1969 });
1970 });
1971 });
1972
1973 describe("preventExtensions", () => {
1974 it("[[Call]] prevents extensions on the object", () => {
1975 const obj = {};
1976 preventExtensions(obj);
1977 assert(!Object.isExtensible(obj));
1978 });
1979
1980 it("[[Call]] returns the provided object", () => {
1981 const obj = {};
1982 assertStrictEquals(preventExtensions(obj), obj);
1983 });
1984
1985 it("[[Construct]] throws an error", () => {
1986 assertThrows(() => new preventExtensions({}));
1987 });
1988
1989 describe(".length", () => {
1990 it("[[Get]] returns the correct length", () => {
1991 assertStrictEquals(preventExtensions.length, 1);
1992 });
1993 });
1994
1995 describe(".name", () => {
1996 it("[[Get]] returns the correct name", () => {
1997 assertStrictEquals(preventExtensions.name, "preventExtensions");
1998 });
1999 });
2000 });
2001
2002 describe("seal", () => {
2003 it("[[Call]] seals the object", () => {
2004 const obj = {};
2005 seal(obj);
2006 assert(Object.isSealed(obj));
2007 });
2008
2009 it("[[Call]] returns the provided object", () => {
2010 const obj = {};
2011 assertStrictEquals(seal(obj), obj);
2012 });
2013
2014 it("[[Construct]] throws an error", () => {
2015 assertThrows(() => new seal({}));
2016 });
2017
2018 describe(".length", () => {
2019 it("[[Get]] returns the correct length", () => {
2020 assertStrictEquals(seal.length, 1);
2021 });
2022 });
2023
2024 describe(".name", () => {
2025 it("[[Get]] returns the correct name", () => {
2026 assertStrictEquals(seal.name, "seal");
2027 });
2028 });
2029 });
2030
2031 describe("setPropertyValue", () => {
2032 it("[[Call]] sets the provided property on the provided object", () => {
2033 const obj = {};
2034 setPropertyValue(obj, "success", true);
2035 assertStrictEquals(obj.success, true);
2036 });
2037
2038 it("[[Call]] calls setters", () => {
2039 const setter = spy((_) => {});
2040 const obj = Object.create(null, { success: { set: setter } });
2041 setPropertyValue(obj, "success", true);
2042 assertSpyCalls(setter, 1);
2043 assertSpyCall(setter, 0, {
2044 args: [true],
2045 self: obj,
2046 });
2047 });
2048
2049 it("[[Call]] walks the prototype chain", () => {
2050 const setter = spy((_) => {});
2051 const obj = Object.create(
2052 Object.create(null, { success: { set: setter } }),
2053 );
2054 setPropertyValue(obj, "success", true);
2055 assertSpyCalls(setter, 1);
2056 assertSpyCall(setter, 0, {
2057 args: [true],
2058 self: obj,
2059 });
2060 });
2061
2062 it("[[Call]] uses the provided receiver", () => {
2063 const setter = spy((_) => {});
2064 const obj = Object.create(null, { success: { set: setter } });
2065 const receiver = {};
2066 setPropertyValue(obj, "success", true, receiver);
2067 assertSpyCalls(setter, 1);
2068 assertSpyCall(setter, 0, {
2069 args: [true],
2070 self: receiver,
2071 });
2072 });
2073
2074 it("[[Call]] throws if the property can’t be set", () => {
2075 const obj = Object.freeze({ failure: undefined });
2076 assertThrows(() => setPropertyValue(obj, "failure", true));
2077 });
2078
2079 it("[[Call]] returns the provided object", () => {
2080 const obj = {};
2081 assertStrictEquals(setPropertyValue(obj, "", undefined), obj);
2082 });
2083
2084 it("[[Construct]] throws an error", () => {
2085 assertThrows(() => new setPropertyValue({}, "", undefined));
2086 });
2087
2088 describe(".length", () => {
2089 it("[[Get]] returns the correct length", () => {
2090 assertStrictEquals(setPropertyValue.length, 3);
2091 });
2092 });
2093
2094 describe(".name", () => {
2095 it("[[Get]] returns the correct name", () => {
2096 assertStrictEquals(setPropertyValue.name, "setPropertyValue");
2097 });
2098 });
2099 });
2100
2101 describe("setPropertyValues", () => {
2102 it("[[Call]] sets the provided properties on the provided object", () => {
2103 const obj = {};
2104 setPropertyValues(obj, { success: true, all: "good" });
2105 assertStrictEquals(obj.success, true);
2106 assertStrictEquals(obj.all, "good");
2107 });
2108
2109 it("[[Call]] can take multiple objects", () => {
2110 const obj = {};
2111 setPropertyValues(
2112 obj,
2113 { success: false, all: "good" },
2114 { success: true },
2115 );
2116 assertStrictEquals(obj.success, true);
2117 assertStrictEquals(obj.all, "good");
2118 });
2119
2120 it("[[Call]] ignores nullish arguments", () => {
2121 const obj = {};
2122 setPropertyValues(obj, null, undefined, { success: true });
2123 assertStrictEquals(obj.success, true);
2124 });
2125
2126 it("[[Call]] calls setters", () => {
2127 const setter = spy((_) => {});
2128 const obj = Object.create(null, { success: { set: setter } });
2129 setPropertyValues(obj, { success: true });
2130 assertSpyCalls(setter, 1);
2131 assertSpyCall(setter, 0, {
2132 args: [true],
2133 self: obj,
2134 });
2135 });
2136
2137 it("[[Call]] calls setters multiple times if property appears more than once", () => {
2138 const setter = spy((_) => {});
2139 const obj = Object.create(null, { success: { set: setter } });
2140 setPropertyValues(obj, { success: false }, { success: true });
2141 assertSpyCalls(setter, 2);
2142 assertSpyCall(setter, 0, {
2143 args: [false],
2144 self: obj,
2145 });
2146 assertSpyCall(setter, 1, {
2147 args: [true],
2148 self: obj,
2149 });
2150 });
2151
2152 it("[[Call]] walks the prototype chain", () => {
2153 const setter = spy((_) => {});
2154 const obj = Object.create(
2155 Object.create(null, { success: { set: setter } }),
2156 );
2157 setPropertyValues(obj, { success: true });
2158 assertSpyCalls(setter, 1);
2159 assertSpyCall(setter, 0, {
2160 args: [true],
2161 self: obj,
2162 });
2163 });
2164
2165 it("[[Call]] throws if the property can’t be set", () => {
2166 const obj = Object.freeze({ failure: undefined });
2167 assertThrows(() => setPropertyValues(obj, { failure: true }));
2168 });
2169
2170 it("[[Call]] returns the provided object", () => {
2171 const obj = {};
2172 assertStrictEquals(setPropertyValues(obj, { "": undefined }), obj);
2173 });
2174
2175 it("[[Construct]] throws an error", () => {
2176 assertThrows(() => new setPropertyValues(obj, { "": undefined }));
2177 });
2178
2179 describe(".length", () => {
2180 it("[[Get]] returns the correct length", () => {
2181 assertStrictEquals(setPropertyValues.length, 2);
2182 });
2183 });
2184
2185 describe(".name", () => {
2186 it("[[Get]] returns the correct name", () => {
2187 assertStrictEquals(setPropertyValues.name, "setPropertyValues");
2188 });
2189 });
2190 });
2191
2192 describe("setPrototype", () => {
2193 it("[[Call]] sets object prototypes", () => {
2194 const obj = {};
2195 const proto = {};
2196 setPrototype(obj, proto);
2197 assertStrictEquals(Object.getPrototypeOf(obj), proto);
2198 });
2199
2200 it("[[Call]] sets null prototypes", () => {
2201 const obj = {};
2202 setPrototype(obj, null);
2203 assertStrictEquals(Object.getPrototypeOf(obj), null);
2204 });
2205
2206 it("[[Call]] can set coercible primitives to their same prototype", () => {
2207 setPrototype(1, Number.prototype);
2208 setPrototype(Symbol(), Symbol.prototype);
2209 });
2210
2211 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
2212 assertThrows(() => setPrototype(1, Object.prototype));
2213 assertThrows(() => setPrototype(Symbol(), Object.prototype));
2214 });
2215
2216 it("[[Call]] throws for null and undefined", () => {
2217 assertThrows(() => setPrototype(null, Object.prototype));
2218 assertThrows(() => setPrototype(undefined, Object.prototype));
2219 });
2220
2221 it("[[Call]] returns the provided value", () => {
2222 const obj = {};
2223 assertStrictEquals(setPrototype(obj, null), obj);
2224 assertStrictEquals(setPrototype(1, Number.prototype), 1);
2225 });
2226
2227 it("[[Construct]] throws an error", () => {
2228 assertThrows(() => new setPrototype({}, null));
2229 });
2230
2231 describe(".length", () => {
2232 it("[[Get]] returns the correct length", () => {
2233 assertStrictEquals(setPrototype.length, 2);
2234 });
2235 });
2236
2237 describe(".name", () => {
2238 it("[[Get]] returns the correct name", () => {
2239 assertStrictEquals(setPrototype.name, "setPrototype");
2240 });
2241 });
2242 });
2243
2244 describe("toObject", () => {
2245 it("returns the input for objects", () => {
2246 const obj = {};
2247 assertStrictEquals(toObject(obj), obj);
2248 });
2249
2250 it("throws for nullish values", () => {
2251 assertThrows(() => toObject(null));
2252 assertThrows(() => toObject(void {}));
2253 });
2254
2255 it("returns a wrapper object for other primitives", () => {
2256 const sym = Symbol();
2257 assertStrictEquals(typeof toObject(sym), "object");
2258 assertStrictEquals(toObject(sym).valueOf(), sym);
2259 });
2260
2261 it("[[Construct]] throws an error", () => {
2262 assertThrows(() => new toObject({}));
2263 });
2264
2265 describe(".length", () => {
2266 it("[[Get]] returns the correct length", () => {
2267 assertStrictEquals(toObject.length, 1);
2268 });
2269 });
2270
2271 describe(".name", () => {
2272 it("[[Get]] returns the correct name", () => {
2273 assertStrictEquals(toObject.name, "toObject");
2274 });
2275 });
2276 });
2277
2278 describe("toPropertyKey", () => {
2279 it("returns a string or symbol", () => {
2280 const sym = Symbol();
2281 assertStrictEquals(toPropertyKey(sym), sym);
2282 assertStrictEquals(
2283 toPropertyKey(new String("success")),
2284 "success",
2285 );
2286 });
2287
2288 it("favours the `toString` representation", () => {
2289 assertStrictEquals(
2290 toPropertyKey({
2291 toString() {
2292 return "success";
2293 },
2294 valueOf() {
2295 return "failure";
2296 },
2297 }),
2298 "success",
2299 );
2300 });
2301
2302 it("[[Construct]] throws an error", () => {
2303 assertThrows(() => new toPropertyKey(""));
2304 });
2305
2306 describe(".length", () => {
2307 it("[[Get]] returns the correct length", () => {
2308 assertStrictEquals(toPropertyKey.length, 1);
2309 });
2310 });
2311
2312 describe(".name", () => {
2313 it("[[Get]] returns the correct name", () => {
2314 assertStrictEquals(toPropertyKey.name, "toPropertyKey");
2315 });
2316 });
2317 });
This page took 0.4051 seconds and 5 git commands to generate.