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