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
,
59 describe("LazyLoader", () => {
60 const symbol
= Symbol("foo");
62 const etaoinMethod
= spy(() => "success");
63 const shrdluMethod
= spy(() => "success");
64 const cmfwypMethod
= spy(() => "success");
65 const vbgkqjMethod
= spy(() => "success");
66 const methodsObject
= Object
.create(
96 xz
fiflffffi: { configurable
: true, enumerable
: false, set(_
) {} },
106 it("[[Call]] throws an error", () => {
107 assertThrows(() => LazyLoader({}));
110 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
112 Object
.getPrototypeOf(new LazyLoader(methodsObject
)),
117 it("[[Construct]] creates a new object with the desired properties", () => {
119 Reflect
.ownKeys(new LazyLoader(methodsObject
)),
120 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol
],
124 it("[[Construct]] creates a new object with configurable properties", () => {
128 for (const key
of Reflect
.ownKeys(ll
)) {
131 Object
.getOwnPropertyDescriptor(ll
, key
).configurable
,
134 }(new LazyLoader(methodsObject
)),
147 it("[[Construct]] creates a new object with the correct enumerability", () => {
151 for (const key
of Reflect
.ownKeys(ll
)) {
154 Object
.getOwnPropertyDescriptor(ll
, key
).enumerable
,
157 }(new LazyLoader(methodsObject
)),
170 it("[[Construct]] creates a new object with defined getters", () => {
174 for (const key
of Reflect
.ownKeys(ll
)) {
177 Object
.getOwnPropertyDescriptor(ll
, key
).get?.name
,
180 }(new LazyLoader(methodsObject
)),
183 etaoin
: "get etaoin",
184 shrdlu
: "get shrdlu",
185 cmfwyp
: "get cmfwyp",
186 vbgkqj
: "get vbgkqj",
187 xz
fiflffffi: "get xzfiflffffi",
188 [symbol
]: `get [${symbol.description}]`,
193 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
197 for (const key
of Reflect
.ownKeys(ll
)) {
200 Object
.getOwnPropertyDescriptor(ll
, key
).set?.name
,
203 }(new LazyLoader(methodsObject
)),
211 [symbol
]: `set [${symbol.description}]`,
216 it("[[Construct]] creates a new object with correct getter behaviour", () => {
217 const ll
= new LazyLoader(methodsObject
);
220 Object
.getOwnPropertyDescriptor(ll
, "etaoin"),
228 assertSpyCalls(etaoinMethod
, 1);
229 assertSpyCall(etaoinMethod
, 0, {
236 Object
.getOwnPropertyDescriptor(ll
, "shrdlu"),
244 assertSpyCalls(shrdluMethod
, 1);
245 assertSpyCall(shrdluMethod
, 0, {
252 Object
.getOwnPropertyDescriptor(ll
, "cmfwyp"),
260 assertSpyCalls(cmfwypMethod
, 1);
261 assertSpyCall(cmfwypMethod
, 0, {
268 Object
.getOwnPropertyDescriptor(ll
, "vbgkqj"),
276 assertSpyCalls(vbgkqjMethod
, 1);
277 assertSpyCall(vbgkqjMethod
, 0, {
282 assertThrows(() => ll
.xz
fiflffffi);
283 assertThrows(() => ll
[symbol
]);
286 it("[[Construct]] creates a new object with correct setter behaviour", () => {
287 const ll
= new LazyLoader(methodsObject
);
288 ll
[symbol
] = "success";
290 Object
.getOwnPropertyDescriptor(ll
, symbol
),
300 describe(".length", () => {
301 it("[[Get]] returns the correct length", () => {
302 assertStrictEquals(LazyLoader
.length
, 1);
306 describe(".name", () => {
307 it("[[Get]] returns the correct name", () => {
308 assertStrictEquals(LazyLoader
.name
, "LazyLoader");
313 describe("PropertyDescriptor", () => {
314 it("[[Call]] throws an error", () => {
315 assertThrows(() => PropertyDescriptor({}));
318 it("[[Construct]] creates a new PropertyDescriptor", () => {
320 Object
.getPrototypeOf(new PropertyDescriptor({})),
321 PropertyDescriptor
.prototype,
325 it("[[Construct]] throws for primitives", () => {
326 assertThrows(() => new PropertyDescriptor("failure"));
329 describe(".length", () => {
330 it("[[Get]] returns the correct length", () => {
331 assertStrictEquals(PropertyDescriptor
.length
, 1);
335 describe(".name", () => {
336 it("[[Get]] returns the correct name", () => {
338 PropertyDescriptor
.name
,
339 "PropertyDescriptor",
344 describe("::complete", () => {
345 it("[[Call]] completes a generic descriptor", () => {
347 PropertyDescriptor
.prototype.complete
.call(desc
);
356 it("[[Call]] completes a data descriptor", () => {
357 const desc
= { value
: undefined };
358 PropertyDescriptor
.prototype.complete
.call(desc
);
367 it("[[Call]] completes an accessor descriptor", () => {
368 const desc
= { get: undefined };
369 PropertyDescriptor
.prototype.complete
.call(desc
);
378 describe(".length", () => {
379 it("[[Get]] returns the correct length", () => {
381 PropertyDescriptor
.prototype.complete
.length
,
387 describe(".name", () => {
388 it("[[Get]] returns the correct name", () => {
390 PropertyDescriptor
.prototype.complete
.name
,
397 describe("::isAccessorDescriptor", () => {
398 it("[[Get]] returns false for a generic descriptor", () => {
401 PropertyDescriptor
.prototype,
402 "isAccessorDescriptor",
409 it("[[Get]] returns false for a data descriptor", () => {
412 PropertyDescriptor
.prototype,
413 "isAccessorDescriptor",
414 { value
: undefined },
420 it("[[Get]] returns true for an accessor descriptor", () => {
423 PropertyDescriptor
.prototype,
424 "isAccessorDescriptor",
431 describe("[[GetOwnProperty]].get.length", () => {
432 it("[[Get]] returns the correct length", () => {
434 Object
.getOwnPropertyDescriptor(
435 PropertyDescriptor
.prototype,
436 "isAccessorDescriptor",
443 describe("[[GetOwnProperty]].get.name", () => {
444 it("[[Get]] returns the correct name", () => {
446 Object
.getOwnPropertyDescriptor(
447 PropertyDescriptor
.prototype,
448 "isAccessorDescriptor",
450 "get isAccessorDescriptor",
456 describe("::isDataDescriptor", () => {
457 it("[[Get]] returns false for a generic descriptor", () => {
460 PropertyDescriptor
.prototype,
468 it("[[Get]] returns true for a data descriptor", () => {
471 PropertyDescriptor
.prototype,
473 { value
: undefined },
479 it("[[Get]] returns false for an accessor descriptor", () => {
482 PropertyDescriptor
.prototype,
490 describe("[[GetOwnProperty]].get.length", () => {
491 it("[[Get]] returns the correct length", () => {
493 Object
.getOwnPropertyDescriptor(
494 PropertyDescriptor
.prototype,
502 describe("[[GetOwnProperty]].get.name", () => {
503 it("[[Get]] returns the correct name", () => {
505 Object
.getOwnPropertyDescriptor(
506 PropertyDescriptor
.prototype,
509 "get isDataDescriptor",
515 describe("::isFullyPopulated", () => {
516 it("[[Get]] returns false for a generic descriptor", () => {
519 PropertyDescriptor
.prototype,
527 it("[[Get]] returns false for a non‐fully‐populated data descriptor", () => {
530 PropertyDescriptor
.prototype,
532 { value
: undefined },
538 it("[[Get]] returns true for a fully‐populated data descriptor", () => {
540 Reflect
.get(PropertyDescriptor
.prototype, "isFullyPopulated", {
550 it("[[Get]] returns false for a non‐fully‐populated accessor descriptor", () => {
553 PropertyDescriptor
.prototype,
561 it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
563 Reflect
.get(PropertyDescriptor
.prototype, "isFullyPopulated", {
573 describe("[[GetOwnProperty]].get.length", () => {
574 it("[[Get]] returns the correct length", () => {
576 Object
.getOwnPropertyDescriptor(
577 PropertyDescriptor
.prototype,
585 describe("[[GetOwnProperty]].get.name", () => {
586 it("[[Get]] returns the correct name", () => {
588 Object
.getOwnPropertyDescriptor(
589 PropertyDescriptor
.prototype,
592 "get isFullyPopulated",
598 describe("::isGenericDescriptor", () => {
599 it("[[Get]] returns true for a generic descriptor", () => {
602 PropertyDescriptor
.prototype,
603 "isGenericDescriptor",
610 it("[[Get]] returns true for a data descriptor", () => {
613 PropertyDescriptor
.prototype,
614 "isGenericDescriptor",
615 { value
: undefined },
621 it("[[Get]] returns false for an accessor descriptor", () => {
624 PropertyDescriptor
.prototype,
625 "isGenericDescriptor",
632 describe("[[GetOwnProperty]].get.length", () => {
633 it("[[Get]] returns the correct length", () => {
635 Object
.getOwnPropertyDescriptor(
636 PropertyDescriptor
.prototype,
637 "isGenericDescriptor",
644 describe("[[GetOwnProperty]].get.name", () => {
645 it("[[Get]] returns the correct name", () => {
647 Object
.getOwnPropertyDescriptor(
648 PropertyDescriptor
.prototype,
649 "isGenericDescriptor",
651 "get isGenericDescriptor",
657 describe("~configurable", () => {
658 it("[[DefineOwnProperty]] coerces to a boolean", () => {
659 const desc
= new PropertyDescriptor({});
660 Object
.defineProperty(desc
, "configurable", {});
661 assertStrictEquals(desc
.configurable
, false);
664 it("[[DefineOwnProperty]] throws for accessor properties", () => {
665 const desc
= new PropertyDescriptor({});
667 Object
.defineProperty(desc
, "configurable", { get: undefined })
671 it("[[Set]] coerces to a boolean", () => {
672 const desc
= new PropertyDescriptor({});
673 desc
.configurable
= undefined;
674 assertStrictEquals(desc
.configurable
, false);
677 it("[[Delete]] works", () => {
678 const desc
= new PropertyDescriptor({ configurable
: false });
679 delete desc
.configurable
;
680 assert(!("configurable" in desc
));
684 describe("~enumerable", () => {
685 it("[[DefineOwnProperty]] coerces to a boolean", () => {
686 const desc
= new PropertyDescriptor({});
687 Object
.defineProperty(desc
, "enumerable", {});
688 assertStrictEquals(desc
.enumerable
, false);
691 it("[[DefineOwnProperty]] throws for accessor properties", () => {
692 const desc
= new PropertyDescriptor({});
694 Object
.defineProperty(desc
, "enumerable", { get: undefined })
698 it("[[Set]] coerces to a boolean", () => {
699 const desc
= new PropertyDescriptor({});
700 desc
.enumerable
= undefined;
701 assertStrictEquals(desc
.enumerable
, false);
704 it("[[Delete]] works", () => {
705 const desc
= new PropertyDescriptor({ enumerable
: false });
706 delete desc
.enumerable
;
707 assert(!("enumerable" in desc
));
711 describe("~get", () => {
712 it("[[DefineOwnProperty]] works", () => {
713 const desc
= new PropertyDescriptor({});
714 Object
.defineProperty(desc
, "get", {});
715 assertStrictEquals(desc
.get, undefined);
718 it("[[DefineOwnProperty]] throws for accessor properties", () => {
719 const desc
= new PropertyDescriptor({});
721 Object
.defineProperty(desc
, "get", { get: undefined })
725 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
726 const desc
= new PropertyDescriptor({});
728 () => Object
.defineProperty(desc
, "get", { value
: null }),
732 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
733 const desc
= new PropertyDescriptor({ value
: undefined });
734 assertThrows(() => Object
.defineProperty(desc
, "get", {}));
737 it("[[Set]] works", () => {
738 const desc
= new PropertyDescriptor({});
741 assertStrictEquals(desc
.get, fn
);
744 it("[[Set]] throws if not callable or undefined", () => {
745 const desc
= new PropertyDescriptor({});
746 assertThrows(() => desc
.get = null);
749 it("[[Set]] throws if a data property is defined", () => {
750 const desc
= new PropertyDescriptor({ value
: undefined });
751 assertThrows(() => desc
.get = undefined);
754 it("[[Delete]] works", () => {
755 const desc
= new PropertyDescriptor({ get: undefined });
757 assert(!("get" in desc
));
761 describe("~set", () => {
762 it("[[DefineOwnProperty]] works", () => {
763 const desc
= new PropertyDescriptor({});
764 Object
.defineProperty(desc
, "set", {});
765 assertStrictEquals(desc
.set, undefined);
768 it("[[DefineOwnProperty]] throws for accessor properties", () => {
769 const desc
= new PropertyDescriptor({});
771 Object
.defineProperty(desc
, "set", { get: undefined })
775 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
776 const desc
= new PropertyDescriptor({});
778 () => Object
.defineProperty(desc
, "set", { value
: null }),
782 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
783 const desc
= new PropertyDescriptor({ value
: undefined });
784 assertThrows(() => Object
.defineProperty(desc
, "set", {}));
787 it("[[Set]] works", () => {
788 const desc
= new PropertyDescriptor({});
789 const fn
= (_
) => {};
791 assertStrictEquals(desc
.set, fn
);
794 it("[[Set]] throws if not callable or undefined", () => {
795 const desc
= new PropertyDescriptor({});
796 assertThrows(() => desc
.set = null);
799 it("[[Set]] throws if a data property is defined", () => {
800 const desc
= new PropertyDescriptor({ value
: undefined });
801 assertThrows(() => desc
.set = undefined);
804 it("[[Delete]] works", () => {
805 const desc
= new PropertyDescriptor({ set: undefined });
807 assert(!("set" in desc
));
811 describe("~value", () => {
812 it("[[DefineOwnProperty]] works", () => {
813 const desc
= new PropertyDescriptor({});
814 Object
.defineProperty(desc
, "value", {});
815 assertStrictEquals(desc
.value
, undefined);
818 it("[[DefineOwnProperty]] throws for accessor properties", () => {
819 const desc
= new PropertyDescriptor({});
821 Object
.defineProperty(desc
, "value", { get: undefined })
825 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
826 const desc
= new PropertyDescriptor({ get: undefined });
827 assertThrows(() => Object
.defineProperty(desc
, "value", {}));
830 it("[[Set]] works", () => {
831 const desc
= new PropertyDescriptor({});
832 desc
.value
= "success";
833 assertStrictEquals(desc
.value
, "success");
836 it("[[Set]] throws if an accessor property is defined", () => {
837 const desc
= new PropertyDescriptor({ get: undefined });
838 assertThrows(() => desc
.value
= null);
841 it("[[Delete]] works", () => {
842 const desc
= new PropertyDescriptor({ value
: undefined });
844 assert(!("value" in desc
));
848 describe("~writable", () => {
849 it("[[DefineOwnProperty]] coerces to a boolean", () => {
850 const desc
= new PropertyDescriptor({});
851 Object
.defineProperty(desc
, "writable", {});
852 assertStrictEquals(desc
.writable
, false);
855 it("[[DefineOwnProperty]] throws for accessor properties", () => {
856 const desc
= new PropertyDescriptor({});
858 Object
.defineProperty(desc
, "writable", { get: undefined })
862 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
863 const desc
= new PropertyDescriptor({ get: undefined });
864 assertThrows(() => Object
.defineProperty(desc
, "writable", {}));
867 it("[[Set]] coerces to a boolean", () => {
868 const desc
= new PropertyDescriptor({});
869 desc
.writable
= undefined;
870 assertStrictEquals(desc
.writable
, false);
873 it("[[Set]] throws if an accessor property is defined", () => {
874 const desc
= new PropertyDescriptor({ get: undefined });
875 assertThrows(() => desc
.writable
= false);
878 it("[[Delete]] works", () => {
879 const desc
= new PropertyDescriptor({ writable
: false });
880 delete desc
.writable
;
881 assert(!("writable" in desc
));
886 describe("defineOwnProperty", () => {
887 it("[[Call]] defines the property", () => {
889 defineOwnProperty(obj
, "etaoin", {});
890 assert("etaoin" in obj
);
893 it("[[Call]] returns the provided object", () => {
895 assertStrictEquals(defineOwnProperty(obj
, "etaoin", {}), obj
);
898 it("[[Construct]] throws an error", () => {
899 assertThrows(() => new defineOwnProperty(obj
, "etaoin", {}));
902 describe(".length", () => {
903 it("[[Get]] returns the correct length", () => {
904 assertStrictEquals(defineOwnProperty
.length
, 3);
908 describe(".name", () => {
909 it("[[Get]] returns the correct name", () => {
911 defineOwnProperty
.name
,
918 describe("defineOwnProperties", () => {
919 it("[[Call]] defines properties from the provided objects", () => {
921 defineOwnProperties(obj
, {
925 assert("etaoin" in obj
);
926 assert("shrdlu" in obj
);
927 assert("cmfwyp" in obj
);
930 it("[[Call]] overrides earlier declarations with later ones", () => {
931 const obj
= { etaoin
: undefined };
932 defineOwnProperties(obj
, {
933 etaoin
: { value
: "failure" },
935 etaoin
: { value
: "success" },
937 assertStrictEquals(obj
.etaoin
, "success");
940 it("[[Call]] returns the provided object", () => {
942 assertStrictEquals(defineOwnProperties(obj
), obj
);
945 it("[[Construct]] throws an error", () => {
946 assertThrows(() => new defineOwnProperties({}));
949 describe(".length", () => {
950 it("[[Get]] returns the correct length", () => {
951 assertStrictEquals(defineOwnProperties
.length
, 1);
955 describe(".name", () => {
956 it("[[Get]] returns the correct name", () => {
958 defineOwnProperties
.name
,
959 "defineOwnProperties",
965 describe("deleteOwnProperty", () => {
966 it("[[Call]] deletes the provided property on the provided object", () => {
967 const obj
= { failure
: undefined };
968 deleteOwnProperty(obj
, "failure");
969 assert(!("failure" in obj
));
972 it("[[Call]] does nothing if the property doesn’t exist", () => {
973 const obj
= Object
.freeze({});
974 deleteOwnProperty(obj
, "failure");
975 assert(!("failure" in obj
));
978 it("[[Call]] throws if the property can’t be deleted", () => {
979 const obj
= Object
.seal({ failure
: undefined });
980 assertThrows(() => deleteOwnProperty(obj
, "failure"));
983 it("[[Call]] returns the provided object", () => {
985 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
988 it("[[Construct]] throws an error", () => {
989 assertThrows(() => new deleteOwnProperty({}, ""));
992 describe(".length", () => {
993 it("[[Get]] returns the correct length", () => {
994 assertStrictEquals(deleteOwnProperty
.length
, 2);
998 describe(".name", () => {
999 it("[[Get]] returns the correct name", () => {
1000 assertStrictEquals(deleteOwnProperty
.name
, "deleteOwnProperty");
1005 describe("freeze", () => {
1006 it("[[Call]] freezes the object", () => {
1009 assert(Object
.isFrozen(obj
));
1012 it("[[Call]] returns the provided object", () => {
1014 assertStrictEquals(freeze(obj
), obj
);
1017 it("[[Construct]] throws an error", () => {
1018 assertThrows(() => new freeze({}));
1021 describe(".length", () => {
1022 it("[[Get]] returns the correct length", () => {
1023 assertStrictEquals(freeze
.length
, 1);
1027 describe(".name", () => {
1028 it("[[Get]] returns the correct name", () => {
1029 assertStrictEquals(freeze
.name
, "freeze");
1034 describe("frozenCopy", () => {
1035 it("[[Call]] returns a frozen object", () => {
1038 frozenCopy(Object
.create(null), {
1055 it("[[Call]] ignores non·enumerable properties", () => {
1058 Object
.create(null, {
1059 data
: { value
: undefined },
1060 accessor
: { get: undefined },
1067 it("[[Call]] preserves accessor properties", () => {
1068 const properties
= {
1070 configurable
: false,
1076 configurable
: false,
1082 configurable
: false,
1088 configurable
: false,
1095 Object
.getOwnPropertyDescriptors(
1096 frozenCopy(Object
.create(null, properties
)),
1102 it("[[Call]] does not copy properties on the prototype", () => {
1105 frozenCopy(Object
.create({ failure
: undefined }), {
1111 accessor
: { configurable
: true, get: undefined },
1116 it("[[Call]] uses the species of the constructor", () => {
1117 const species
= { prototype: {} };
1119 Object
.getPrototypeOf(
1120 frozenCopy({}, { [Symbol
.species
]: species
}),
1126 it("[[Call]] uses constructor if no species is defined", () => {
1127 const constructor = { [Symbol
.species
]: null, prototype: {} };
1129 Object
.getPrototypeOf(frozenCopy({}, constructor)),
1130 constructor.prototype,
1134 it("[[Call]] uses the constructor on the object if none is provided", () => {
1135 const constructor = { [Symbol
.species
]: null, prototype: {} };
1137 Object
.getPrototypeOf(frozenCopy({ constructor })),
1138 constructor.prototype,
1142 it("[[Call]] allows a null constructor", () => {
1144 Object
.getPrototypeOf(frozenCopy({}, null)),
1149 it("[[Construct]] throws an error", () => {
1150 assertThrows(() => new frozenCopy({}));
1153 describe(".length", () => {
1154 it("[[Get]] returns the correct length", () => {
1155 assertStrictEquals(frozenCopy
.length
, 1);
1159 describe(".name", () => {
1160 it("[[Get]] returns the correct name", () => {
1161 assertStrictEquals(frozenCopy
.name
, "frozenCopy");
1166 describe("getMethod", () => {
1167 it("[[Call]] gets a method", () => {
1168 const method
= () => {};
1169 assertStrictEquals(getMethod({ method
}, "method"), method
);
1172 it("[[Call]] works for values coercible to objects", () => {
1173 assertEquals(getMethod("", "toString"), String
.prototype.toString
);
1176 it("[[Call]] throws for null and undefined", () => {
1177 assertThrows(() => getMethod(null, "valueOf"));
1178 assertThrows(() => getMethod(undefined, "valueOf"));
1181 it("[[Call]] throws if the resulting value isn’t callable", () => {
1182 assertThrows(() => getMethod({ "failure": true }, "failure"));
1185 it("[[Construct]] throws an error", () => {
1186 assertThrows(() => new getMethod({ method() {} }, "method"));
1189 describe(".length", () => {
1190 it("[[Get]] returns the correct length", () => {
1191 assertStrictEquals(getMethod
.length
, 2);
1195 describe(".name", () => {
1196 it("[[Get]] returns the correct name", () => {
1197 assertStrictEquals(getMethod
.name
, "getMethod");
1202 describe("getOwnPropertyDescriptor", () => {
1203 it("[[Call]] gets the descriptor", () => {
1205 getOwnPropertyDescriptor({ success
: true }, "success"),
1215 it("[[Call]] returns undefined for non‐own properties", () => {
1217 getOwnPropertyDescriptor({}, "valueOf"),
1222 it("[[Construct]] throws an error", () => {
1223 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
1226 describe(".length", () => {
1227 it("[[Get]] returns the correct length", () => {
1228 assertStrictEquals(getOwnPropertyDescriptor
.length
, 2);
1232 describe(".name", () => {
1233 it("[[Get]] returns the correct name", () => {
1235 getOwnPropertyDescriptor
.name
,
1236 "getOwnPropertyDescriptor",
1242 describe("getOwnPropertyDescriptors", () => {
1243 it("[[Call]] gets the descriptors", () => {
1245 getOwnPropertyDescriptors({ success
: true, etaoin
: "shrdlu" }),
1263 it("[[Construct]] throws an error", () => {
1264 assertThrows(() => new getOwnPropertyDescriptors({}));
1267 describe(".length", () => {
1268 it("[[Get]] returns the correct length", () => {
1269 assertStrictEquals(getOwnPropertyDescriptors
.length
, 1);
1273 describe(".name", () => {
1274 it("[[Get]] returns the correct name", () => {
1276 getOwnPropertyDescriptors
.name
,
1277 "getOwnPropertyDescriptors",
1283 describe("getOwnPropertyKeys", () => {
1284 it("[[Call]] gets own (but not inherited) property keys", () => {
1285 assertEquals(getOwnPropertyKeys({ success
: true }), ["success"]);
1288 it("[[Call]] works for values coercible to objects", () => {
1289 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
1292 it("[[Call]] throws for null and undefined", () => {
1293 assertThrows(() => getOwnPropertyKeys(null));
1294 assertThrows(() => getOwnPropertyKeys(undefined));
1297 it("[[Construct]] throws an error", () => {
1298 assertThrows(() => new getOwnPropertyKeys({}));
1301 describe(".length", () => {
1302 it("[[Get]] returns the correct length", () => {
1303 assertStrictEquals(getOwnPropertyKeys
.length
, 1);
1307 describe(".name", () => {
1308 it("[[Get]] returns the correct name", () => {
1310 getOwnPropertyKeys
.name
,
1311 "getOwnPropertyKeys",
1317 describe("getOwnPropertyStrings", () => {
1318 it("[[Call]] gets own string keys", () => {
1319 assertEquals(getOwnPropertyStrings({ success
: true }), [
1324 it("[[Call]] works for values coercible to objects", () => {
1325 assertEquals(getOwnPropertyStrings("foo"), [
1333 it("[[Call]] throws for null and undefined", () => {
1334 assertThrows(() => getOwnPropertyStrings(null));
1335 assertThrows(() => getOwnPropertyStrings(undefined));
1338 it("[[Construct]] throws an error", () => {
1339 assertThrows(() => new getOwnPropertyStrings({}));
1342 describe(".length", () => {
1343 it("[[Get]] returns the correct length", () => {
1344 assertStrictEquals(getOwnPropertyStrings
.length
, 1);
1348 describe(".name", () => {
1349 it("[[Get]] returns the correct name", () => {
1351 getOwnPropertyStrings
.name
,
1352 "getOwnPropertyStrings",
1358 describe("getOwnPropertySymbols", () => {
1359 it("[[Call]] gets own symbol keys", () => {
1360 const sym
= Symbol();
1361 assertEquals(getOwnPropertySymbols({ [sym
]: true }), [sym
]);
1364 it("[[Call]] works for values coercible to objects", () => {
1365 assertEquals(getOwnPropertySymbols("foo"), []);
1368 it("[[Call]] throws for null and undefined", () => {
1369 assertThrows(() => getOwnPropertySymbols(null));
1370 assertThrows(() => getOwnPropertySymbols(undefined));
1373 it("[[Construct]] throws an error", () => {
1374 assertThrows(() => new getOwnPropertySymbols({}));
1377 describe(".length", () => {
1378 it("[[Get]] returns the correct length", () => {
1379 assertStrictEquals(getOwnPropertySymbols
.length
, 1);
1383 describe(".name", () => {
1384 it("[[Get]] returns the correct name", () => {
1386 getOwnPropertySymbols
.name
,
1387 "getOwnPropertySymbols",
1393 describe("getPropertyValue", () => {
1394 it("[[Call]] gets property values on the provided object", () => {
1396 getPropertyValue({ success
: true }, "success"),
1401 it("[[Call]] works for values coercible to objects", () => {
1403 getPropertyValue("", "toString"),
1404 String
.prototype.toString
,
1408 it("[[Call]] throws for null and undefined", () => {
1409 assertThrows(() => getPropertyValue(null, "valueOf"));
1410 assertThrows(() => getPropertyValue(undefined, "valueOf"));
1413 it("[[Construct]] throws an error", () => {
1414 assertThrows(() => new getPropertyValue({}, "valueOf"));
1417 describe(".length", () => {
1418 it("[[Get]] returns the correct length", () => {
1419 assertStrictEquals(getPropertyValue
.length
, 2);
1423 describe(".name", () => {
1424 it("[[Get]] returns the correct name", () => {
1425 assertStrictEquals(getPropertyValue
.name
, "getPropertyValue");
1430 describe("getPrototype", () => {
1431 it("[[Call]] gets object prototypes", () => {
1432 assertStrictEquals(getPrototype({}), Object
.prototype);
1434 assertStrictEquals(getPrototype(Object
.create(proto
)), proto
);
1437 it("[[Call]] gets null prototypes", () => {
1438 assertStrictEquals(getPrototype(Object
.create(null)), null);
1441 it("[[Call]] gets prototypes for coercible primitives", () => {
1442 assertStrictEquals(getPrototype(1), Number
.prototype);
1443 assertStrictEquals(getPrototype(Symbol()), Symbol
.prototype);
1446 it("[[Call]] throws for null and undefined", () => {
1447 assertThrows(() => getPrototype(null));
1448 assertThrows(() => getPrototype(undefined));
1451 it("[[Construct]] throws an error", () => {
1452 assertThrows(() => new getPrototype({}));
1455 describe(".length", () => {
1456 it("[[Get]] returns the correct length", () => {
1457 assertStrictEquals(getPrototype
.length
, 1);
1461 describe(".name", () => {
1462 it("[[Get]] returns the correct name", () => {
1463 assertStrictEquals(getPrototype
.name
, "getPrototype");
1468 describe("hasProperty", () => {
1469 it("[[Call]] gets whether a property exists on the provided object", () => {
1471 hasProperty({ success
: "etaoin" }, "success"),
1474 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
1477 it("[[Call]] works for values coercible to objects", () => {
1478 assertStrictEquals(hasProperty("", "length"), true);
1479 assertStrictEquals(hasProperty("", "toString"), true);
1482 it("[[Call]] throws for null and undefined", () => {
1483 assertThrows(() => hasProperty(null, "valueOf"));
1484 assertThrows(() => hasProperty(undefined, "valueOf"));
1487 it("[[Construct]] throws an error", () => {
1488 assertThrows(() => new hasProperty({}, "valueOf"));
1491 describe(".length", () => {
1492 it("[[Get]] returns the correct length", () => {
1493 assertStrictEquals(hasProperty
.length
, 2);
1497 describe(".name", () => {
1498 it("[[Get]] returns the correct name", () => {
1499 assertStrictEquals(hasProperty
.name
, "hasProperty");
1504 describe("hasOwnProperty", () => {
1505 it("[[Call]] gets whether an own property exists on the provided object", () => {
1507 hasOwnProperty({ success
: "etaoin" }, "success"),
1510 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
1513 it("[[Call]] works for values coercible to objects", () => {
1514 assertStrictEquals(hasOwnProperty("", "length"), true);
1515 assertStrictEquals(hasOwnProperty("", "toString"), false);
1518 it("[[Call]] throws for null and undefined", () => {
1519 assertThrows(() => hasOwnProperty(null, "valueOf"));
1520 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
1523 it("[[Construct]] throws an error", () => {
1524 assertThrows(() => new hasOwnProperty({}, "valueOf"));
1527 describe(".length", () => {
1528 it("[[Get]] returns the correct length", () => {
1529 assertStrictEquals(hasOwnProperty
.length
, 2);
1533 describe(".name", () => {
1534 it("[[Get]] returns the correct name", () => {
1535 assertStrictEquals(hasOwnProperty
.name
, "hasOwnProperty");
1540 describe("isArraylikeObject", () => {
1541 it("[[Call]] returns false for primitives", () => {
1542 assertStrictEquals(isArraylikeObject("failure"), false);
1545 it("[[Call]] returns false if length throws", () => {
1556 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
1557 assertStrictEquals(isArraylikeObject({ length
: 1n
}), false);
1560 it("[[Call]] returns true if length is convertable to a number", () => {
1561 assertStrictEquals(isArraylikeObject({ length
: -0 }), true);
1562 assertStrictEquals(isArraylikeObject({ length
: 1 }), true);
1563 assertStrictEquals(isArraylikeObject({ length
: -1.25 }), true);
1565 isArraylikeObject({ length
: 9007199254740992 }),
1568 assertStrictEquals(isArraylikeObject({ length
: Infinity
}), true);
1569 assertStrictEquals(isArraylikeObject({ length
: "success" }), true);
1572 it("[[Construct]] throws an error", () => {
1573 assertThrows(() => new isArraylikeObject({}));
1576 describe(".length", () => {
1577 it("[[Get]] returns the correct length", () => {
1578 assertStrictEquals(isArraylikeObject
.length
, 1);
1582 describe(".name", () => {
1583 it("[[Get]] returns the correct name", () => {
1585 isArraylikeObject
.name
,
1586 "isArraylikeObject",
1592 describe("isConcatSpreadableObject", () => {
1593 it("[[Call]] returns false for primitives", () => {
1594 assertStrictEquals(isConcatSpreadableObject("failure"), false);
1597 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
1599 isConcatSpreadableObject(
1600 Object
.assign([], { [Symbol
.isConcatSpreadable
]: null }),
1605 isConcatSpreadableObject(
1606 Object
.assign([], { [Symbol
.isConcatSpreadable
]: false }),
1612 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
1614 isConcatSpreadableObject(
1615 Object
.assign([], { [Symbol
.isConcatSpreadable
]: undefined }),
1621 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
1623 isConcatSpreadableObject({ [Symbol
.isConcatSpreadable
]: true }),
1628 it("[[Construct]] throws an error", () => {
1629 assertThrows(() => new isConcatSpreadableObject({}));
1632 describe(".length", () => {
1633 it("[[Get]] returns the correct length", () => {
1634 assertStrictEquals(isConcatSpreadableObject
.length
, 1);
1638 describe(".name", () => {
1639 it("[[Get]] returns the correct name", () => {
1641 isConcatSpreadableObject
.name
,
1642 "isConcatSpreadableObject",
1648 describe("isExtensibleObject", () => {
1649 it("[[Call]] returns true for extensible objects", () => {
1650 assertStrictEquals(isExtensibleObject({}), true);
1653 it("[[Call]] returns false for coercible primitives", () => {
1654 assertStrictEquals(isExtensibleObject(1), false);
1655 assertStrictEquals(isExtensibleObject(Symbol()), false);
1658 it("[[Call]] returns false for non·extensible objects", () => {
1660 isExtensibleObject(Object
.preventExtensions({})),
1665 it("[[Call]] returns false for null and undefined", () => {
1666 assertStrictEquals(isExtensibleObject(null), false);
1667 assertStrictEquals(isExtensibleObject(undefined), false);
1670 it("[[Construct]] throws an error", () => {
1671 assertThrows(() => new isExtensibleObject({}));
1674 describe(".length", () => {
1675 it("[[Get]] returns the correct length", () => {
1676 assertStrictEquals(isExtensibleObject
.length
, 1);
1680 describe(".name", () => {
1681 it("[[Get]] returns the correct name", () => {
1683 isExtensibleObject
.name
,
1684 "isExtensibleObject",
1690 describe("isUnfrozenObject", () => {
1691 it("[[Call]] returns true for unfrozen objects", () => {
1692 assertStrictEquals(isUnfrozenObject({}), true);
1695 it("[[Call]] returns false for coercible primitives", () => {
1696 assertStrictEquals(isUnfrozenObject(1), false);
1697 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1700 it("[[Call]] returns false for frozen objects", () => {
1701 assertStrictEquals(isUnfrozenObject(Object
.freeze({})), false);
1704 it("[[Call]] returns false for null and undefined", () => {
1705 assertStrictEquals(isUnfrozenObject(null), false);
1706 assertStrictEquals(isUnfrozenObject(undefined), false);
1709 it("[[Construct]] throws an error", () => {
1710 assertThrows(() => new isUnfrozenObject({}));
1713 describe(".length", () => {
1714 it("[[Get]] returns the correct length", () => {
1715 assertStrictEquals(isUnfrozenObject
.length
, 1);
1719 describe(".name", () => {
1720 it("[[Get]] returns the correct name", () => {
1721 assertStrictEquals(isUnfrozenObject
.name
, "isUnfrozenObject");
1726 describe("isUnsealedObject", () => {
1727 it("[[Call]] returns true for unsealed objects", () => {
1728 assertStrictEquals(isUnsealedObject({}), true);
1731 it("[[Call]] returns false for coercible primitives", () => {
1732 assertStrictEquals(isUnsealedObject(1), false);
1733 assertStrictEquals(isUnsealedObject(Symbol()), false);
1736 it("[[Call]] returns false for sealed objects", () => {
1737 assertStrictEquals(isUnsealedObject(Object
.seal({})), false);
1740 it("[[Call]] returns false for null and undefined", () => {
1741 assertStrictEquals(isUnsealedObject(null), false);
1742 assertStrictEquals(isUnsealedObject(undefined), false);
1745 it("[[Construct]] throws an error", () => {
1746 assertThrows(() => new isUnsealedObject({}));
1749 describe(".length", () => {
1750 it("[[Get]] returns the correct length", () => {
1751 assertStrictEquals(isUnsealedObject
.length
, 1);
1755 describe(".name", () => {
1756 it("[[Get]] returns the correct name", () => {
1757 assertStrictEquals(isUnsealedObject
.name
, "isUnsealedObject");
1762 describe("lengthOfArraylike", () => {
1763 it("[[Call]] returns the length", () => {
1765 lengthOfArraylike({ length
: 9007199254740991 }),
1770 it("[[Call]] returns a non·nan result", () => {
1771 assertStrictEquals(lengthOfArraylike({ length
: NaN
}), 0);
1772 assertStrictEquals(lengthOfArraylike({ length
: "failure" }), 0);
1775 it("[[Call]] returns an integral result", () => {
1776 assertStrictEquals(lengthOfArraylike({ length
: 0.25 }), 0);
1777 assertStrictEquals(lengthOfArraylike({ length
: 1.1 }), 1);
1780 it("[[Call]] returns a result greater than or equal to zero", () => {
1781 assertStrictEquals(lengthOfArraylike({ length
: -0 }), 0);
1782 assertStrictEquals(lengthOfArraylike({ length
: -1 }), 0);
1783 assertStrictEquals(lengthOfArraylike({ length
: -Infinity
}), 0);
1786 it("[[Call]] returns a result less than 2 ** 53", () => {
1788 lengthOfArraylike({ length
: 9007199254740992 }),
1792 lengthOfArraylike({ length
: Infinity
}),
1797 it("[[Call]] does not require an object argument", () => {
1798 assertStrictEquals(lengthOfArraylike("string"), 6);
1799 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1802 it("[[Construct]] throws an error", () => {
1803 assertThrows(() => new lengthOfArraylike(""));
1806 describe(".length", () => {
1807 it("[[Get]] returns the correct length", () => {
1808 assertStrictEquals(lengthOfArraylike
.length
, 1);
1812 describe(".name", () => {
1813 it("[[Get]] returns the correct name", () => {
1814 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
1819 describe("namedEntries", () => {
1820 it("[[Call]] gets named entries", () => {
1821 assertEquals(namedEntries({ success
: true }), [["success", true]]);
1824 it("[[Call]] works for values coercible to objects", () => {
1825 assertEquals(namedEntries("foo"), [
1832 it("[[Call]] throws for null and undefined", () => {
1833 assertThrows(() => namedEntries(null));
1834 assertThrows(() => namedEntries(undefined));
1837 it("[[Construct]] throws an error", () => {
1838 assertThrows(() => new namedEntries({}));
1841 describe(".length", () => {
1842 it("[[Get]] returns the correct length", () => {
1843 assertStrictEquals(namedEntries
.length
, 1);
1847 describe(".name", () => {
1848 it("[[Get]] returns the correct name", () => {
1849 assertStrictEquals(namedEntries
.name
, "namedEntries");
1854 describe("namedKeys", () => {
1855 it("[[Call]] gets named keys", () => {
1856 assertEquals(namedKeys({ success
: true }), ["success"]);
1859 it("[[Call]] works for values coercible to objects", () => {
1860 assertEquals(namedKeys("foo"), [
1867 it("[[Call]] throws for null and undefined", () => {
1868 assertThrows(() => namedKeys(null));
1869 assertThrows(() => namedKeys(undefined));
1872 it("[[Construct]] throws an error", () => {
1873 assertThrows(() => new namedKeys({}));
1876 describe(".length", () => {
1877 it("[[Get]] returns the correct length", () => {
1878 assertStrictEquals(namedKeys
.length
, 1);
1882 describe(".name", () => {
1883 it("[[Get]] returns the correct name", () => {
1884 assertStrictEquals(namedKeys
.name
, "namedKeys");
1889 describe("namedValues", () => {
1890 it("[[Call]] gets named values", () => {
1891 assertEquals(namedValues({ success
: true }), [true]);
1894 it("[[Call]] works for values coercible to objects", () => {
1895 assertEquals(namedValues("foo"), [
1902 it("[[Call]] throws for null and undefined", () => {
1903 assertThrows(() => namedValues(null));
1904 assertThrows(() => namedValues(undefined));
1907 it("[[Construct]] throws an error", () => {
1908 assertThrows(() => new namedValues({}));
1911 describe(".length", () => {
1912 it("[[Get]] returns the correct length", () => {
1913 assertStrictEquals(namedValues
.length
, 1);
1917 describe(".name", () => {
1918 it("[[Get]] returns the correct name", () => {
1919 assertStrictEquals(namedValues
.name
, "namedValues");
1924 describe("objectCreate", () => {
1925 it("[[Call]] creates an object", () => {
1926 const obj
= objectCreate(null);
1927 assertStrictEquals(Object(obj
), obj
);
1930 it("[[Call]] correctly sets the prototype", () => {
1933 Object
.getPrototypeOf(objectCreate(proto
)),
1937 Object
.getPrototypeOf(objectCreate(null)),
1942 it("[[Call]] correctly sets own properties", () => {
1944 Object
.getOwnPropertyDescriptors(
1945 objectCreate(null, { success
: { value
: true } }),
1949 configurable
: false,
1958 it("[[Call]] throws for coercible primitives", () => {
1959 assertThrows(() => objectCreate(1));
1960 assertThrows(() => objectCreate(Symbol()));
1963 it("[[Call]] throws for undefined", () => {
1964 assertThrows(() => objectCreate(undefined));
1967 it("[[Construct]] throws an error", () => {
1968 assertThrows(() => new objectCreate({}));
1971 describe(".length", () => {
1972 it("[[Get]] returns the correct length", () => {
1973 assertStrictEquals(objectCreate
.length
, 2);
1977 describe(".name", () => {
1978 it("[[Get]] returns the correct name", () => {
1979 assertStrictEquals(objectCreate
.name
, "objectCreate");
1984 describe("objectFromEntries", () => {
1985 it("[[Call]] creates an object", () => {
1986 const obj
= objectFromEntries([]);
1987 assertStrictEquals(Object(obj
), obj
);
1990 it("[[Call]] correctly sets the prototype", () => {
1992 Object
.getPrototypeOf(objectFromEntries([])),
1997 it("[[Call]] correctly sets own properties", () => {
1999 Object
.entries(objectFromEntries([["success", true]])),
2000 [["success", true]],
2004 it("[[Call]] throws if the argument is not a nested arraylike", () => {
2005 assertThrows(() => objectFromEntries(1));
2006 assertThrows(() => objectFromEntries(Symbol()));
2007 assertThrows(() => objectFromEntries(null));
2008 assertThrows(() => objectFromEntries(undefined));
2009 assertThrows(() => objectFromEntries({}));
2010 assertThrows(() => objectFromEntries([undefined]));
2013 it("[[Construct]] throws an error", () => {
2014 assertThrows(() => new objectFromEntries([]));
2017 describe(".length", () => {
2018 it("[[Get]] returns the correct length", () => {
2019 assertStrictEquals(objectFromEntries
.length
, 1);
2023 describe(".name", () => {
2024 it("[[Get]] returns the correct name", () => {
2025 assertStrictEquals(objectFromEntries
.name
, "objectFromEntries");
2030 describe("preventExtensions", () => {
2031 it("[[Call]] prevents extensions on the object", () => {
2033 preventExtensions(obj
);
2034 assert(!Object
.isExtensible(obj
));
2037 it("[[Call]] returns the provided object", () => {
2039 assertStrictEquals(preventExtensions(obj
), obj
);
2042 it("[[Construct]] throws an error", () => {
2043 assertThrows(() => new preventExtensions({}));
2046 describe(".length", () => {
2047 it("[[Get]] returns the correct length", () => {
2048 assertStrictEquals(preventExtensions
.length
, 1);
2052 describe(".name", () => {
2053 it("[[Get]] returns the correct name", () => {
2054 assertStrictEquals(preventExtensions
.name
, "preventExtensions");
2059 describe("seal", () => {
2060 it("[[Call]] seals the object", () => {
2063 assert(Object
.isSealed(obj
));
2066 it("[[Call]] returns the provided object", () => {
2068 assertStrictEquals(seal(obj
), obj
);
2071 it("[[Construct]] throws an error", () => {
2072 assertThrows(() => new seal({}));
2075 describe(".length", () => {
2076 it("[[Get]] returns the correct length", () => {
2077 assertStrictEquals(seal
.length
, 1);
2081 describe(".name", () => {
2082 it("[[Get]] returns the correct name", () => {
2083 assertStrictEquals(seal
.name
, "seal");
2088 describe("setPropertyValue", () => {
2089 it("[[Call]] sets the provided property on the provided object", () => {
2091 setPropertyValue(obj
, "success", true);
2092 assertStrictEquals(obj
.success
, true);
2095 it("[[Call]] calls setters", () => {
2096 const setter
= spy((_
) => {});
2097 const obj
= Object
.create(null, { success
: { set: setter
} });
2098 setPropertyValue(obj
, "success", true);
2099 assertSpyCalls(setter
, 1);
2100 assertSpyCall(setter
, 0, {
2106 it("[[Call]] walks the prototype chain", () => {
2107 const setter
= spy((_
) => {});
2108 const obj
= Object
.create(
2109 Object
.create(null, { success
: { set: setter
} }),
2111 setPropertyValue(obj
, "success", true);
2112 assertSpyCalls(setter
, 1);
2113 assertSpyCall(setter
, 0, {
2119 it("[[Call]] uses the provided receiver", () => {
2120 const setter
= spy((_
) => {});
2121 const obj
= Object
.create(null, { success
: { set: setter
} });
2122 const receiver
= {};
2123 setPropertyValue(obj
, "success", true, receiver
);
2124 assertSpyCalls(setter
, 1);
2125 assertSpyCall(setter
, 0, {
2131 it("[[Call]] throws if the property can’t be set", () => {
2132 const obj
= Object
.freeze({ failure
: undefined });
2133 assertThrows(() => setPropertyValue(obj
, "failure", true));
2136 it("[[Call]] returns the provided object", () => {
2138 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
2141 it("[[Construct]] throws an error", () => {
2142 assertThrows(() => new setPropertyValue({}, "", undefined));
2145 describe(".length", () => {
2146 it("[[Get]] returns the correct length", () => {
2147 assertStrictEquals(setPropertyValue
.length
, 3);
2151 describe(".name", () => {
2152 it("[[Get]] returns the correct name", () => {
2153 assertStrictEquals(setPropertyValue
.name
, "setPropertyValue");
2158 describe("setPropertyValues", () => {
2159 it("[[Call]] sets the provided properties on the provided object", () => {
2161 setPropertyValues(obj
, { success
: true, all
: "good" });
2162 assertStrictEquals(obj
.success
, true);
2163 assertStrictEquals(obj
.all
, "good");
2166 it("[[Call]] can take multiple objects", () => {
2170 { success
: false, all
: "good" },
2173 assertStrictEquals(obj
.success
, true);
2174 assertStrictEquals(obj
.all
, "good");
2177 it("[[Call]] ignores nullish arguments", () => {
2179 setPropertyValues(obj
, null, undefined, { success
: true });
2180 assertStrictEquals(obj
.success
, true);
2183 it("[[Call]] calls setters", () => {
2184 const setter
= spy((_
) => {});
2185 const obj
= Object
.create(null, { success
: { set: setter
} });
2186 setPropertyValues(obj
, { success
: true });
2187 assertSpyCalls(setter
, 1);
2188 assertSpyCall(setter
, 0, {
2194 it("[[Call]] calls setters multiple times if property appears more than once", () => {
2195 const setter
= spy((_
) => {});
2196 const obj
= Object
.create(null, { success
: { set: setter
} });
2197 setPropertyValues(obj
, { success
: false }, { success
: true });
2198 assertSpyCalls(setter
, 2);
2199 assertSpyCall(setter
, 0, {
2203 assertSpyCall(setter
, 1, {
2209 it("[[Call]] walks the prototype chain", () => {
2210 const setter
= spy((_
) => {});
2211 const obj
= Object
.create(
2212 Object
.create(null, { success
: { set: setter
} }),
2214 setPropertyValues(obj
, { success
: true });
2215 assertSpyCalls(setter
, 1);
2216 assertSpyCall(setter
, 0, {
2222 it("[[Call]] throws if the property can’t be set", () => {
2223 const obj
= Object
.freeze({ failure
: undefined });
2224 assertThrows(() => setPropertyValues(obj
, { failure
: true }));
2227 it("[[Call]] returns the provided object", () => {
2229 assertStrictEquals(setPropertyValues(obj
, { "": undefined }), obj
);
2232 it("[[Construct]] throws an error", () => {
2233 assertThrows(() => new setPropertyValues(obj
, { "": undefined }));
2236 describe(".length", () => {
2237 it("[[Get]] returns the correct length", () => {
2238 assertStrictEquals(setPropertyValues
.length
, 2);
2242 describe(".name", () => {
2243 it("[[Get]] returns the correct name", () => {
2244 assertStrictEquals(setPropertyValues
.name
, "setPropertyValues");
2249 describe("setPrototype", () => {
2250 it("[[Call]] sets object prototypes", () => {
2253 setPrototype(obj
, proto
);
2254 assertStrictEquals(Object
.getPrototypeOf(obj
), proto
);
2257 it("[[Call]] sets null prototypes", () => {
2259 setPrototype(obj
, null);
2260 assertStrictEquals(Object
.getPrototypeOf(obj
), null);
2263 it("[[Call]] can set coercible primitives to their same prototype", () => {
2264 setPrototype(1, Number
.prototype);
2265 setPrototype(Symbol(), Symbol
.prototype);
2268 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
2269 assertThrows(() => setPrototype(1, Object
.prototype));
2270 assertThrows(() => setPrototype(Symbol(), Object
.prototype));
2273 it("[[Call]] throws for null and undefined", () => {
2274 assertThrows(() => setPrototype(null, Object
.prototype));
2275 assertThrows(() => setPrototype(undefined, Object
.prototype));
2278 it("[[Call]] returns the provided value", () => {
2280 assertStrictEquals(setPrototype(obj
, null), obj
);
2281 assertStrictEquals(setPrototype(1, Number
.prototype), 1);
2284 it("[[Construct]] throws an error", () => {
2285 assertThrows(() => new setPrototype({}, null));
2288 describe(".length", () => {
2289 it("[[Get]] returns the correct length", () => {
2290 assertStrictEquals(setPrototype
.length
, 2);
2294 describe(".name", () => {
2295 it("[[Get]] returns the correct name", () => {
2296 assertStrictEquals(setPrototype
.name
, "setPrototype");
2301 describe("toObject", () => {
2302 it("returns the input for objects", () => {
2304 assertStrictEquals(toObject(obj
), obj
);
2307 it("throws for nullish values", () => {
2308 assertThrows(() => toObject(null));
2309 assertThrows(() => toObject(void {}));
2312 it("returns a wrapper object for other primitives", () => {
2313 const sym
= Symbol();
2314 assertStrictEquals(typeof toObject(sym
), "object");
2315 assertStrictEquals(toObject(sym
).valueOf(), sym
);
2318 it("[[Construct]] throws an error", () => {
2319 assertThrows(() => new toObject({}));
2322 describe(".length", () => {
2323 it("[[Get]] returns the correct length", () => {
2324 assertStrictEquals(toObject
.length
, 1);
2328 describe(".name", () => {
2329 it("[[Get]] returns the correct name", () => {
2330 assertStrictEquals(toObject
.name
, "toObject");
2335 describe("toPropertyKey", () => {
2336 it("returns a string or symbol", () => {
2337 const sym
= Symbol();
2338 assertStrictEquals(toPropertyKey(sym
), sym
);
2340 toPropertyKey(new String("success")),
2345 it("favours the `toString` representation", () => {
2359 it("[[Construct]] throws an error", () => {
2360 assertThrows(() => new toPropertyKey(""));
2363 describe(".length", () => {
2364 it("[[Get]] returns the correct length", () => {
2365 assertStrictEquals(toPropertyKey
.length
, 1);
2369 describe(".name", () => {
2370 it("[[Get]] returns the correct name", () => {
2371 assertStrictEquals(toPropertyKey
.name
, "toPropertyKey");