1 // ♓🌟 Piscēs ∷ object.test.js
2 // ====================================================================
4 // Copyright © 2022–2023 Lady [@ Lady’s Computer].
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/>.
20 } from "./dev-deps.js";
28 getOwnPropertyDescriptor
,
29 getOwnPropertyDescriptors
,
31 getOwnPropertyStrings
,
32 getOwnPropertySymbols
,
38 isConcatSpreadableObject
,
58 describe("LazyLoader", () => {
59 const symbol
= Symbol("foo");
61 const etaoinMethod
= spy(() => "success");
62 const shrdluMethod
= spy(() => "success");
63 const cmfwypMethod
= spy(() => "success");
64 const vbgkqjMethod
= spy(() => "success");
65 const methodsObject
= Object
.create(
95 xz
fiflffffi: { configurable
: true, enumerable
: false, set(_
) {} },
105 it("[[Call]] throws an error", () => {
106 assertThrows(() => LazyLoader({}));
109 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
111 Object
.getPrototypeOf(new LazyLoader(methodsObject
)),
116 it("[[Construct]] creates a new object with the desired properties", () => {
118 Reflect
.ownKeys(new LazyLoader(methodsObject
)),
119 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol
],
123 it("[[Construct]] creates a new object with configurable properties", () => {
127 for (const key
of Reflect
.ownKeys(ll
)) {
130 Object
.getOwnPropertyDescriptor(ll
, key
).configurable
,
133 }(new LazyLoader(methodsObject
)),
146 it("[[Construct]] creates a new object with the correct enumerability", () => {
150 for (const key
of Reflect
.ownKeys(ll
)) {
153 Object
.getOwnPropertyDescriptor(ll
, key
).enumerable
,
156 }(new LazyLoader(methodsObject
)),
169 it("[[Construct]] creates a new object with defined getters", () => {
173 for (const key
of Reflect
.ownKeys(ll
)) {
176 Object
.getOwnPropertyDescriptor(ll
, key
).get?.name
,
179 }(new LazyLoader(methodsObject
)),
182 etaoin
: "get etaoin",
183 shrdlu
: "get shrdlu",
184 cmfwyp
: "get cmfwyp",
185 vbgkqj
: "get vbgkqj",
186 xz
fiflffffi: "get xzfiflffffi",
187 [symbol
]: `get [${symbol.description}]`,
192 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
196 for (const key
of Reflect
.ownKeys(ll
)) {
199 Object
.getOwnPropertyDescriptor(ll
, key
).set?.name
,
202 }(new LazyLoader(methodsObject
)),
210 [symbol
]: `set [${symbol.description}]`,
215 it("[[Construct]] creates a new object with correct getter behaviour", () => {
216 const ll
= new LazyLoader(methodsObject
);
219 Object
.getOwnPropertyDescriptor(ll
, "etaoin"),
227 assertSpyCalls(etaoinMethod
, 1);
228 assertSpyCall(etaoinMethod
, 0, {
235 Object
.getOwnPropertyDescriptor(ll
, "shrdlu"),
243 assertSpyCalls(shrdluMethod
, 1);
244 assertSpyCall(shrdluMethod
, 0, {
251 Object
.getOwnPropertyDescriptor(ll
, "cmfwyp"),
259 assertSpyCalls(cmfwypMethod
, 1);
260 assertSpyCall(cmfwypMethod
, 0, {
267 Object
.getOwnPropertyDescriptor(ll
, "vbgkqj"),
275 assertSpyCalls(vbgkqjMethod
, 1);
276 assertSpyCall(vbgkqjMethod
, 0, {
281 assertThrows(() => ll
.xz
fiflffffi);
282 assertThrows(() => ll
[symbol
]);
285 it("[[Construct]] creates a new object with correct setter behaviour", () => {
286 const ll
= new LazyLoader(methodsObject
);
287 ll
[symbol
] = "success";
289 Object
.getOwnPropertyDescriptor(ll
, symbol
),
299 describe(".length", () => {
300 it("[[Get]] returns the correct length", () => {
301 assertStrictEquals(LazyLoader
.length
, 1);
305 describe(".name", () => {
306 it("[[Get]] returns the correct name", () => {
307 assertStrictEquals(LazyLoader
.name
, "LazyLoader");
312 describe("defineOwnProperty", () => {
313 it("[[Call]] defines the property", () => {
315 defineOwnProperty(obj
, "etaoin", {});
316 assert("etaoin" in obj
);
319 it("[[Call]] returns the provided object", () => {
321 assertStrictEquals(defineOwnProperty(obj
, "etaoin", {}), obj
);
324 it("[[Construct]] throws an error", () => {
325 assertThrows(() => new defineOwnProperty(obj
, "etaoin", {}));
328 describe(".length", () => {
329 it("[[Get]] returns the correct length", () => {
330 assertStrictEquals(defineOwnProperty
.length
, 3);
334 describe(".name", () => {
335 it("[[Get]] returns the correct name", () => {
337 defineOwnProperty
.name
,
344 describe("defineOwnProperties", () => {
345 it("[[Call]] defines properties from the provided objects", () => {
347 defineOwnProperties(obj
, {
351 assert("etaoin" in obj
);
352 assert("shrdlu" in obj
);
353 assert("cmfwyp" in obj
);
356 it("[[Call]] overrides earlier declarations with later ones", () => {
357 const obj
= { etaoin
: undefined };
358 defineOwnProperties(obj
, {
359 etaoin
: { value
: "failure" },
361 etaoin
: { value
: "success" },
363 assertStrictEquals(obj
.etaoin
, "success");
366 it("[[Call]] returns the provided object", () => {
368 assertStrictEquals(defineOwnProperties(obj
), obj
);
371 it("[[Construct]] throws an error", () => {
372 assertThrows(() => new defineOwnProperties({}));
375 describe(".length", () => {
376 it("[[Get]] returns the correct length", () => {
377 assertStrictEquals(defineOwnProperties
.length
, 1);
381 describe(".name", () => {
382 it("[[Get]] returns the correct name", () => {
384 defineOwnProperties
.name
,
385 "defineOwnProperties",
391 describe("deleteOwnProperty", () => {
392 it("[[Call]] deletes the provided property on the provided object", () => {
393 const obj
= { failure
: undefined };
394 deleteOwnProperty(obj
, "failure");
395 assert(!("failure" in obj
));
398 it("[[Call]] does nothing if the property doesn’t exist", () => {
399 const obj
= Object
.freeze({});
400 deleteOwnProperty(obj
, "failure");
401 assert(!("failure" in obj
));
404 it("[[Call]] throws if the property can’t be deleted", () => {
405 const obj
= Object
.seal({ failure
: undefined });
406 assertThrows(() => deleteOwnProperty(obj
, "failure"));
409 it("[[Call]] returns the provided object", () => {
411 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
414 it("[[Construct]] throws an error", () => {
415 assertThrows(() => new deleteOwnProperty({}, ""));
418 describe(".length", () => {
419 it("[[Get]] returns the correct length", () => {
420 assertStrictEquals(deleteOwnProperty
.length
, 2);
424 describe(".name", () => {
425 it("[[Get]] returns the correct name", () => {
426 assertStrictEquals(deleteOwnProperty
.name
, "deleteOwnProperty");
431 describe("freeze", () => {
432 it("[[Call]] freezes the object", () => {
435 assert(Object
.isFrozen(obj
));
438 it("[[Call]] returns the provided object", () => {
440 assertStrictEquals(freeze(obj
), obj
);
443 it("[[Construct]] throws an error", () => {
444 assertThrows(() => new freeze({}));
447 describe(".length", () => {
448 it("[[Get]] returns the correct length", () => {
449 assertStrictEquals(freeze
.length
, 1);
453 describe(".name", () => {
454 it("[[Get]] returns the correct name", () => {
455 assertStrictEquals(freeze
.name
, "freeze");
460 describe("frozenCopy", () => {
461 it("[[Call]] returns a frozen object", () => {
464 frozenCopy(Object
.create(null), {
481 it("[[Call]] ignores non·enumerable properties", () => {
484 Object
.create(null, {
485 data
: { value
: undefined },
486 accessor
: { get: undefined },
493 it("[[Call]] preserves accessor properties", () => {
521 Object
.getOwnPropertyDescriptors(
522 frozenCopy(Object
.create(null, properties
)),
528 it("[[Call]] does not copy properties on the prototype", () => {
531 frozenCopy(Object
.create({ failure
: undefined }), {
537 accessor
: { configurable
: true, get: undefined },
542 it("[[Call]] uses the species of the constructor", () => {
543 const species
= { prototype: {} };
545 Object
.getPrototypeOf(
546 frozenCopy({}, { [Symbol
.species
]: species
}),
552 it("[[Call]] uses constructor if no species is defined", () => {
553 const constructor = { [Symbol
.species
]: null, prototype: {} };
555 Object
.getPrototypeOf(frozenCopy({}, constructor)),
556 constructor.prototype,
560 it("[[Call]] uses the constructor on the object if none is provided", () => {
561 const constructor = { [Symbol
.species
]: null, prototype: {} };
563 Object
.getPrototypeOf(frozenCopy({ constructor })),
564 constructor.prototype,
568 it("[[Call]] allows a null constructor", () => {
570 Object
.getPrototypeOf(frozenCopy({}, null)),
575 it("[[Construct]] throws an error", () => {
576 assertThrows(() => new frozenCopy({}));
579 describe(".length", () => {
580 it("[[Get]] returns the correct length", () => {
581 assertStrictEquals(frozenCopy
.length
, 1);
585 describe(".name", () => {
586 it("[[Get]] returns the correct name", () => {
587 assertStrictEquals(frozenCopy
.name
, "frozenCopy");
592 describe("getMethod", () => {
593 it("[[Call]] gets a method", () => {
594 const method
= () => {};
595 assertStrictEquals(getMethod({ method
}, "method"), method
);
598 it("[[Call]] works for values coercible to objects", () => {
599 assertEquals(getMethod("", "toString"), String
.prototype.toString
);
602 it("[[Call]] throws for null and undefined", () => {
603 assertThrows(() => getMethod(null, "valueOf"));
604 assertThrows(() => getMethod(undefined, "valueOf"));
607 it("[[Call]] throws if the resulting value isn’t callable", () => {
608 assertThrows(() => getMethod({ "failure": true }, "failure"));
611 it("[[Construct]] throws an error", () => {
612 assertThrows(() => new getMethod({ method() {} }, "method"));
615 describe(".length", () => {
616 it("[[Get]] returns the correct length", () => {
617 assertStrictEquals(getMethod
.length
, 2);
621 describe(".name", () => {
622 it("[[Get]] returns the correct name", () => {
623 assertStrictEquals(getMethod
.name
, "getMethod");
628 describe("getOwnPropertyDescriptor", () => {
629 it("[[Call]] gets the descriptor", () => {
631 getOwnPropertyDescriptor({ success
: true }, "success"),
641 it("[[Call]] returns undefined for non‐own properties", () => {
643 getOwnPropertyDescriptor({}, "valueOf"),
648 it("[[Construct]] throws an error", () => {
649 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
652 describe(".length", () => {
653 it("[[Get]] returns the correct length", () => {
654 assertStrictEquals(getOwnPropertyDescriptor
.length
, 2);
658 describe(".name", () => {
659 it("[[Get]] returns the correct name", () => {
661 getOwnPropertyDescriptor
.name
,
662 "getOwnPropertyDescriptor",
668 describe("getOwnPropertyDescriptors", () => {
669 it("[[Call]] gets the descriptors", () => {
671 getOwnPropertyDescriptors({ success
: true, etaoin
: "shrdlu" }),
689 it("[[Construct]] throws an error", () => {
690 assertThrows(() => new getOwnPropertyDescriptors({}));
693 describe(".length", () => {
694 it("[[Get]] returns the correct length", () => {
695 assertStrictEquals(getOwnPropertyDescriptors
.length
, 1);
699 describe(".name", () => {
700 it("[[Get]] returns the correct name", () => {
702 getOwnPropertyDescriptors
.name
,
703 "getOwnPropertyDescriptors",
709 describe("getOwnPropertyKeys", () => {
710 it("[[Call]] gets own (but not inherited) property keys", () => {
711 assertEquals(getOwnPropertyKeys({ success
: true }), ["success"]);
714 it("[[Call]] works for values coercible to objects", () => {
715 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
718 it("[[Call]] throws for null and undefined", () => {
719 assertThrows(() => getOwnPropertyKeys(null));
720 assertThrows(() => getOwnPropertyKeys(undefined));
723 it("[[Construct]] throws an error", () => {
724 assertThrows(() => new getOwnPropertyKeys({}));
727 describe(".length", () => {
728 it("[[Get]] returns the correct length", () => {
729 assertStrictEquals(getOwnPropertyKeys
.length
, 1);
733 describe(".name", () => {
734 it("[[Get]] returns the correct name", () => {
736 getOwnPropertyKeys
.name
,
737 "getOwnPropertyKeys",
743 describe("getOwnPropertyStrings", () => {
744 it("[[Call]] gets own string keys", () => {
745 assertEquals(getOwnPropertyStrings({ success
: true }), [
750 it("[[Call]] works for values coercible to objects", () => {
751 assertEquals(getOwnPropertyStrings("foo"), [
759 it("[[Call]] throws for null and undefined", () => {
760 assertThrows(() => getOwnPropertyStrings(null));
761 assertThrows(() => getOwnPropertyStrings(undefined));
764 it("[[Construct]] throws an error", () => {
765 assertThrows(() => new getOwnPropertyStrings({}));
768 describe(".length", () => {
769 it("[[Get]] returns the correct length", () => {
770 assertStrictEquals(getOwnPropertyStrings
.length
, 1);
774 describe(".name", () => {
775 it("[[Get]] returns the correct name", () => {
777 getOwnPropertyStrings
.name
,
778 "getOwnPropertyStrings",
784 describe("getOwnPropertySymbols", () => {
785 it("[[Call]] gets own symbol keys", () => {
786 const sym
= Symbol();
787 assertEquals(getOwnPropertySymbols({ [sym
]: true }), [sym
]);
790 it("[[Call]] works for values coercible to objects", () => {
791 assertEquals(getOwnPropertySymbols("foo"), []);
794 it("[[Call]] throws for null and undefined", () => {
795 assertThrows(() => getOwnPropertySymbols(null));
796 assertThrows(() => getOwnPropertySymbols(undefined));
799 it("[[Construct]] throws an error", () => {
800 assertThrows(() => new getOwnPropertySymbols({}));
803 describe(".length", () => {
804 it("[[Get]] returns the correct length", () => {
805 assertStrictEquals(getOwnPropertySymbols
.length
, 1);
809 describe(".name", () => {
810 it("[[Get]] returns the correct name", () => {
812 getOwnPropertySymbols
.name
,
813 "getOwnPropertySymbols",
819 describe("getPropertyValue", () => {
820 it("[[Call]] gets property values on the provided object", () => {
822 getPropertyValue({ success
: true }, "success"),
827 it("[[Call]] works for values coercible to objects", () => {
829 getPropertyValue("", "toString"),
830 String
.prototype.toString
,
834 it("[[Call]] throws for null and undefined", () => {
835 assertThrows(() => getPropertyValue(null, "valueOf"));
836 assertThrows(() => getPropertyValue(undefined, "valueOf"));
839 it("[[Construct]] throws an error", () => {
840 assertThrows(() => new getPropertyValue({}, "valueOf"));
843 describe(".length", () => {
844 it("[[Get]] returns the correct length", () => {
845 assertStrictEquals(getPropertyValue
.length
, 2);
849 describe(".name", () => {
850 it("[[Get]] returns the correct name", () => {
851 assertStrictEquals(getPropertyValue
.name
, "getPropertyValue");
856 describe("getPrototype", () => {
857 it("[[Call]] gets object prototypes", () => {
858 assertStrictEquals(getPrototype({}), Object
.prototype);
860 assertStrictEquals(getPrototype(Object
.create(proto
)), proto
);
863 it("[[Call]] gets null prototypes", () => {
864 assertStrictEquals(getPrototype(Object
.create(null)), null);
867 it("[[Call]] gets prototypes for coercible primitives", () => {
868 assertStrictEquals(getPrototype(1), Number
.prototype);
869 assertStrictEquals(getPrototype(Symbol()), Symbol
.prototype);
872 it("[[Call]] throws for null and undefined", () => {
873 assertThrows(() => getPrototype(null));
874 assertThrows(() => getPrototype(undefined));
877 it("[[Construct]] throws an error", () => {
878 assertThrows(() => new getPrototype({}));
881 describe(".length", () => {
882 it("[[Get]] returns the correct length", () => {
883 assertStrictEquals(getPrototype
.length
, 1);
887 describe(".name", () => {
888 it("[[Get]] returns the correct name", () => {
889 assertStrictEquals(getPrototype
.name
, "getPrototype");
894 describe("hasProperty", () => {
895 it("[[Call]] gets whether a property exists on the provided object", () => {
897 hasProperty({ success
: "etaoin" }, "success"),
900 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
903 it("[[Call]] works for values coercible to objects", () => {
904 assertStrictEquals(hasProperty("", "length"), true);
905 assertStrictEquals(hasProperty("", "toString"), true);
908 it("[[Call]] throws for null and undefined", () => {
909 assertThrows(() => hasProperty(null, "valueOf"));
910 assertThrows(() => hasProperty(undefined, "valueOf"));
913 it("[[Construct]] throws an error", () => {
914 assertThrows(() => new hasProperty({}, "valueOf"));
917 describe(".length", () => {
918 it("[[Get]] returns the correct length", () => {
919 assertStrictEquals(hasProperty
.length
, 2);
923 describe(".name", () => {
924 it("[[Get]] returns the correct name", () => {
925 assertStrictEquals(hasProperty
.name
, "hasProperty");
930 describe("hasOwnProperty", () => {
931 it("[[Call]] gets whether an own property exists on the provided object", () => {
933 hasOwnProperty({ success
: "etaoin" }, "success"),
936 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
939 it("[[Call]] works for values coercible to objects", () => {
940 assertStrictEquals(hasOwnProperty("", "length"), true);
941 assertStrictEquals(hasOwnProperty("", "toString"), false);
944 it("[[Call]] throws for null and undefined", () => {
945 assertThrows(() => hasOwnProperty(null, "valueOf"));
946 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
949 it("[[Construct]] throws an error", () => {
950 assertThrows(() => new hasOwnProperty({}, "valueOf"));
953 describe(".length", () => {
954 it("[[Get]] returns the correct length", () => {
955 assertStrictEquals(hasOwnProperty
.length
, 2);
959 describe(".name", () => {
960 it("[[Get]] returns the correct name", () => {
961 assertStrictEquals(hasOwnProperty
.name
, "hasOwnProperty");
966 describe("isArraylikeObject", () => {
967 it("[[Call]] returns false for primitives", () => {
968 assertStrictEquals(isArraylikeObject("failure"), false);
971 it("[[Call]] returns false if length throws", () => {
982 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
983 assertStrictEquals(isArraylikeObject({ length
: 1n
}), false);
986 it("[[Call]] returns true if length is convertable to a number", () => {
987 assertStrictEquals(isArraylikeObject({ length
: -0 }), true);
988 assertStrictEquals(isArraylikeObject({ length
: 1 }), true);
989 assertStrictEquals(isArraylikeObject({ length
: -1.25 }), true);
991 isArraylikeObject({ length
: 9007199254740992 }),
994 assertStrictEquals(isArraylikeObject({ length
: Infinity
}), true);
995 assertStrictEquals(isArraylikeObject({ length
: "success" }), true);
998 it("[[Construct]] throws an error", () => {
999 assertThrows(() => new isArraylikeObject({}));
1002 describe(".length", () => {
1003 it("[[Get]] returns the correct length", () => {
1004 assertStrictEquals(isArraylikeObject
.length
, 1);
1008 describe(".name", () => {
1009 it("[[Get]] returns the correct name", () => {
1011 isArraylikeObject
.name
,
1012 "isArraylikeObject",
1018 describe("isConcatSpreadableObject", () => {
1019 it("[[Call]] returns false for primitives", () => {
1020 assertStrictEquals(isConcatSpreadableObject("failure"), false);
1023 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
1025 isConcatSpreadableObject(
1026 Object
.assign([], { [Symbol
.isConcatSpreadable
]: null }),
1031 isConcatSpreadableObject(
1032 Object
.assign([], { [Symbol
.isConcatSpreadable
]: false }),
1038 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
1040 isConcatSpreadableObject(
1041 Object
.assign([], { [Symbol
.isConcatSpreadable
]: undefined }),
1047 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
1049 isConcatSpreadableObject({ [Symbol
.isConcatSpreadable
]: true }),
1054 it("[[Construct]] throws an error", () => {
1055 assertThrows(() => new isConcatSpreadableObject({}));
1058 describe(".length", () => {
1059 it("[[Get]] returns the correct length", () => {
1060 assertStrictEquals(isConcatSpreadableObject
.length
, 1);
1064 describe(".name", () => {
1065 it("[[Get]] returns the correct name", () => {
1067 isConcatSpreadableObject
.name
,
1068 "isConcatSpreadableObject",
1074 describe("isExtensibleObject", () => {
1075 it("[[Call]] returns true for extensible objects", () => {
1076 assertStrictEquals(isExtensibleObject({}), true);
1079 it("[[Call]] returns false for coercible primitives", () => {
1080 assertStrictEquals(isExtensibleObject(1), false);
1081 assertStrictEquals(isExtensibleObject(Symbol()), false);
1084 it("[[Call]] returns false for non·extensible objects", () => {
1086 isExtensibleObject(Object
.preventExtensions({})),
1091 it("[[Call]] returns false for null and undefined", () => {
1092 assertStrictEquals(isExtensibleObject(null), false);
1093 assertStrictEquals(isExtensibleObject(undefined), false);
1096 it("[[Construct]] throws an error", () => {
1097 assertThrows(() => new isExtensibleObject({}));
1100 describe(".length", () => {
1101 it("[[Get]] returns the correct length", () => {
1102 assertStrictEquals(isExtensibleObject
.length
, 1);
1106 describe(".name", () => {
1107 it("[[Get]] returns the correct name", () => {
1109 isExtensibleObject
.name
,
1110 "isExtensibleObject",
1116 describe("isUnfrozenObject", () => {
1117 it("[[Call]] returns true for unfrozen objects", () => {
1118 assertStrictEquals(isUnfrozenObject({}), true);
1121 it("[[Call]] returns false for coercible primitives", () => {
1122 assertStrictEquals(isUnfrozenObject(1), false);
1123 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1126 it("[[Call]] returns false for frozen objects", () => {
1127 assertStrictEquals(isUnfrozenObject(Object
.freeze({})), false);
1130 it("[[Call]] returns false for null and undefined", () => {
1131 assertStrictEquals(isUnfrozenObject(null), false);
1132 assertStrictEquals(isUnfrozenObject(undefined), false);
1135 it("[[Construct]] throws an error", () => {
1136 assertThrows(() => new isUnfrozenObject({}));
1139 describe(".length", () => {
1140 it("[[Get]] returns the correct length", () => {
1141 assertStrictEquals(isUnfrozenObject
.length
, 1);
1145 describe(".name", () => {
1146 it("[[Get]] returns the correct name", () => {
1147 assertStrictEquals(isUnfrozenObject
.name
, "isUnfrozenObject");
1152 describe("isUnsealedObject", () => {
1153 it("[[Call]] returns true for unsealed objects", () => {
1154 assertStrictEquals(isUnsealedObject({}), true);
1157 it("[[Call]] returns false for coercible primitives", () => {
1158 assertStrictEquals(isUnsealedObject(1), false);
1159 assertStrictEquals(isUnsealedObject(Symbol()), false);
1162 it("[[Call]] returns false for sealed objects", () => {
1163 assertStrictEquals(isUnsealedObject(Object
.seal({})), false);
1166 it("[[Call]] returns false for null and undefined", () => {
1167 assertStrictEquals(isUnsealedObject(null), false);
1168 assertStrictEquals(isUnsealedObject(undefined), false);
1171 it("[[Construct]] throws an error", () => {
1172 assertThrows(() => new isUnsealedObject({}));
1175 describe(".length", () => {
1176 it("[[Get]] returns the correct length", () => {
1177 assertStrictEquals(isUnsealedObject
.length
, 1);
1181 describe(".name", () => {
1182 it("[[Get]] returns the correct name", () => {
1183 assertStrictEquals(isUnsealedObject
.name
, "isUnsealedObject");
1188 describe("lengthOfArraylike", () => {
1189 it("[[Call]] returns the length", () => {
1191 lengthOfArraylike({ length
: 9007199254740991 }),
1196 it("[[Call]] returns a non·nan result", () => {
1197 assertStrictEquals(lengthOfArraylike({ length
: NaN
}), 0);
1198 assertStrictEquals(lengthOfArraylike({ length
: "failure" }), 0);
1201 it("[[Call]] returns an integral result", () => {
1202 assertStrictEquals(lengthOfArraylike({ length
: 0.25 }), 0);
1203 assertStrictEquals(lengthOfArraylike({ length
: 1.1 }), 1);
1206 it("[[Call]] returns a result greater than or equal to zero", () => {
1207 assertStrictEquals(lengthOfArraylike({ length
: -0 }), 0);
1208 assertStrictEquals(lengthOfArraylike({ length
: -1 }), 0);
1209 assertStrictEquals(lengthOfArraylike({ length
: -Infinity
}), 0);
1212 it("[[Call]] returns a result less than 2 ** 53", () => {
1214 lengthOfArraylike({ length
: 9007199254740992 }),
1218 lengthOfArraylike({ length
: Infinity
}),
1223 it("[[Call]] does not require an object argument", () => {
1224 assertStrictEquals(lengthOfArraylike("string"), 6);
1225 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1228 it("[[Construct]] throws an error", () => {
1229 assertThrows(() => new lengthOfArraylike(""));
1232 describe(".length", () => {
1233 it("[[Get]] returns the correct length", () => {
1234 assertStrictEquals(lengthOfArraylike
.length
, 1);
1238 describe(".name", () => {
1239 it("[[Get]] returns the correct name", () => {
1240 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
1245 describe("namedEntries", () => {
1246 it("[[Call]] gets named entries", () => {
1247 assertEquals(namedEntries({ success
: true }), [["success", true]]);
1250 it("[[Call]] works for values coercible to objects", () => {
1251 assertEquals(namedEntries("foo"), [
1258 it("[[Call]] throws for null and undefined", () => {
1259 assertThrows(() => namedEntries(null));
1260 assertThrows(() => namedEntries(undefined));
1263 it("[[Construct]] throws an error", () => {
1264 assertThrows(() => new namedEntries({}));
1267 describe(".length", () => {
1268 it("[[Get]] returns the correct length", () => {
1269 assertStrictEquals(namedEntries
.length
, 1);
1273 describe(".name", () => {
1274 it("[[Get]] returns the correct name", () => {
1275 assertStrictEquals(namedEntries
.name
, "namedEntries");
1280 describe("namedKeys", () => {
1281 it("[[Call]] gets named keys", () => {
1282 assertEquals(namedKeys({ success
: true }), ["success"]);
1285 it("[[Call]] works for values coercible to objects", () => {
1286 assertEquals(namedKeys("foo"), [
1293 it("[[Call]] throws for null and undefined", () => {
1294 assertThrows(() => namedKeys(null));
1295 assertThrows(() => namedKeys(undefined));
1298 it("[[Construct]] throws an error", () => {
1299 assertThrows(() => new namedKeys({}));
1302 describe(".length", () => {
1303 it("[[Get]] returns the correct length", () => {
1304 assertStrictEquals(namedKeys
.length
, 1);
1308 describe(".name", () => {
1309 it("[[Get]] returns the correct name", () => {
1310 assertStrictEquals(namedKeys
.name
, "namedKeys");
1315 describe("namedValues", () => {
1316 it("[[Call]] gets named values", () => {
1317 assertEquals(namedValues({ success
: true }), [true]);
1320 it("[[Call]] works for values coercible to objects", () => {
1321 assertEquals(namedValues("foo"), [
1328 it("[[Call]] throws for null and undefined", () => {
1329 assertThrows(() => namedValues(null));
1330 assertThrows(() => namedValues(undefined));
1333 it("[[Construct]] throws an error", () => {
1334 assertThrows(() => new namedValues({}));
1337 describe(".length", () => {
1338 it("[[Get]] returns the correct length", () => {
1339 assertStrictEquals(namedValues
.length
, 1);
1343 describe(".name", () => {
1344 it("[[Get]] returns the correct name", () => {
1345 assertStrictEquals(namedValues
.name
, "namedValues");
1350 describe("objectCreate", () => {
1351 it("[[Call]] creates an object", () => {
1352 const obj
= objectCreate(null);
1353 assertStrictEquals(Object(obj
), obj
);
1356 it("[[Call]] correctly sets the prototype", () => {
1359 Object
.getPrototypeOf(objectCreate(proto
)),
1363 Object
.getPrototypeOf(objectCreate(null)),
1368 it("[[Call]] correctly sets own properties", () => {
1370 Object
.getOwnPropertyDescriptors(
1371 objectCreate(null, { success
: { value
: true } }),
1375 configurable
: false,
1384 it("[[Call]] throws for coercible primitives", () => {
1385 assertThrows(() => objectCreate(1));
1386 assertThrows(() => objectCreate(Symbol()));
1389 it("[[Call]] throws for undefined", () => {
1390 assertThrows(() => objectCreate(undefined));
1393 it("[[Construct]] throws an error", () => {
1394 assertThrows(() => new objectCreate({}));
1397 describe(".length", () => {
1398 it("[[Get]] returns the correct length", () => {
1399 assertStrictEquals(objectCreate
.length
, 2);
1403 describe(".name", () => {
1404 it("[[Get]] returns the correct name", () => {
1405 assertStrictEquals(objectCreate
.name
, "objectCreate");
1410 describe("objectFromEntries", () => {
1411 it("[[Call]] creates an object", () => {
1412 const obj
= objectFromEntries([]);
1413 assertStrictEquals(Object(obj
), obj
);
1416 it("[[Call]] correctly sets the prototype", () => {
1418 Object
.getPrototypeOf(objectFromEntries([])),
1423 it("[[Call]] correctly sets own properties", () => {
1425 Object
.entries(objectFromEntries([["success", true]])),
1426 [["success", true]],
1430 it("[[Call]] throws if the argument is not a nested arraylike", () => {
1431 assertThrows(() => objectFromEntries(1));
1432 assertThrows(() => objectFromEntries(Symbol()));
1433 assertThrows(() => objectFromEntries(null));
1434 assertThrows(() => objectFromEntries(undefined));
1435 assertThrows(() => objectFromEntries({}));
1436 assertThrows(() => objectFromEntries([undefined]));
1439 it("[[Construct]] throws an error", () => {
1440 assertThrows(() => new objectFromEntries([]));
1443 describe(".length", () => {
1444 it("[[Get]] returns the correct length", () => {
1445 assertStrictEquals(objectFromEntries
.length
, 1);
1449 describe(".name", () => {
1450 it("[[Get]] returns the correct name", () => {
1451 assertStrictEquals(objectFromEntries
.name
, "objectFromEntries");
1456 describe("preventExtensions", () => {
1457 it("[[Call]] prevents extensions on the object", () => {
1459 preventExtensions(obj
);
1460 assert(!Object
.isExtensible(obj
));
1463 it("[[Call]] returns the provided object", () => {
1465 assertStrictEquals(preventExtensions(obj
), obj
);
1468 it("[[Construct]] throws an error", () => {
1469 assertThrows(() => new preventExtensions({}));
1472 describe(".length", () => {
1473 it("[[Get]] returns the correct length", () => {
1474 assertStrictEquals(preventExtensions
.length
, 1);
1478 describe(".name", () => {
1479 it("[[Get]] returns the correct name", () => {
1480 assertStrictEquals(preventExtensions
.name
, "preventExtensions");
1485 describe("seal", () => {
1486 it("[[Call]] seals the object", () => {
1489 assert(Object
.isSealed(obj
));
1492 it("[[Call]] returns the provided object", () => {
1494 assertStrictEquals(seal(obj
), obj
);
1497 it("[[Construct]] throws an error", () => {
1498 assertThrows(() => new seal({}));
1501 describe(".length", () => {
1502 it("[[Get]] returns the correct length", () => {
1503 assertStrictEquals(seal
.length
, 1);
1507 describe(".name", () => {
1508 it("[[Get]] returns the correct name", () => {
1509 assertStrictEquals(seal
.name
, "seal");
1514 describe("setPropertyValue", () => {
1515 it("[[Call]] sets the provided property on the provided object", () => {
1517 setPropertyValue(obj
, "success", true);
1518 assertStrictEquals(obj
.success
, true);
1521 it("[[Call]] calls setters", () => {
1522 const setter
= spy((_
) => {});
1523 const obj
= Object
.create(null, { success
: { set: setter
} });
1524 setPropertyValue(obj
, "success", true);
1525 assertSpyCalls(setter
, 1);
1526 assertSpyCall(setter
, 0, {
1532 it("[[Call]] walks the prototype chain", () => {
1533 const setter
= spy((_
) => {});
1534 const obj
= Object
.create(
1535 Object
.create(null, { success
: { set: setter
} }),
1537 setPropertyValue(obj
, "success", true);
1538 assertSpyCalls(setter
, 1);
1539 assertSpyCall(setter
, 0, {
1545 it("[[Call]] uses the provided receiver", () => {
1546 const setter
= spy((_
) => {});
1547 const obj
= Object
.create(null, { success
: { set: setter
} });
1548 const receiver
= {};
1549 setPropertyValue(obj
, "success", true, receiver
);
1550 assertSpyCalls(setter
, 1);
1551 assertSpyCall(setter
, 0, {
1557 it("[[Call]] throws if the property can’t be set", () => {
1558 const obj
= Object
.freeze({ failure
: undefined });
1559 assertThrows(() => setPropertyValue(obj
, "failure", true));
1562 it("[[Call]] returns the provided object", () => {
1564 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
1567 it("[[Construct]] throws an error", () => {
1568 assertThrows(() => new setPropertyValue({}, "", undefined));
1571 describe(".length", () => {
1572 it("[[Get]] returns the correct length", () => {
1573 assertStrictEquals(setPropertyValue
.length
, 3);
1577 describe(".name", () => {
1578 it("[[Get]] returns the correct name", () => {
1579 assertStrictEquals(setPropertyValue
.name
, "setPropertyValue");
1584 describe("setPropertyValues", () => {
1585 it("[[Call]] sets the provided properties on the provided object", () => {
1587 setPropertyValues(obj
, { success
: true, all
: "good" });
1588 assertStrictEquals(obj
.success
, true);
1589 assertStrictEquals(obj
.all
, "good");
1592 it("[[Call]] can take multiple objects", () => {
1596 { success
: false, all
: "good" },
1599 assertStrictEquals(obj
.success
, true);
1600 assertStrictEquals(obj
.all
, "good");
1603 it("[[Call]] ignores nullish arguments", () => {
1605 setPropertyValues(obj
, null, undefined, { success
: true });
1606 assertStrictEquals(obj
.success
, true);
1609 it("[[Call]] calls setters", () => {
1610 const setter
= spy((_
) => {});
1611 const obj
= Object
.create(null, { success
: { set: setter
} });
1612 setPropertyValues(obj
, { success
: true });
1613 assertSpyCalls(setter
, 1);
1614 assertSpyCall(setter
, 0, {
1620 it("[[Call]] calls setters multiple times if property appears more than once", () => {
1621 const setter
= spy((_
) => {});
1622 const obj
= Object
.create(null, { success
: { set: setter
} });
1623 setPropertyValues(obj
, { success
: false }, { success
: true });
1624 assertSpyCalls(setter
, 2);
1625 assertSpyCall(setter
, 0, {
1629 assertSpyCall(setter
, 1, {
1635 it("[[Call]] walks the prototype chain", () => {
1636 const setter
= spy((_
) => {});
1637 const obj
= Object
.create(
1638 Object
.create(null, { success
: { set: setter
} }),
1640 setPropertyValues(obj
, { success
: true });
1641 assertSpyCalls(setter
, 1);
1642 assertSpyCall(setter
, 0, {
1648 it("[[Call]] throws if the property can’t be set", () => {
1649 const obj
= Object
.freeze({ failure
: undefined });
1650 assertThrows(() => setPropertyValues(obj
, { failure
: true }));
1653 it("[[Call]] returns the provided object", () => {
1655 assertStrictEquals(setPropertyValues(obj
, { "": undefined }), obj
);
1658 it("[[Construct]] throws an error", () => {
1659 assertThrows(() => new setPropertyValues(obj
, { "": undefined }));
1662 describe(".length", () => {
1663 it("[[Get]] returns the correct length", () => {
1664 assertStrictEquals(setPropertyValues
.length
, 2);
1668 describe(".name", () => {
1669 it("[[Get]] returns the correct name", () => {
1670 assertStrictEquals(setPropertyValues
.name
, "setPropertyValues");
1675 describe("setPrototype", () => {
1676 it("[[Call]] sets object prototypes", () => {
1679 setPrototype(obj
, proto
);
1680 assertStrictEquals(Object
.getPrototypeOf(obj
), proto
);
1683 it("[[Call]] sets null prototypes", () => {
1685 setPrototype(obj
, null);
1686 assertStrictEquals(Object
.getPrototypeOf(obj
), null);
1689 it("[[Call]] can set coercible primitives to their same prototype", () => {
1690 setPrototype(1, Number
.prototype);
1691 setPrototype(Symbol(), Symbol
.prototype);
1694 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
1695 assertThrows(() => setPrototype(1, Object
.prototype));
1696 assertThrows(() => setPrototype(Symbol(), Object
.prototype));
1699 it("[[Call]] throws for null and undefined", () => {
1700 assertThrows(() => setPrototype(null, Object
.prototype));
1701 assertThrows(() => setPrototype(undefined, Object
.prototype));
1704 it("[[Call]] returns the provided value", () => {
1706 assertStrictEquals(setPrototype(obj
, null), obj
);
1707 assertStrictEquals(setPrototype(1, Number
.prototype), 1);
1710 it("[[Construct]] throws an error", () => {
1711 assertThrows(() => new setPrototype({}, null));
1714 describe(".length", () => {
1715 it("[[Get]] returns the correct length", () => {
1716 assertStrictEquals(setPrototype
.length
, 2);
1720 describe(".name", () => {
1721 it("[[Get]] returns the correct name", () => {
1722 assertStrictEquals(setPrototype
.name
, "setPrototype");
1727 describe("toObject", () => {
1728 it("returns the input for objects", () => {
1730 assertStrictEquals(toObject(obj
), obj
);
1733 it("throws for nullish values", () => {
1734 assertThrows(() => toObject(null));
1735 assertThrows(() => toObject(void {}));
1738 it("returns a wrapper object for other primitives", () => {
1739 const sym
= Symbol();
1740 assertStrictEquals(typeof toObject(sym
), "object");
1741 assertStrictEquals(toObject(sym
).valueOf(), sym
);
1744 it("[[Construct]] throws an error", () => {
1745 assertThrows(() => new toObject({}));
1748 describe(".length", () => {
1749 it("[[Get]] returns the correct length", () => {
1750 assertStrictEquals(toObject
.length
, 1);
1754 describe(".name", () => {
1755 it("[[Get]] returns the correct name", () => {
1756 assertStrictEquals(toObject
.name
, "toObject");
1761 describe("toPropertyKey", () => {
1762 it("returns a string or symbol", () => {
1763 const sym
= Symbol();
1764 assertStrictEquals(toPropertyKey(sym
), sym
);
1766 toPropertyKey(new String("success")),
1771 it("favours the `toString` representation", () => {
1785 it("[[Construct]] throws an error", () => {
1786 assertThrows(() => new toPropertyKey(""));
1789 describe(".length", () => {
1790 it("[[Get]] returns the correct length", () => {
1791 assertStrictEquals(toPropertyKey
.length
, 1);
1795 describe(".name", () => {
1796 it("[[Get]] returns the correct name", () => {
1797 assertStrictEquals(toPropertyKey
.name
, "toPropertyKey");