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";
22 defineOwnDataProperty
,
23 defineOwnNonenumerableDataProperty
,
30 getOwnPropertyDescriptor
,
31 getOwnPropertyDescriptors
,
33 getOwnPropertyStrings
,
34 getOwnPropertySymbols
,
40 isConcatSpreadableObject
,
60 describe("LazyLoader", () => {
61 const symbol
= Symbol("foo");
63 const etaoinMethod
= spy(() => "success");
64 const shrdluMethod
= spy(() => "success");
65 const cmfwypMethod
= spy(() => "success");
66 const vbgkqjMethod
= spy(() => "success");
67 const methodsObject
= Object
.create(
97 xz
fiflffffi: { configurable
: true, enumerable
: false, set(_
) {} },
107 it("[[Call]] throws an error", () => {
108 assertThrows(() => LazyLoader({}));
111 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
113 Object
.getPrototypeOf(new LazyLoader(methodsObject
)),
118 it("[[Construct]] creates a new object with the desired properties", () => {
120 Reflect
.ownKeys(new LazyLoader(methodsObject
)),
121 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol
],
125 it("[[Construct]] creates a new object with configurable properties", () => {
129 for (const key
of Reflect
.ownKeys(ll
)) {
132 Object
.getOwnPropertyDescriptor(ll
, key
).configurable
,
135 }(new LazyLoader(methodsObject
)),
148 it("[[Construct]] creates a new object with the correct enumerability", () => {
152 for (const key
of Reflect
.ownKeys(ll
)) {
155 Object
.getOwnPropertyDescriptor(ll
, key
).enumerable
,
158 }(new LazyLoader(methodsObject
)),
171 it("[[Construct]] creates a new object with defined getters", () => {
175 for (const key
of Reflect
.ownKeys(ll
)) {
178 Object
.getOwnPropertyDescriptor(ll
, key
).get?.name
,
181 }(new LazyLoader(methodsObject
)),
184 etaoin
: "get etaoin",
185 shrdlu
: "get shrdlu",
186 cmfwyp
: "get cmfwyp",
187 vbgkqj
: "get vbgkqj",
188 xz
fiflffffi: "get xzfiflffffi",
189 [symbol
]: `get [${symbol.description}]`,
194 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
198 for (const key
of Reflect
.ownKeys(ll
)) {
201 Object
.getOwnPropertyDescriptor(ll
, key
).set?.name
,
204 }(new LazyLoader(methodsObject
)),
212 [symbol
]: `set [${symbol.description}]`,
217 it("[[Construct]] creates a new object with correct getter behaviour", () => {
218 const ll
= new LazyLoader(methodsObject
);
221 Object
.getOwnPropertyDescriptor(ll
, "etaoin"),
229 assertSpyCalls(etaoinMethod
, 1);
230 assertSpyCall(etaoinMethod
, 0, {
237 Object
.getOwnPropertyDescriptor(ll
, "shrdlu"),
245 assertSpyCalls(shrdluMethod
, 1);
246 assertSpyCall(shrdluMethod
, 0, {
253 Object
.getOwnPropertyDescriptor(ll
, "cmfwyp"),
261 assertSpyCalls(cmfwypMethod
, 1);
262 assertSpyCall(cmfwypMethod
, 0, {
269 Object
.getOwnPropertyDescriptor(ll
, "vbgkqj"),
277 assertSpyCalls(vbgkqjMethod
, 1);
278 assertSpyCall(vbgkqjMethod
, 0, {
283 assertThrows(() => ll
.xz
fiflffffi);
284 assertThrows(() => ll
[symbol
]);
287 it("[[Construct]] creates a new object with correct setter behaviour", () => {
288 const ll
= new LazyLoader(methodsObject
);
289 ll
[symbol
] = "success";
291 Object
.getOwnPropertyDescriptor(ll
, symbol
),
301 describe(".length", () => {
302 it("[[Get]] returns the correct length", () => {
303 assertStrictEquals(LazyLoader
.length
, 1);
307 describe(".name", () => {
308 it("[[Get]] returns the correct name", () => {
309 assertStrictEquals(LazyLoader
.name
, "LazyLoader");
314 describe("defineOwnDataProperty", () => {
315 it("[[Call]] defines the property", () => {
317 defineOwnDataProperty(obj
, "etaoin", "success");
318 assert(Object
.hasOwn(obj
, "etaoin"));
319 assertStrictEquals(obj
.etaoin
, "success");
322 it("[[Call]] defines a configurable, enumerable, writable property", () => {
324 defineOwnDataProperty(obj
, "etaoin", "success");
326 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
336 it("[[Call]] returns the provided object", () => {
339 defineOwnDataProperty(obj
, "etaoin", null),
344 it("[[Construct]] throws an error", () => {
345 assertThrows(() => new defineOwnDataProperty(obj
, "etaoin", null));
348 describe(".length", () => {
349 it("[[Get]] returns the correct length", () => {
350 assertStrictEquals(defineOwnDataProperty
.length
, 3);
354 describe(".name", () => {
355 it("[[Get]] returns the correct name", () => {
357 defineOwnDataProperty
.name
,
358 "defineOwnDataProperty",
364 describe("defineOwnNonenumerableDataProperty", () => {
365 it("[[Call]] defines the property", () => {
367 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
368 assert(Object
.hasOwn(obj
, "etaoin"));
369 assertStrictEquals(obj
.etaoin
, "success");
372 it("[[Call]] defines a configurable, non·enumerable, writable property", () => {
374 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
376 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
386 it("[[Call]] returns the provided object", () => {
389 defineOwnNonenumerableDataProperty(obj
, "etaoin", null),
394 it("[[Construct]] throws an error", () => {
396 new defineOwnNonenumerableDataProperty(obj
, "etaoin", null)
400 describe(".length", () => {
401 it("[[Get]] returns the correct length", () => {
402 assertStrictEquals(defineOwnNonenumerableDataProperty
.length
, 3);
406 describe(".name", () => {
407 it("[[Get]] returns the correct name", () => {
409 defineOwnNonenumerableDataProperty
.name
,
410 "defineOwnNonenumerableDataProperty",
416 describe("defineOwnProperty", () => {
417 it("[[Call]] defines the property", () => {
419 defineOwnProperty(obj
, "etaoin", {});
420 assert(Object
.hasOwn(obj
, "etaoin"));
423 it("[[Call]] returns the provided object", () => {
425 assertStrictEquals(defineOwnProperty(obj
, "etaoin", {}), obj
);
428 it("[[Construct]] throws an error", () => {
429 assertThrows(() => new defineOwnProperty(obj
, "etaoin", {}));
432 describe(".length", () => {
433 it("[[Get]] returns the correct length", () => {
434 assertStrictEquals(defineOwnProperty
.length
, 3);
438 describe(".name", () => {
439 it("[[Get]] returns the correct name", () => {
441 defineOwnProperty
.name
,
448 describe("defineOwnProperties", () => {
449 it("[[Call]] defines properties from the provided objects", () => {
451 defineOwnProperties(obj
, {
455 assert("etaoin" in obj
);
456 assert("shrdlu" in obj
);
457 assert("cmfwyp" in obj
);
460 it("[[Call]] overrides earlier declarations with later ones", () => {
461 const obj
= { etaoin
: undefined };
462 defineOwnProperties(obj
, {
463 etaoin
: { value
: "failure" },
465 etaoin
: { value
: "success" },
467 assertStrictEquals(obj
.etaoin
, "success");
470 it("[[Call]] returns the provided object", () => {
472 assertStrictEquals(defineOwnProperties(obj
), obj
);
475 it("[[Construct]] throws an error", () => {
476 assertThrows(() => new defineOwnProperties({}));
479 describe(".length", () => {
480 it("[[Get]] returns the correct length", () => {
481 assertStrictEquals(defineOwnProperties
.length
, 1);
485 describe(".name", () => {
486 it("[[Get]] returns the correct name", () => {
488 defineOwnProperties
.name
,
489 "defineOwnProperties",
495 describe("deleteOwnProperty", () => {
496 it("[[Call]] deletes the provided property on the provided object", () => {
497 const obj
= { failure
: undefined };
498 deleteOwnProperty(obj
, "failure");
499 assert(!("failure" in obj
));
502 it("[[Call]] does nothing if the property doesn’t exist", () => {
503 const obj
= Object
.freeze({});
504 deleteOwnProperty(obj
, "failure");
505 assert(!("failure" in obj
));
508 it("[[Call]] throws if the property can’t be deleted", () => {
509 const obj
= Object
.seal({ failure
: undefined });
510 assertThrows(() => deleteOwnProperty(obj
, "failure"));
513 it("[[Call]] returns the provided object", () => {
515 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
518 it("[[Construct]] throws an error", () => {
519 assertThrows(() => new deleteOwnProperty({}, ""));
522 describe(".length", () => {
523 it("[[Get]] returns the correct length", () => {
524 assertStrictEquals(deleteOwnProperty
.length
, 2);
528 describe(".name", () => {
529 it("[[Get]] returns the correct name", () => {
530 assertStrictEquals(deleteOwnProperty
.name
, "deleteOwnProperty");
535 describe("freeze", () => {
536 it("[[Call]] freezes the object", () => {
539 assert(Object
.isFrozen(obj
));
542 it("[[Call]] returns the provided object", () => {
544 assertStrictEquals(freeze(obj
), obj
);
547 it("[[Construct]] throws an error", () => {
548 assertThrows(() => new freeze({}));
551 describe(".length", () => {
552 it("[[Get]] returns the correct length", () => {
553 assertStrictEquals(freeze
.length
, 1);
557 describe(".name", () => {
558 it("[[Get]] returns the correct name", () => {
559 assertStrictEquals(freeze
.name
, "freeze");
564 describe("frozenCopy", () => {
565 it("[[Call]] returns a frozen object", () => {
568 frozenCopy(Object
.create(null), {
585 it("[[Call]] ignores non·enumerable properties", () => {
588 Object
.create(null, {
589 data
: { value
: undefined },
590 accessor
: { get: undefined },
597 it("[[Call]] preserves accessor properties", () => {
625 Object
.getOwnPropertyDescriptors(
626 frozenCopy(Object
.create(null, properties
)),
632 it("[[Call]] preserves data properties", () => {
652 Object
.getOwnPropertyDescriptors(
653 frozenCopy(Object
.create(null, properties
)),
657 ...properties
.implied
,
661 writable
: { ...properties
.writable
, writable
: false },
662 nonwritable
: properties
.nonwritable
,
667 it("[[Call]] does not copy properties on the prototype", () => {
670 frozenCopy(Object
.create({ failure
: undefined }))),
674 it("[[Call]] uses the species of the constructor", () => {
675 const species
= { prototype: {} };
677 Object
.getPrototypeOf(
678 frozenCopy({}, { [Symbol
.species
]: species
}),
684 it("[[Call]] uses constructor if no species is defined", () => {
685 const constructor = { [Symbol
.species
]: null, prototype: {} };
687 Object
.getPrototypeOf(frozenCopy({}, constructor)),
688 constructor.prototype,
692 it("[[Call]] uses the constructor on the object if none is provided", () => {
693 const constructor = { [Symbol
.species
]: null, prototype: {} };
695 Object
.getPrototypeOf(frozenCopy({ constructor })),
696 constructor.prototype,
700 it("[[Call]] allows a null constructor", () => {
702 Object
.getPrototypeOf(frozenCopy({}, null)),
707 it("[[Construct]] throws an error", () => {
708 assertThrows(() => new frozenCopy({}));
711 describe(".length", () => {
712 it("[[Get]] returns the correct length", () => {
713 assertStrictEquals(frozenCopy
.length
, 1);
717 describe(".name", () => {
718 it("[[Get]] returns the correct name", () => {
719 assertStrictEquals(frozenCopy
.name
, "frozenCopy");
724 describe("getMethod", () => {
725 it("[[Call]] gets a method", () => {
726 const method
= () => {};
727 assertStrictEquals(getMethod({ method
}, "method"), method
);
730 it("[[Call]] works for values coercible to objects", () => {
731 assertEquals(getMethod("", "toString"), String
.prototype.toString
);
734 it("[[Call]] throws for null and undefined", () => {
735 assertThrows(() => getMethod(null, "valueOf"));
736 assertThrows(() => getMethod(undefined, "valueOf"));
739 it("[[Call]] throws if the resulting value isn’t callable", () => {
740 assertThrows(() => getMethod({ "failure": true }, "failure"));
743 it("[[Construct]] throws an error", () => {
744 assertThrows(() => new getMethod({ method() {} }, "method"));
747 describe(".length", () => {
748 it("[[Get]] returns the correct length", () => {
749 assertStrictEquals(getMethod
.length
, 2);
753 describe(".name", () => {
754 it("[[Get]] returns the correct name", () => {
755 assertStrictEquals(getMethod
.name
, "getMethod");
760 describe("getOwnPropertyDescriptor", () => {
761 it("[[Call]] gets the descriptor", () => {
763 getOwnPropertyDescriptor({ success
: true }, "success"),
773 it("[[Call]] returns undefined for non‐own properties", () => {
775 getOwnPropertyDescriptor({}, "valueOf"),
780 it("[[Construct]] throws an error", () => {
781 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
784 describe(".length", () => {
785 it("[[Get]] returns the correct length", () => {
786 assertStrictEquals(getOwnPropertyDescriptor
.length
, 2);
790 describe(".name", () => {
791 it("[[Get]] returns the correct name", () => {
793 getOwnPropertyDescriptor
.name
,
794 "getOwnPropertyDescriptor",
800 describe("getOwnPropertyDescriptors", () => {
801 it("[[Call]] gets the descriptors", () => {
803 getOwnPropertyDescriptors({ success
: true, etaoin
: "shrdlu" }),
821 it("[[Construct]] throws an error", () => {
822 assertThrows(() => new getOwnPropertyDescriptors({}));
825 describe(".length", () => {
826 it("[[Get]] returns the correct length", () => {
827 assertStrictEquals(getOwnPropertyDescriptors
.length
, 1);
831 describe(".name", () => {
832 it("[[Get]] returns the correct name", () => {
834 getOwnPropertyDescriptors
.name
,
835 "getOwnPropertyDescriptors",
841 describe("getOwnPropertyKeys", () => {
842 it("[[Call]] gets own (but not inherited) property keys", () => {
843 assertEquals(getOwnPropertyKeys({ success
: true }), ["success"]);
846 it("[[Call]] works for values coercible to objects", () => {
847 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
850 it("[[Call]] throws for null and undefined", () => {
851 assertThrows(() => getOwnPropertyKeys(null));
852 assertThrows(() => getOwnPropertyKeys(undefined));
855 it("[[Construct]] throws an error", () => {
856 assertThrows(() => new getOwnPropertyKeys({}));
859 describe(".length", () => {
860 it("[[Get]] returns the correct length", () => {
861 assertStrictEquals(getOwnPropertyKeys
.length
, 1);
865 describe(".name", () => {
866 it("[[Get]] returns the correct name", () => {
868 getOwnPropertyKeys
.name
,
869 "getOwnPropertyKeys",
875 describe("getOwnPropertyStrings", () => {
876 it("[[Call]] gets own string keys", () => {
877 assertEquals(getOwnPropertyStrings({ success
: true }), [
882 it("[[Call]] works for values coercible to objects", () => {
883 assertEquals(getOwnPropertyStrings("foo"), [
891 it("[[Call]] throws for null and undefined", () => {
892 assertThrows(() => getOwnPropertyStrings(null));
893 assertThrows(() => getOwnPropertyStrings(undefined));
896 it("[[Construct]] throws an error", () => {
897 assertThrows(() => new getOwnPropertyStrings({}));
900 describe(".length", () => {
901 it("[[Get]] returns the correct length", () => {
902 assertStrictEquals(getOwnPropertyStrings
.length
, 1);
906 describe(".name", () => {
907 it("[[Get]] returns the correct name", () => {
909 getOwnPropertyStrings
.name
,
910 "getOwnPropertyStrings",
916 describe("getOwnPropertySymbols", () => {
917 it("[[Call]] gets own symbol keys", () => {
918 const sym
= Symbol();
919 assertEquals(getOwnPropertySymbols({ [sym
]: true }), [sym
]);
922 it("[[Call]] works for values coercible to objects", () => {
923 assertEquals(getOwnPropertySymbols("foo"), []);
926 it("[[Call]] throws for null and undefined", () => {
927 assertThrows(() => getOwnPropertySymbols(null));
928 assertThrows(() => getOwnPropertySymbols(undefined));
931 it("[[Construct]] throws an error", () => {
932 assertThrows(() => new getOwnPropertySymbols({}));
935 describe(".length", () => {
936 it("[[Get]] returns the correct length", () => {
937 assertStrictEquals(getOwnPropertySymbols
.length
, 1);
941 describe(".name", () => {
942 it("[[Get]] returns the correct name", () => {
944 getOwnPropertySymbols
.name
,
945 "getOwnPropertySymbols",
951 describe("getPropertyValue", () => {
952 it("[[Call]] gets property values on the provided object", () => {
954 getPropertyValue({ success
: true }, "success"),
959 it("[[Call]] works for values coercible to objects", () => {
961 getPropertyValue("", "toString"),
962 String
.prototype.toString
,
966 it("[[Call]] throws for null and undefined", () => {
967 assertThrows(() => getPropertyValue(null, "valueOf"));
968 assertThrows(() => getPropertyValue(undefined, "valueOf"));
971 it("[[Construct]] throws an error", () => {
972 assertThrows(() => new getPropertyValue({}, "valueOf"));
975 describe(".length", () => {
976 it("[[Get]] returns the correct length", () => {
977 assertStrictEquals(getPropertyValue
.length
, 2);
981 describe(".name", () => {
982 it("[[Get]] returns the correct name", () => {
983 assertStrictEquals(getPropertyValue
.name
, "getPropertyValue");
988 describe("getPrototype", () => {
989 it("[[Call]] gets object prototypes", () => {
990 assertStrictEquals(getPrototype({}), Object
.prototype);
992 assertStrictEquals(getPrototype(Object
.create(proto
)), proto
);
995 it("[[Call]] gets null prototypes", () => {
996 assertStrictEquals(getPrototype(Object
.create(null)), null);
999 it("[[Call]] gets prototypes for coercible primitives", () => {
1000 assertStrictEquals(getPrototype(1), Number
.prototype);
1001 assertStrictEquals(getPrototype(Symbol()), Symbol
.prototype);
1004 it("[[Call]] throws for null and undefined", () => {
1005 assertThrows(() => getPrototype(null));
1006 assertThrows(() => getPrototype(undefined));
1009 it("[[Construct]] throws an error", () => {
1010 assertThrows(() => new getPrototype({}));
1013 describe(".length", () => {
1014 it("[[Get]] returns the correct length", () => {
1015 assertStrictEquals(getPrototype
.length
, 1);
1019 describe(".name", () => {
1020 it("[[Get]] returns the correct name", () => {
1021 assertStrictEquals(getPrototype
.name
, "getPrototype");
1026 describe("hasProperty", () => {
1027 it("[[Call]] gets whether a property exists on the provided object", () => {
1029 hasProperty({ success
: "etaoin" }, "success"),
1032 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
1035 it("[[Call]] works for values coercible to objects", () => {
1036 assertStrictEquals(hasProperty("", "length"), true);
1037 assertStrictEquals(hasProperty("", "toString"), true);
1040 it("[[Call]] throws for null and undefined", () => {
1041 assertThrows(() => hasProperty(null, "valueOf"));
1042 assertThrows(() => hasProperty(undefined, "valueOf"));
1045 it("[[Construct]] throws an error", () => {
1046 assertThrows(() => new hasProperty({}, "valueOf"));
1049 describe(".length", () => {
1050 it("[[Get]] returns the correct length", () => {
1051 assertStrictEquals(hasProperty
.length
, 2);
1055 describe(".name", () => {
1056 it("[[Get]] returns the correct name", () => {
1057 assertStrictEquals(hasProperty
.name
, "hasProperty");
1062 describe("hasOwnProperty", () => {
1063 it("[[Call]] gets whether an own property exists on the provided object", () => {
1065 hasOwnProperty({ success
: "etaoin" }, "success"),
1068 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
1071 it("[[Call]] works for values coercible to objects", () => {
1072 assertStrictEquals(hasOwnProperty("", "length"), true);
1073 assertStrictEquals(hasOwnProperty("", "toString"), false);
1076 it("[[Call]] throws for null and undefined", () => {
1077 assertThrows(() => hasOwnProperty(null, "valueOf"));
1078 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
1081 it("[[Construct]] throws an error", () => {
1082 assertThrows(() => new hasOwnProperty({}, "valueOf"));
1085 describe(".length", () => {
1086 it("[[Get]] returns the correct length", () => {
1087 assertStrictEquals(hasOwnProperty
.length
, 2);
1091 describe(".name", () => {
1092 it("[[Get]] returns the correct name", () => {
1093 assertStrictEquals(hasOwnProperty
.name
, "hasOwnProperty");
1098 describe("isArraylikeObject", () => {
1099 it("[[Call]] returns false for primitives", () => {
1100 assertStrictEquals(isArraylikeObject("failure"), false);
1103 it("[[Call]] returns false if length throws", () => {
1114 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
1115 assertStrictEquals(isArraylikeObject({ length
: 1n
}), false);
1118 it("[[Call]] returns true if length is convertable to a number", () => {
1119 assertStrictEquals(isArraylikeObject({ length
: -0 }), true);
1120 assertStrictEquals(isArraylikeObject({ length
: 1 }), true);
1121 assertStrictEquals(isArraylikeObject({ length
: -1.25 }), true);
1123 isArraylikeObject({ length
: 9007199254740992 }),
1126 assertStrictEquals(isArraylikeObject({ length
: Infinity
}), true);
1127 assertStrictEquals(isArraylikeObject({ length
: "success" }), true);
1130 it("[[Construct]] throws an error", () => {
1131 assertThrows(() => new isArraylikeObject({}));
1134 describe(".length", () => {
1135 it("[[Get]] returns the correct length", () => {
1136 assertStrictEquals(isArraylikeObject
.length
, 1);
1140 describe(".name", () => {
1141 it("[[Get]] returns the correct name", () => {
1143 isArraylikeObject
.name
,
1144 "isArraylikeObject",
1150 describe("isConcatSpreadableObject", () => {
1151 it("[[Call]] returns false for primitives", () => {
1152 assertStrictEquals(isConcatSpreadableObject("failure"), false);
1155 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
1157 isConcatSpreadableObject(
1158 Object
.assign([], { [Symbol
.isConcatSpreadable
]: null }),
1163 isConcatSpreadableObject(
1164 Object
.assign([], { [Symbol
.isConcatSpreadable
]: false }),
1170 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
1172 isConcatSpreadableObject(
1173 Object
.assign([], { [Symbol
.isConcatSpreadable
]: undefined }),
1179 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
1181 isConcatSpreadableObject({ [Symbol
.isConcatSpreadable
]: true }),
1186 it("[[Construct]] throws an error", () => {
1187 assertThrows(() => new isConcatSpreadableObject({}));
1190 describe(".length", () => {
1191 it("[[Get]] returns the correct length", () => {
1192 assertStrictEquals(isConcatSpreadableObject
.length
, 1);
1196 describe(".name", () => {
1197 it("[[Get]] returns the correct name", () => {
1199 isConcatSpreadableObject
.name
,
1200 "isConcatSpreadableObject",
1206 describe("isExtensibleObject", () => {
1207 it("[[Call]] returns true for extensible objects", () => {
1208 assertStrictEquals(isExtensibleObject({}), true);
1211 it("[[Call]] returns false for coercible primitives", () => {
1212 assertStrictEquals(isExtensibleObject(1), false);
1213 assertStrictEquals(isExtensibleObject(Symbol()), false);
1216 it("[[Call]] returns false for non·extensible objects", () => {
1218 isExtensibleObject(Object
.preventExtensions({})),
1223 it("[[Call]] returns false for null and undefined", () => {
1224 assertStrictEquals(isExtensibleObject(null), false);
1225 assertStrictEquals(isExtensibleObject(undefined), false);
1228 it("[[Construct]] throws an error", () => {
1229 assertThrows(() => new isExtensibleObject({}));
1232 describe(".length", () => {
1233 it("[[Get]] returns the correct length", () => {
1234 assertStrictEquals(isExtensibleObject
.length
, 1);
1238 describe(".name", () => {
1239 it("[[Get]] returns the correct name", () => {
1241 isExtensibleObject
.name
,
1242 "isExtensibleObject",
1248 describe("isUnfrozenObject", () => {
1249 it("[[Call]] returns true for unfrozen objects", () => {
1250 assertStrictEquals(isUnfrozenObject({}), true);
1253 it("[[Call]] returns false for coercible primitives", () => {
1254 assertStrictEquals(isUnfrozenObject(1), false);
1255 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1258 it("[[Call]] returns false for frozen objects", () => {
1259 assertStrictEquals(isUnfrozenObject(Object
.freeze({})), false);
1262 it("[[Call]] returns false for null and undefined", () => {
1263 assertStrictEquals(isUnfrozenObject(null), false);
1264 assertStrictEquals(isUnfrozenObject(undefined), false);
1267 it("[[Construct]] throws an error", () => {
1268 assertThrows(() => new isUnfrozenObject({}));
1271 describe(".length", () => {
1272 it("[[Get]] returns the correct length", () => {
1273 assertStrictEquals(isUnfrozenObject
.length
, 1);
1277 describe(".name", () => {
1278 it("[[Get]] returns the correct name", () => {
1279 assertStrictEquals(isUnfrozenObject
.name
, "isUnfrozenObject");
1284 describe("isUnsealedObject", () => {
1285 it("[[Call]] returns true for unsealed objects", () => {
1286 assertStrictEquals(isUnsealedObject({}), true);
1289 it("[[Call]] returns false for coercible primitives", () => {
1290 assertStrictEquals(isUnsealedObject(1), false);
1291 assertStrictEquals(isUnsealedObject(Symbol()), false);
1294 it("[[Call]] returns false for sealed objects", () => {
1295 assertStrictEquals(isUnsealedObject(Object
.seal({})), false);
1298 it("[[Call]] returns false for null and undefined", () => {
1299 assertStrictEquals(isUnsealedObject(null), false);
1300 assertStrictEquals(isUnsealedObject(undefined), false);
1303 it("[[Construct]] throws an error", () => {
1304 assertThrows(() => new isUnsealedObject({}));
1307 describe(".length", () => {
1308 it("[[Get]] returns the correct length", () => {
1309 assertStrictEquals(isUnsealedObject
.length
, 1);
1313 describe(".name", () => {
1314 it("[[Get]] returns the correct name", () => {
1315 assertStrictEquals(isUnsealedObject
.name
, "isUnsealedObject");
1320 describe("lengthOfArraylike", () => {
1321 it("[[Call]] returns the length", () => {
1323 lengthOfArraylike({ length
: 9007199254740991 }),
1328 it("[[Call]] returns a non·nan result", () => {
1329 assertStrictEquals(lengthOfArraylike({ length
: NaN
}), 0);
1330 assertStrictEquals(lengthOfArraylike({ length
: "failure" }), 0);
1333 it("[[Call]] returns an integral result", () => {
1334 assertStrictEquals(lengthOfArraylike({ length
: 0.25 }), 0);
1335 assertStrictEquals(lengthOfArraylike({ length
: 1.1 }), 1);
1338 it("[[Call]] returns a result greater than or equal to zero", () => {
1339 assertStrictEquals(lengthOfArraylike({ length
: -0 }), 0);
1340 assertStrictEquals(lengthOfArraylike({ length
: -1 }), 0);
1341 assertStrictEquals(lengthOfArraylike({ length
: -Infinity
}), 0);
1344 it("[[Call]] returns a result less than 2 ** 53", () => {
1346 lengthOfArraylike({ length
: 9007199254740992 }),
1350 lengthOfArraylike({ length
: Infinity
}),
1355 it("[[Call]] does not require an object argument", () => {
1356 assertStrictEquals(lengthOfArraylike("string"), 6);
1357 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1360 it("[[Construct]] throws an error", () => {
1361 assertThrows(() => new lengthOfArraylike(""));
1364 describe(".length", () => {
1365 it("[[Get]] returns the correct length", () => {
1366 assertStrictEquals(lengthOfArraylike
.length
, 1);
1370 describe(".name", () => {
1371 it("[[Get]] returns the correct name", () => {
1372 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
1377 describe("namedEntries", () => {
1378 it("[[Call]] gets named entries", () => {
1379 assertEquals(namedEntries({ success
: true }), [["success", true]]);
1382 it("[[Call]] works for values coercible to objects", () => {
1383 assertEquals(namedEntries("foo"), [
1390 it("[[Call]] throws for null and undefined", () => {
1391 assertThrows(() => namedEntries(null));
1392 assertThrows(() => namedEntries(undefined));
1395 it("[[Construct]] throws an error", () => {
1396 assertThrows(() => new namedEntries({}));
1399 describe(".length", () => {
1400 it("[[Get]] returns the correct length", () => {
1401 assertStrictEquals(namedEntries
.length
, 1);
1405 describe(".name", () => {
1406 it("[[Get]] returns the correct name", () => {
1407 assertStrictEquals(namedEntries
.name
, "namedEntries");
1412 describe("namedKeys", () => {
1413 it("[[Call]] gets named keys", () => {
1414 assertEquals(namedKeys({ success
: true }), ["success"]);
1417 it("[[Call]] works for values coercible to objects", () => {
1418 assertEquals(namedKeys("foo"), [
1425 it("[[Call]] throws for null and undefined", () => {
1426 assertThrows(() => namedKeys(null));
1427 assertThrows(() => namedKeys(undefined));
1430 it("[[Construct]] throws an error", () => {
1431 assertThrows(() => new namedKeys({}));
1434 describe(".length", () => {
1435 it("[[Get]] returns the correct length", () => {
1436 assertStrictEquals(namedKeys
.length
, 1);
1440 describe(".name", () => {
1441 it("[[Get]] returns the correct name", () => {
1442 assertStrictEquals(namedKeys
.name
, "namedKeys");
1447 describe("namedValues", () => {
1448 it("[[Call]] gets named values", () => {
1449 assertEquals(namedValues({ success
: true }), [true]);
1452 it("[[Call]] works for values coercible to objects", () => {
1453 assertEquals(namedValues("foo"), [
1460 it("[[Call]] throws for null and undefined", () => {
1461 assertThrows(() => namedValues(null));
1462 assertThrows(() => namedValues(undefined));
1465 it("[[Construct]] throws an error", () => {
1466 assertThrows(() => new namedValues({}));
1469 describe(".length", () => {
1470 it("[[Get]] returns the correct length", () => {
1471 assertStrictEquals(namedValues
.length
, 1);
1475 describe(".name", () => {
1476 it("[[Get]] returns the correct name", () => {
1477 assertStrictEquals(namedValues
.name
, "namedValues");
1482 describe("objectCreate", () => {
1483 it("[[Call]] creates an object", () => {
1484 const obj
= objectCreate(null);
1485 assertStrictEquals(Object(obj
), obj
);
1488 it("[[Call]] correctly sets the prototype", () => {
1491 Object
.getPrototypeOf(objectCreate(proto
)),
1495 Object
.getPrototypeOf(objectCreate(null)),
1500 it("[[Call]] correctly sets own properties", () => {
1502 Object
.getOwnPropertyDescriptors(
1503 objectCreate(null, { success
: { value
: true } }),
1507 configurable
: false,
1516 it("[[Call]] throws for coercible primitives", () => {
1517 assertThrows(() => objectCreate(1));
1518 assertThrows(() => objectCreate(Symbol()));
1521 it("[[Call]] throws for undefined", () => {
1522 assertThrows(() => objectCreate(undefined));
1525 it("[[Construct]] throws an error", () => {
1526 assertThrows(() => new objectCreate({}));
1529 describe(".length", () => {
1530 it("[[Get]] returns the correct length", () => {
1531 assertStrictEquals(objectCreate
.length
, 2);
1535 describe(".name", () => {
1536 it("[[Get]] returns the correct name", () => {
1537 assertStrictEquals(objectCreate
.name
, "objectCreate");
1542 describe("objectFromEntries", () => {
1543 it("[[Call]] creates an object", () => {
1544 const obj
= objectFromEntries([]);
1545 assertStrictEquals(Object(obj
), obj
);
1548 it("[[Call]] correctly sets the prototype", () => {
1550 Object
.getPrototypeOf(objectFromEntries([])),
1555 it("[[Call]] correctly sets own properties", () => {
1557 Object
.entries(objectFromEntries([["success", true]])),
1558 [["success", true]],
1562 it("[[Call]] throws if the argument is not a nested arraylike", () => {
1563 assertThrows(() => objectFromEntries(1));
1564 assertThrows(() => objectFromEntries(Symbol()));
1565 assertThrows(() => objectFromEntries(null));
1566 assertThrows(() => objectFromEntries(undefined));
1567 assertThrows(() => objectFromEntries({}));
1568 assertThrows(() => objectFromEntries([undefined]));
1571 it("[[Construct]] throws an error", () => {
1572 assertThrows(() => new objectFromEntries([]));
1575 describe(".length", () => {
1576 it("[[Get]] returns the correct length", () => {
1577 assertStrictEquals(objectFromEntries
.length
, 1);
1581 describe(".name", () => {
1582 it("[[Get]] returns the correct name", () => {
1583 assertStrictEquals(objectFromEntries
.name
, "objectFromEntries");
1588 describe("preventExtensions", () => {
1589 it("[[Call]] prevents extensions on the object", () => {
1591 preventExtensions(obj
);
1592 assert(!Object
.isExtensible(obj
));
1595 it("[[Call]] returns the provided object", () => {
1597 assertStrictEquals(preventExtensions(obj
), obj
);
1600 it("[[Construct]] throws an error", () => {
1601 assertThrows(() => new preventExtensions({}));
1604 describe(".length", () => {
1605 it("[[Get]] returns the correct length", () => {
1606 assertStrictEquals(preventExtensions
.length
, 1);
1610 describe(".name", () => {
1611 it("[[Get]] returns the correct name", () => {
1612 assertStrictEquals(preventExtensions
.name
, "preventExtensions");
1617 describe("seal", () => {
1618 it("[[Call]] seals the object", () => {
1621 assert(Object
.isSealed(obj
));
1624 it("[[Call]] returns the provided object", () => {
1626 assertStrictEquals(seal(obj
), obj
);
1629 it("[[Construct]] throws an error", () => {
1630 assertThrows(() => new seal({}));
1633 describe(".length", () => {
1634 it("[[Get]] returns the correct length", () => {
1635 assertStrictEquals(seal
.length
, 1);
1639 describe(".name", () => {
1640 it("[[Get]] returns the correct name", () => {
1641 assertStrictEquals(seal
.name
, "seal");
1646 describe("setPropertyValue", () => {
1647 it("[[Call]] sets the provided property on the provided object", () => {
1649 setPropertyValue(obj
, "success", true);
1650 assertStrictEquals(obj
.success
, true);
1653 it("[[Call]] calls setters", () => {
1654 const setter
= spy((_
) => {});
1655 const obj
= Object
.create(null, { success
: { set: setter
} });
1656 setPropertyValue(obj
, "success", true);
1657 assertSpyCalls(setter
, 1);
1658 assertSpyCall(setter
, 0, {
1664 it("[[Call]] walks the prototype chain", () => {
1665 const setter
= spy((_
) => {});
1666 const obj
= Object
.create(
1667 Object
.create(null, { success
: { set: setter
} }),
1669 setPropertyValue(obj
, "success", true);
1670 assertSpyCalls(setter
, 1);
1671 assertSpyCall(setter
, 0, {
1677 it("[[Call]] uses the provided receiver", () => {
1678 const setter
= spy((_
) => {});
1679 const obj
= Object
.create(null, { success
: { set: setter
} });
1680 const receiver
= {};
1681 setPropertyValue(obj
, "success", true, receiver
);
1682 assertSpyCalls(setter
, 1);
1683 assertSpyCall(setter
, 0, {
1689 it("[[Call]] throws if the property can’t be set", () => {
1690 const obj
= Object
.freeze({ failure
: undefined });
1691 assertThrows(() => setPropertyValue(obj
, "failure", true));
1694 it("[[Call]] returns the provided object", () => {
1696 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
1699 it("[[Construct]] throws an error", () => {
1700 assertThrows(() => new setPropertyValue({}, "", undefined));
1703 describe(".length", () => {
1704 it("[[Get]] returns the correct length", () => {
1705 assertStrictEquals(setPropertyValue
.length
, 3);
1709 describe(".name", () => {
1710 it("[[Get]] returns the correct name", () => {
1711 assertStrictEquals(setPropertyValue
.name
, "setPropertyValue");
1716 describe("setPropertyValues", () => {
1717 it("[[Call]] sets the provided properties on the provided object", () => {
1719 setPropertyValues(obj
, { success
: true, all
: "good" });
1720 assertStrictEquals(obj
.success
, true);
1721 assertStrictEquals(obj
.all
, "good");
1724 it("[[Call]] can take multiple objects", () => {
1728 { success
: false, all
: "good" },
1731 assertStrictEquals(obj
.success
, true);
1732 assertStrictEquals(obj
.all
, "good");
1735 it("[[Call]] ignores nullish arguments", () => {
1737 setPropertyValues(obj
, null, undefined, { success
: true });
1738 assertStrictEquals(obj
.success
, true);
1741 it("[[Call]] calls setters", () => {
1742 const setter
= spy((_
) => {});
1743 const obj
= Object
.create(null, { success
: { set: setter
} });
1744 setPropertyValues(obj
, { success
: true });
1745 assertSpyCalls(setter
, 1);
1746 assertSpyCall(setter
, 0, {
1752 it("[[Call]] calls setters multiple times if property appears more than once", () => {
1753 const setter
= spy((_
) => {});
1754 const obj
= Object
.create(null, { success
: { set: setter
} });
1755 setPropertyValues(obj
, { success
: false }, { success
: true });
1756 assertSpyCalls(setter
, 2);
1757 assertSpyCall(setter
, 0, {
1761 assertSpyCall(setter
, 1, {
1767 it("[[Call]] walks the prototype chain", () => {
1768 const setter
= spy((_
) => {});
1769 const obj
= Object
.create(
1770 Object
.create(null, { success
: { set: setter
} }),
1772 setPropertyValues(obj
, { success
: true });
1773 assertSpyCalls(setter
, 1);
1774 assertSpyCall(setter
, 0, {
1780 it("[[Call]] throws if the property can’t be set", () => {
1781 const obj
= Object
.freeze({ failure
: undefined });
1782 assertThrows(() => setPropertyValues(obj
, { failure
: true }));
1785 it("[[Call]] returns the provided object", () => {
1787 assertStrictEquals(setPropertyValues(obj
, { "": undefined }), obj
);
1790 it("[[Construct]] throws an error", () => {
1791 assertThrows(() => new setPropertyValues(obj
, { "": undefined }));
1794 describe(".length", () => {
1795 it("[[Get]] returns the correct length", () => {
1796 assertStrictEquals(setPropertyValues
.length
, 2);
1800 describe(".name", () => {
1801 it("[[Get]] returns the correct name", () => {
1802 assertStrictEquals(setPropertyValues
.name
, "setPropertyValues");
1807 describe("setPrototype", () => {
1808 it("[[Call]] sets object prototypes", () => {
1811 setPrototype(obj
, proto
);
1812 assertStrictEquals(Object
.getPrototypeOf(obj
), proto
);
1815 it("[[Call]] sets null prototypes", () => {
1817 setPrototype(obj
, null);
1818 assertStrictEquals(Object
.getPrototypeOf(obj
), null);
1821 it("[[Call]] can set coercible primitives to their same prototype", () => {
1822 setPrototype(1, Number
.prototype);
1823 setPrototype(Symbol(), Symbol
.prototype);
1826 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
1827 assertThrows(() => setPrototype(1, Object
.prototype));
1828 assertThrows(() => setPrototype(Symbol(), Object
.prototype));
1831 it("[[Call]] throws for null and undefined", () => {
1832 assertThrows(() => setPrototype(null, Object
.prototype));
1833 assertThrows(() => setPrototype(undefined, Object
.prototype));
1836 it("[[Call]] returns the provided value", () => {
1838 assertStrictEquals(setPrototype(obj
, null), obj
);
1839 assertStrictEquals(setPrototype(1, Number
.prototype), 1);
1842 it("[[Construct]] throws an error", () => {
1843 assertThrows(() => new setPrototype({}, null));
1846 describe(".length", () => {
1847 it("[[Get]] returns the correct length", () => {
1848 assertStrictEquals(setPrototype
.length
, 2);
1852 describe(".name", () => {
1853 it("[[Get]] returns the correct name", () => {
1854 assertStrictEquals(setPrototype
.name
, "setPrototype");
1859 describe("toObject", () => {
1860 it("returns the input for objects", () => {
1862 assertStrictEquals(toObject(obj
), obj
);
1865 it("throws for nullish values", () => {
1866 assertThrows(() => toObject(null));
1867 assertThrows(() => toObject(void {}));
1870 it("returns a wrapper object for other primitives", () => {
1871 const sym
= Symbol();
1872 assertStrictEquals(typeof toObject(sym
), "object");
1873 assertStrictEquals(toObject(sym
).valueOf(), sym
);
1876 it("[[Construct]] throws an error", () => {
1877 assertThrows(() => new toObject({}));
1880 describe(".length", () => {
1881 it("[[Get]] returns the correct length", () => {
1882 assertStrictEquals(toObject
.length
, 1);
1886 describe(".name", () => {
1887 it("[[Get]] returns the correct name", () => {
1888 assertStrictEquals(toObject
.name
, "toObject");
1893 describe("toPropertyKey", () => {
1894 it("returns a string or symbol", () => {
1895 const sym
= Symbol();
1896 assertStrictEquals(toPropertyKey(sym
), sym
);
1898 toPropertyKey(new String("success")),
1903 it("favours the `toString` representation", () => {
1917 it("[[Construct]] throws an error", () => {
1918 assertThrows(() => new toPropertyKey(""));
1921 describe(".length", () => {
1922 it("[[Get]] returns the correct length", () => {
1923 assertStrictEquals(toPropertyKey
.length
, 1);
1927 describe(".name", () => {
1928 it("[[Get]] returns the correct name", () => {
1929 assertStrictEquals(toPropertyKey
.name
, "toPropertyKey");