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