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