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