1 // SPDX-FileCopyrightText: 2022, 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
2 // SPDX-License-Identifier: MPL-2.0
4 * ⁌ ♓🌟 Piscēs ∷ object.js
6 * Copyright © 2022–2023, 2025 Lady [@ Ladys Computer].
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
16 assertNotStrictEquals
,
24 } from "./dev-deps.js";
26 defineOwnDataProperty
,
27 defineOwnNonenumerableDataProperty
,
34 getOwnPropertyDescriptor
,
35 getOwnPropertyDescriptors
,
36 getOwnPropertyEntries
,
38 getOwnPropertyStrings
,
39 getOwnPropertySymbols
,
47 isConcatSpreadableObject
,
49 isPropertyDescriptorRecord
,
65 toPropertyDescriptorRecord
,
68 describe("LazyLoader", () => {
69 const symbol
= Symbol("foo");
71 const etaoinMethod
= spy(() => "success");
72 const shrdluMethod
= spy(() => "success");
73 const cmfwypMethod
= spy(() => "success");
74 const vbgkqjMethod
= spy(() => "success");
75 const methodsObject
= Object
.create(
105 xz
fiflffffi: { configurable: true, enumerable: false, set(_
) {} },
115 it("[[Call]] throws an error", () => {
116 assertThrows(() => LazyLoader({}));
119 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
121 Object
.getPrototypeOf(new LazyLoader(methodsObject
)),
126 it("[[Construct]] creates a new object with the desired properties", () => {
128 Reflect
.ownKeys(new LazyLoader(methodsObject
)),
129 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol
],
133 it("[[Construct]] creates a new object with configurable properties", () => {
137 for (const key
of Reflect
.ownKeys(ll
)) {
140 Object
.getOwnPropertyDescriptor(ll
, key
).configurable
,
143 }(new LazyLoader(methodsObject
)),
156 it("[[Construct]] creates a new object with the correct enumerability", () => {
160 for (const key
of Reflect
.ownKeys(ll
)) {
163 Object
.getOwnPropertyDescriptor(ll
, key
).enumerable
,
166 }(new LazyLoader(methodsObject
)),
179 it("[[Construct]] creates a new object with defined getters", () => {
183 for (const key
of Reflect
.ownKeys(ll
)) {
186 Object
.getOwnPropertyDescriptor(ll
, key
).get?.name
,
189 }(new LazyLoader(methodsObject
)),
192 etaoin: "get etaoin",
193 shrdlu: "get shrdlu",
194 cmfwyp: "get cmfwyp",
195 vbgkqj: "get vbgkqj",
196 xz
fiflffffi: "get xzfiflffffi",
197 [symbol
]: `get [${symbol.description}]`,
202 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
206 for (const key
of Reflect
.ownKeys(ll
)) {
209 Object
.getOwnPropertyDescriptor(ll
, key
).set?.name
,
212 }(new LazyLoader(methodsObject
)),
220 [symbol
]: `set [${symbol.description}]`,
225 it("[[Construct]] creates a new object with correct getter behaviour", () => {
226 const ll
= new LazyLoader(methodsObject
);
229 Object
.getOwnPropertyDescriptor(ll
, "etaoin"),
237 assertSpyCalls(etaoinMethod
, 1);
238 assertSpyCall(etaoinMethod
, 0, {
245 Object
.getOwnPropertyDescriptor(ll
, "shrdlu"),
253 assertSpyCalls(shrdluMethod
, 1);
254 assertSpyCall(shrdluMethod
, 0, {
261 Object
.getOwnPropertyDescriptor(ll
, "cmfwyp"),
269 assertSpyCalls(cmfwypMethod
, 1);
270 assertSpyCall(cmfwypMethod
, 0, {
277 Object
.getOwnPropertyDescriptor(ll
, "vbgkqj"),
285 assertSpyCalls(vbgkqjMethod
, 1);
286 assertSpyCall(vbgkqjMethod
, 0, {
291 assertThrows(() => ll
.xz
fiflffffi);
292 assertThrows(() => ll
[symbol
]);
295 it("[[Construct]] creates a new object with correct setter behaviour", () => {
296 const ll
= new LazyLoader(methodsObject
);
297 ll
[symbol
] = "success";
299 Object
.getOwnPropertyDescriptor(ll
, symbol
),
309 describe(".length", () => {
310 it("[[Get]] returns the correct length", () => {
311 assertStrictEquals(LazyLoader
.length
, 1);
315 describe(".name", () => {
316 it("[[Get]] returns the correct name", () => {
317 assertStrictEquals(LazyLoader
.name
, "LazyLoader");
322 describe("defineOwnDataProperty", () => {
323 it("[[Call]] defines the property", () => {
325 defineOwnDataProperty(obj
, "etaoin", "success");
326 assert(Object
.hasOwn(obj
, "etaoin"));
327 assertStrictEquals(obj
.etaoin
, "success");
330 it("[[Call]] defines a configurable, enumerable, writable property", () => {
332 defineOwnDataProperty(obj
, "etaoin", "success");
334 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
344 it("[[Call]] returns the provided object", () => {
347 defineOwnDataProperty(obj
, "etaoin", null),
352 it("[[Construct]] throws an error", () => {
353 assertThrows(() => new defineOwnDataProperty(obj
, "etaoin", null));
356 describe(".length", () => {
357 it("[[Get]] returns the correct length", () => {
358 assertStrictEquals(defineOwnDataProperty
.length
, 3);
362 describe(".name", () => {
363 it("[[Get]] returns the correct name", () => {
365 defineOwnDataProperty
.name
,
366 "defineOwnDataProperty",
372 describe("defineOwnNonenumerableDataProperty", () => {
373 it("[[Call]] defines the property", () => {
375 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
376 assert(Object
.hasOwn(obj
, "etaoin"));
377 assertStrictEquals(obj
.etaoin
, "success");
380 it("[[Call]] defines a configurable, non·enumerable, writable property", () => {
382 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
384 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
394 it("[[Call]] returns the provided object", () => {
397 defineOwnNonenumerableDataProperty(obj
, "etaoin", null),
402 it("[[Construct]] throws an error", () => {
404 new defineOwnNonenumerableDataProperty(obj
, "etaoin", null)
408 describe(".length", () => {
409 it("[[Get]] returns the correct length", () => {
410 assertStrictEquals(defineOwnNonenumerableDataProperty
.length
, 3);
414 describe(".name", () => {
415 it("[[Get]] returns the correct name", () => {
417 defineOwnNonenumerableDataProperty
.name
,
418 "defineOwnNonenumerableDataProperty",
424 describe("defineOwnProperty", () => {
425 it("[[Call]] defines the property", () => {
427 defineOwnProperty(obj
, "etaoin", {});
428 assert(Object
.hasOwn(obj
, "etaoin"));
431 it("[[Call]] returns the provided object", () => {
433 assertStrictEquals(defineOwnProperty(obj
, "etaoin", {}), obj
);
436 it("[[Construct]] throws an error", () => {
437 assertThrows(() => new defineOwnProperty(obj
, "etaoin", {}));
440 describe(".length", () => {
441 it("[[Get]] returns the correct length", () => {
442 assertStrictEquals(defineOwnProperty
.length
, 3);
446 describe(".name", () => {
447 it("[[Get]] returns the correct name", () => {
449 defineOwnProperty
.name
,
456 describe("defineOwnProperties", () => {
457 it("[[Call]] defines properties from the provided objects", () => {
459 defineOwnProperties(obj
, {
463 assert("etaoin" in obj
);
464 assert("shrdlu" in obj
);
465 assert("cmfwyp" in obj
);
468 it("[[Call]] overrides earlier declarations with later ones", () => {
469 const obj
= { etaoin: undefined };
470 defineOwnProperties(obj
, {
471 etaoin: { value: "failure" },
473 etaoin: { value: "success" },
475 assertStrictEquals(obj
.etaoin
, "success");
478 it("[[Call]] returns the provided object", () => {
480 assertStrictEquals(defineOwnProperties(obj
), obj
);
483 it("[[Construct]] throws an error", () => {
484 assertThrows(() => new defineOwnProperties({}));
487 describe(".length", () => {
488 it("[[Get]] returns the correct length", () => {
489 assertStrictEquals(defineOwnProperties
.length
, 1);
493 describe(".name", () => {
494 it("[[Get]] returns the correct name", () => {
496 defineOwnProperties
.name
,
497 "defineOwnProperties",
503 describe("deleteOwnProperty", () => {
504 it("[[Call]] deletes the provided property on the provided object", () => {
505 const obj
= { failure: undefined };
506 deleteOwnProperty(obj
, "failure");
507 assert(!("failure" in obj
));
510 it("[[Call]] does nothing if the property doesn’t exist", () => {
511 const obj
= Object
.freeze({});
512 deleteOwnProperty(obj
, "failure");
513 assert(!("failure" in obj
));
516 it("[[Call]] throws if the property can’t be deleted", () => {
517 const obj
= Object
.seal({ failure: undefined });
518 assertThrows(() => deleteOwnProperty(obj
, "failure"));
521 it("[[Call]] returns the provided object", () => {
523 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
526 it("[[Construct]] throws an error", () => {
527 assertThrows(() => new deleteOwnProperty({}, ""));
530 describe(".length", () => {
531 it("[[Get]] returns the correct length", () => {
532 assertStrictEquals(deleteOwnProperty
.length
, 2);
536 describe(".name", () => {
537 it("[[Get]] returns the correct name", () => {
538 assertStrictEquals(deleteOwnProperty
.name
, "deleteOwnProperty");
543 describe("freeze", () => {
544 it("[[Call]] freezes the object", () => {
547 assert(Object
.isFrozen(obj
));
550 it("[[Call]] returns the provided object", () => {
552 assertStrictEquals(freeze(obj
), obj
);
555 it("[[Construct]] throws an error", () => {
556 assertThrows(() => new freeze({}));
559 describe(".length", () => {
560 it("[[Get]] returns the correct length", () => {
561 assertStrictEquals(freeze
.length
, 1);
565 describe(".name", () => {
566 it("[[Get]] returns the correct name", () => {
567 assertStrictEquals(freeze
.name
, "freeze");
572 describe("frozenCopy", () => {
573 it("[[Call]] returns a frozen object", () => {
576 frozenCopy(Object
.create(null), {
593 it("[[Call]] ignores non·enumerable properties", () => {
596 Object
.create(null, {
597 data: { value: undefined },
598 accessor: { get: undefined },
605 it("[[Call]] preserves accessor properties", () => {
633 Object
.getOwnPropertyDescriptors(
634 frozenCopy(Object
.create(null, properties
)),
640 it("[[Call]] preserves data properties", () => {
660 Object
.getOwnPropertyDescriptors(
661 frozenCopy(Object
.create(null, properties
)),
665 ...properties
.implied
,
669 writable: { ...properties
.writable
, writable: false },
670 nonwritable: properties
.nonwritable
,
675 it("[[Call]] does not copy properties on the prototype", () => {
678 in frozenCopy(Object
.create({ failure: undefined }))),
682 it("[[Call]] uses the species of the constructor", () => {
683 const species
= { prototype: {} };
685 Object
.getPrototypeOf(
686 frozenCopy({}, { [Symbol
.species
]: species
}),
692 it("[[Call]] uses constructor if no species is defined", () => {
693 const constructor = { [Symbol
.species
]: null, prototype: {} };
695 Object
.getPrototypeOf(frozenCopy({}, constructor)),
696 constructor.prototype,
700 it("[[Call]] uses the constructor on the object if none is provided", () => {
701 const constructor = { [Symbol
.species
]: null, prototype: {} };
703 Object
.getPrototypeOf(frozenCopy({ constructor })),
704 constructor.prototype,
708 it("[[Call]] allows a null constructor", () => {
710 Object
.getPrototypeOf(frozenCopy({}, null)),
715 it("[[Construct]] throws an error", () => {
716 assertThrows(() => new frozenCopy({}));
719 describe(".length", () => {
720 it("[[Get]] returns the correct length", () => {
721 assertStrictEquals(frozenCopy
.length
, 1);
725 describe(".name", () => {
726 it("[[Get]] returns the correct name", () => {
727 assertStrictEquals(frozenCopy
.name
, "frozenCopy");
732 describe("getMethod", () => {
733 it("[[Call]] gets a method", () => {
734 const method
= () => {};
735 assertStrictEquals(getMethod({ method
}, "method"), method
);
738 it("[[Call]] works for values coercible to objects", () => {
739 assertEquals(getMethod("", "toString"), String
.prototype.toString
);
742 it("[[Call]] throws for null and undefined", () => {
743 assertThrows(() => getMethod(null, "valueOf"));
744 assertThrows(() => getMethod(undefined, "valueOf"));
747 it("[[Call]] throws if the resulting value isn’t callable", () => {
748 assertThrows(() => getMethod({ "failure": true }, "failure"));
751 it("[[Construct]] throws an error", () => {
752 assertThrows(() => new getMethod({ method() {} }, "method"));
755 describe(".length", () => {
756 it("[[Get]] returns the correct length", () => {
757 assertStrictEquals(getMethod
.length
, 2);
761 describe(".name", () => {
762 it("[[Get]] returns the correct name", () => {
763 assertStrictEquals(getMethod
.name
, "getMethod");
768 describe("getOwnPropertyDescriptor", () => {
769 it("[[Call]] gets the descriptor", () => {
771 getOwnPropertyDescriptor({ success: true }, "success"),
781 it("[[Call]] returns undefined for non‐own properties", () => {
783 getOwnPropertyDescriptor({}, "valueOf"),
788 it("[[Construct]] throws an error", () => {
789 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
792 describe(".length", () => {
793 it("[[Get]] returns the correct length", () => {
794 assertStrictEquals(getOwnPropertyDescriptor
.length
, 2);
798 describe(".name", () => {
799 it("[[Get]] returns the correct name", () => {
801 getOwnPropertyDescriptor
.name
,
802 "getOwnPropertyDescriptor",
808 describe("getOwnPropertyDescriptors", () => {
809 it("[[Call]] gets the descriptors", () => {
811 getOwnPropertyDescriptors({ success: true, etaoin: "shrdlu" }),
829 it("[[Construct]] throws an error", () => {
830 assertThrows(() => new getOwnPropertyDescriptors({}));
833 describe(".length", () => {
834 it("[[Get]] returns the correct length", () => {
835 assertStrictEquals(getOwnPropertyDescriptors
.length
, 1);
839 describe(".name", () => {
840 it("[[Get]] returns the correct name", () => {
842 getOwnPropertyDescriptors
.name
,
843 "getOwnPropertyDescriptors",
849 describe("getOwnPropertyEntries", () => {
850 it("[[Call]] gets own (but not inherited) property entries", () => {
852 getOwnPropertyEntries({ success: true }),
857 it("[[Call]] works for values coercible to objects", () => {
859 getOwnPropertyEntries("foo"),
860 [["0", "f"], ["1", "o"], ["2", "o"], ["length", 3]],
864 it("[[Call]] uses the provided receiver", () => {
867 getOwnPropertyEntries({
872 [["success", target
]],
876 it("[[Call]] throws for null and undefined", () => {
877 assertThrows(() => getOwnPropertyEntries(null));
878 assertThrows(() => getOwnPropertyEntries(undefined));
881 it("[[Construct]] throws an error", () => {
882 assertThrows(() => new getOwnPropertyEntries({}));
885 describe(".length", () => {
886 it("[[Get]] returns the correct length", () => {
887 assertStrictEquals(getOwnPropertyEntries
.length
, 1);
891 describe(".name", () => {
892 it("[[Get]] returns the correct name", () => {
894 getOwnPropertyEntries
.name
,
895 "getOwnPropertyEntries",
901 describe("getOwnPropertyKeys", () => {
902 it("[[Call]] gets own (but not inherited) property keys", () => {
903 assertEquals(getOwnPropertyKeys({ success: true }), ["success"]);
906 it("[[Call]] works for values coercible to objects", () => {
907 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
910 it("[[Call]] throws for null and undefined", () => {
911 assertThrows(() => getOwnPropertyKeys(null));
912 assertThrows(() => getOwnPropertyKeys(undefined));
915 it("[[Construct]] throws an error", () => {
916 assertThrows(() => new getOwnPropertyKeys({}));
919 describe(".length", () => {
920 it("[[Get]] returns the correct length", () => {
921 assertStrictEquals(getOwnPropertyKeys
.length
, 1);
925 describe(".name", () => {
926 it("[[Get]] returns the correct name", () => {
928 getOwnPropertyKeys
.name
,
929 "getOwnPropertyKeys",
935 describe("getOwnPropertyStrings", () => {
936 it("[[Call]] gets own string keys", () => {
937 assertEquals(getOwnPropertyStrings({ success: true }), [
942 it("[[Call]] works for values coercible to objects", () => {
943 assertEquals(getOwnPropertyStrings("foo"), [
951 it("[[Call]] throws for null and undefined", () => {
952 assertThrows(() => getOwnPropertyStrings(null));
953 assertThrows(() => getOwnPropertyStrings(undefined));
956 it("[[Construct]] throws an error", () => {
957 assertThrows(() => new getOwnPropertyStrings({}));
960 describe(".length", () => {
961 it("[[Get]] returns the correct length", () => {
962 assertStrictEquals(getOwnPropertyStrings
.length
, 1);
966 describe(".name", () => {
967 it("[[Get]] returns the correct name", () => {
969 getOwnPropertyStrings
.name
,
970 "getOwnPropertyStrings",
976 describe("getOwnPropertySymbols", () => {
977 it("[[Call]] gets own symbol keys", () => {
978 const sym
= Symbol();
979 assertEquals(getOwnPropertySymbols({ [sym
]: true }), [sym
]);
982 it("[[Call]] works for values coercible to objects", () => {
983 assertEquals(getOwnPropertySymbols("foo"), []);
986 it("[[Call]] throws for null and undefined", () => {
987 assertThrows(() => getOwnPropertySymbols(null));
988 assertThrows(() => getOwnPropertySymbols(undefined));
991 it("[[Construct]] throws an error", () => {
992 assertThrows(() => new getOwnPropertySymbols({}));
995 describe(".length", () => {
996 it("[[Get]] returns the correct length", () => {
997 assertStrictEquals(getOwnPropertySymbols
.length
, 1);
1001 describe(".name", () => {
1002 it("[[Get]] returns the correct name", () => {
1004 getOwnPropertySymbols
.name
,
1005 "getOwnPropertySymbols",
1011 describe("getOwnPropertyValue", () => {
1012 it("[[Call]] gets the own property value", () => {
1014 getOwnPropertyValue({ success: true }, "success"),
1019 it("[[Call]] returns undefined for non‐own properties", () => {
1021 getOwnPropertyValue(Object
.create({ success: true }), "success"),
1026 it("[[Call]] works for values coercible to objects", () => {
1027 assertStrictEquals(getOwnPropertyValue("foo", "length"), 3);
1030 it("[[Call]] uses the provided receiver", () => {
1033 getOwnPropertyValue(
1046 it("[[Call]] throws for null and undefined", () => {
1047 assertThrows(() => getOwnPropertyValue(null));
1048 assertThrows(() => getOwnPropertyValue(undefined));
1051 it("[[Construct]] throws an error", () => {
1052 assertThrows(() => new getOwnPropertyValue({}));
1055 describe(".length", () => {
1056 it("[[Get]] returns the correct length", () => {
1057 assertStrictEquals(getOwnPropertyValue
.length
, 2);
1061 describe(".name", () => {
1062 it("[[Get]] returns the correct name", () => {
1064 getOwnPropertyValue
.name
,
1065 "getOwnPropertyValue",
1071 describe("getOwnPropertyValues", () => {
1072 it("[[Call]] gets own (but not inherited) property values", () => {
1073 assertEquals(getOwnPropertyValues({ success: true }), [true]);
1076 it("[[Call]] works for values coercible to objects", () => {
1078 getOwnPropertyValues("foo"),
1083 it("[[Call]] uses the provided receiver", () => {
1086 getOwnPropertyValues({
1095 it("[[Call]] throws for null and undefined", () => {
1096 assertThrows(() => getOwnPropertyValues(null));
1097 assertThrows(() => getOwnPropertyValues(undefined));
1100 it("[[Construct]] throws an error", () => {
1101 assertThrows(() => new getOwnPropertyValues({}));
1104 describe(".length", () => {
1105 it("[[Get]] returns the correct length", () => {
1106 assertStrictEquals(getOwnPropertyValues
.length
, 1);
1110 describe(".name", () => {
1111 it("[[Get]] returns the correct name", () => {
1113 getOwnPropertyValues
.name
,
1114 "getOwnPropertyValues",
1120 describe("getPropertyValue", () => {
1121 it("[[Call]] gets property values on the provided object", () => {
1123 getPropertyValue({ success: true }, "success"),
1128 it("[[Call]] works for values coercible to objects", () => {
1130 getPropertyValue("", "toString"),
1131 String
.prototype.toString
,
1135 it("[[Call]] throws for null and undefined", () => {
1136 assertThrows(() => getPropertyValue(null, "valueOf"));
1137 assertThrows(() => getPropertyValue(undefined, "valueOf"));
1140 it("[[Construct]] throws an error", () => {
1141 assertThrows(() => new getPropertyValue({}, "valueOf"));
1144 describe(".length", () => {
1145 it("[[Get]] returns the correct length", () => {
1146 assertStrictEquals(getPropertyValue
.length
, 2);
1150 describe(".name", () => {
1151 it("[[Get]] returns the correct name", () => {
1152 assertStrictEquals(getPropertyValue
.name
, "getPropertyValue");
1157 describe("getPrototype", () => {
1158 it("[[Call]] gets object prototypes", () => {
1159 assertStrictEquals(getPrototype({}), Object
.prototype);
1161 assertStrictEquals(getPrototype(Object
.create(proto
)), proto
);
1164 it("[[Call]] gets null prototypes", () => {
1165 assertStrictEquals(getPrototype(Object
.create(null)), null);
1168 it("[[Call]] gets prototypes for coercible primitives", () => {
1169 assertStrictEquals(getPrototype(1), Number
.prototype);
1170 assertStrictEquals(getPrototype(Symbol()), Symbol
.prototype);
1173 it("[[Call]] throws for null and undefined", () => {
1174 assertThrows(() => getPrototype(null));
1175 assertThrows(() => getPrototype(undefined));
1178 it("[[Construct]] throws an error", () => {
1179 assertThrows(() => new getPrototype({}));
1182 describe(".length", () => {
1183 it("[[Get]] returns the correct length", () => {
1184 assertStrictEquals(getPrototype
.length
, 1);
1188 describe(".name", () => {
1189 it("[[Get]] returns the correct name", () => {
1190 assertStrictEquals(getPrototype
.name
, "getPrototype");
1195 describe("hasProperty", () => {
1196 it("[[Call]] gets whether a property exists on the provided object", () => {
1198 hasProperty({ success: "etaoin" }, "success"),
1201 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
1204 it("[[Call]] works for values coercible to objects", () => {
1205 assertStrictEquals(hasProperty("", "length"), true);
1206 assertStrictEquals(hasProperty("", "toString"), true);
1209 it("[[Call]] throws for null and undefined", () => {
1210 assertThrows(() => hasProperty(null, "valueOf"));
1211 assertThrows(() => hasProperty(undefined, "valueOf"));
1214 it("[[Construct]] throws an error", () => {
1215 assertThrows(() => new hasProperty({}, "valueOf"));
1218 describe(".length", () => {
1219 it("[[Get]] returns the correct length", () => {
1220 assertStrictEquals(hasProperty
.length
, 2);
1224 describe(".name", () => {
1225 it("[[Get]] returns the correct name", () => {
1226 assertStrictEquals(hasProperty
.name
, "hasProperty");
1231 describe("hasOwnProperty", () => {
1232 it("[[Call]] gets whether an own property exists on the provided object", () => {
1234 hasOwnProperty({ success: "etaoin" }, "success"),
1237 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
1240 it("[[Call]] works for values coercible to objects", () => {
1241 assertStrictEquals(hasOwnProperty("", "length"), true);
1242 assertStrictEquals(hasOwnProperty("", "toString"), false);
1245 it("[[Call]] throws for null and undefined", () => {
1246 assertThrows(() => hasOwnProperty(null, "valueOf"));
1247 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
1250 it("[[Construct]] throws an error", () => {
1251 assertThrows(() => new hasOwnProperty({}, "valueOf"));
1254 describe(".length", () => {
1255 it("[[Get]] returns the correct length", () => {
1256 assertStrictEquals(hasOwnProperty
.length
, 2);
1260 describe(".name", () => {
1261 it("[[Get]] returns the correct name", () => {
1262 assertStrictEquals(hasOwnProperty
.name
, "hasOwnProperty");
1267 describe("isArraylikeObject", () => {
1268 it("[[Call]] returns false for primitives", () => {
1269 assertStrictEquals(isArraylikeObject("failure"), false);
1272 it("[[Call]] returns false if length throws", () => {
1283 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
1284 assertStrictEquals(isArraylikeObject({ length: 1n
}), false);
1287 it("[[Call]] returns true if length is convertable to a number", () => {
1288 assertStrictEquals(isArraylikeObject({ length: -0 }), true);
1289 assertStrictEquals(isArraylikeObject({ length: 1 }), true);
1290 assertStrictEquals(isArraylikeObject({ length: -1.25 }), true);
1292 isArraylikeObject({ length: 9007199254740992 }),
1295 assertStrictEquals(isArraylikeObject({ length: Infinity
}), true);
1296 assertStrictEquals(isArraylikeObject({ length: "success" }), true);
1299 it("[[Construct]] throws an error", () => {
1300 assertThrows(() => new isArraylikeObject({}));
1303 describe(".length", () => {
1304 it("[[Get]] returns the correct length", () => {
1305 assertStrictEquals(isArraylikeObject
.length
, 1);
1309 describe(".name", () => {
1310 it("[[Get]] returns the correct name", () => {
1312 isArraylikeObject
.name
,
1313 "isArraylikeObject",
1319 describe("isConcatSpreadableObject", () => {
1320 it("[[Call]] returns false for primitives", () => {
1321 assertStrictEquals(isConcatSpreadableObject("failure"), false);
1324 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
1326 isConcatSpreadableObject(
1327 Object
.assign([], { [Symbol
.isConcatSpreadable
]: null }),
1332 isConcatSpreadableObject(
1333 Object
.assign([], { [Symbol
.isConcatSpreadable
]: false }),
1339 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
1341 isConcatSpreadableObject(
1342 Object
.assign([], { [Symbol
.isConcatSpreadable
]: undefined }),
1348 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
1350 isConcatSpreadableObject({ [Symbol
.isConcatSpreadable
]: true }),
1355 it("[[Construct]] throws an error", () => {
1356 assertThrows(() => new isConcatSpreadableObject({}));
1359 describe(".length", () => {
1360 it("[[Get]] returns the correct length", () => {
1361 assertStrictEquals(isConcatSpreadableObject
.length
, 1);
1365 describe(".name", () => {
1366 it("[[Get]] returns the correct name", () => {
1368 isConcatSpreadableObject
.name
,
1369 "isConcatSpreadableObject",
1375 describe("isExtensibleObject", () => {
1376 it("[[Call]] returns true for extensible objects", () => {
1377 assertStrictEquals(isExtensibleObject({}), true);
1380 it("[[Call]] returns false for coercible primitives", () => {
1381 assertStrictEquals(isExtensibleObject(1), false);
1382 assertStrictEquals(isExtensibleObject(Symbol()), false);
1385 it("[[Call]] returns false for non·extensible objects", () => {
1387 isExtensibleObject(Object
.preventExtensions({})),
1392 it("[[Call]] returns false for null and undefined", () => {
1393 assertStrictEquals(isExtensibleObject(null), false);
1394 assertStrictEquals(isExtensibleObject(undefined), false);
1397 it("[[Construct]] throws an error", () => {
1398 assertThrows(() => new isExtensibleObject({}));
1401 describe(".length", () => {
1402 it("[[Get]] returns the correct length", () => {
1403 assertStrictEquals(isExtensibleObject
.length
, 1);
1407 describe(".name", () => {
1408 it("[[Get]] returns the correct name", () => {
1410 isExtensibleObject
.name
,
1411 "isExtensibleObject",
1417 describe("isPropertyDescriptorRecord", () => {
1418 it("[[Call]] returns true for objects created by toPropertyDescriptorRecord", () => {
1420 isPropertyDescriptorRecord(toPropertyDescriptorRecord({})),
1425 it("[[Get]] returns false for other objects", () => {
1427 isPropertyDescriptorRecord(Object
.create(null)),
1432 it("[[Get]] returns false for undefined", () => {
1433 assertStrictEquals(isPropertyDescriptorRecord(undefined), false);
1436 it("[[Construct]] throws an error", () => {
1437 assertThrows(() => new isPropertyDescriptorRecord({}));
1440 describe(".length", () => {
1441 it("[[Get]] returns the correct length", () => {
1442 assertStrictEquals(isPropertyDescriptorRecord
.length
, 1);
1446 describe(".name", () => {
1447 it("[[Get]] returns the correct name", () => {
1449 isPropertyDescriptorRecord
.name
,
1450 "isPropertyDescriptorRecord",
1456 describe("isUnfrozenObject", () => {
1457 it("[[Call]] returns true for unfrozen objects", () => {
1458 assertStrictEquals(isUnfrozenObject({}), true);
1461 it("[[Call]] returns false for coercible primitives", () => {
1462 assertStrictEquals(isUnfrozenObject(1), false);
1463 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1466 it("[[Call]] returns false for frozen objects", () => {
1467 assertStrictEquals(isUnfrozenObject(Object
.freeze({})), false);
1470 it("[[Call]] returns false for null and undefined", () => {
1471 assertStrictEquals(isUnfrozenObject(null), false);
1472 assertStrictEquals(isUnfrozenObject(undefined), false);
1475 it("[[Construct]] throws an error", () => {
1476 assertThrows(() => new isUnfrozenObject({}));
1479 describe(".length", () => {
1480 it("[[Get]] returns the correct length", () => {
1481 assertStrictEquals(isUnfrozenObject
.length
, 1);
1485 describe(".name", () => {
1486 it("[[Get]] returns the correct name", () => {
1487 assertStrictEquals(isUnfrozenObject
.name
, "isUnfrozenObject");
1492 describe("isUnsealedObject", () => {
1493 it("[[Call]] returns true for unsealed objects", () => {
1494 assertStrictEquals(isUnsealedObject({}), true);
1497 it("[[Call]] returns false for coercible primitives", () => {
1498 assertStrictEquals(isUnsealedObject(1), false);
1499 assertStrictEquals(isUnsealedObject(Symbol()), false);
1502 it("[[Call]] returns false for sealed objects", () => {
1503 assertStrictEquals(isUnsealedObject(Object
.seal({})), false);
1506 it("[[Call]] returns false for null and undefined", () => {
1507 assertStrictEquals(isUnsealedObject(null), false);
1508 assertStrictEquals(isUnsealedObject(undefined), false);
1511 it("[[Construct]] throws an error", () => {
1512 assertThrows(() => new isUnsealedObject({}));
1515 describe(".length", () => {
1516 it("[[Get]] returns the correct length", () => {
1517 assertStrictEquals(isUnsealedObject
.length
, 1);
1521 describe(".name", () => {
1522 it("[[Get]] returns the correct name", () => {
1523 assertStrictEquals(isUnsealedObject
.name
, "isUnsealedObject");
1528 describe("lengthOfArraylike", () => {
1529 it("[[Call]] returns the length", () => {
1531 lengthOfArraylike({ length: 9007199254740991 }),
1536 it("[[Call]] returns a non·nan result", () => {
1537 assertStrictEquals(lengthOfArraylike({ length: NaN
}), 0);
1538 assertStrictEquals(lengthOfArraylike({ length: "failure" }), 0);
1541 it("[[Call]] returns an integral result", () => {
1542 assertStrictEquals(lengthOfArraylike({ length: 0.25 }), 0);
1543 assertStrictEquals(lengthOfArraylike({ length: 1.1 }), 1);
1546 it("[[Call]] returns a result greater than or equal to zero", () => {
1547 assertStrictEquals(lengthOfArraylike({ length: -0 }), 0);
1548 assertStrictEquals(lengthOfArraylike({ length: -1 }), 0);
1549 assertStrictEquals(lengthOfArraylike({ length: -Infinity
}), 0);
1552 it("[[Call]] returns a result less than 2 ** 53", () => {
1554 lengthOfArraylike({ length: 9007199254740992 }),
1558 lengthOfArraylike({ length: Infinity
}),
1563 it("[[Call]] does not require an object argument", () => {
1564 assertStrictEquals(lengthOfArraylike("string"), 6);
1565 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1568 it("[[Construct]] throws an error", () => {
1569 assertThrows(() => new lengthOfArraylike(""));
1572 describe(".length", () => {
1573 it("[[Get]] returns the correct length", () => {
1574 assertStrictEquals(lengthOfArraylike
.length
, 1);
1578 describe(".name", () => {
1579 it("[[Get]] returns the correct name", () => {
1580 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
1585 describe("namedEntries", () => {
1586 it("[[Call]] gets named entries", () => {
1587 assertEquals(namedEntries({ success: true }), [["success", true]]);
1590 it("[[Call]] works for values coercible to objects", () => {
1591 assertEquals(namedEntries("foo"), [
1598 it("[[Call]] throws for null and undefined", () => {
1599 assertThrows(() => namedEntries(null));
1600 assertThrows(() => namedEntries(undefined));
1603 it("[[Construct]] throws an error", () => {
1604 assertThrows(() => new namedEntries({}));
1607 describe(".length", () => {
1608 it("[[Get]] returns the correct length", () => {
1609 assertStrictEquals(namedEntries
.length
, 1);
1613 describe(".name", () => {
1614 it("[[Get]] returns the correct name", () => {
1615 assertStrictEquals(namedEntries
.name
, "namedEntries");
1620 describe("namedKeys", () => {
1621 it("[[Call]] gets named keys", () => {
1622 assertEquals(namedKeys({ success: true }), ["success"]);
1625 it("[[Call]] works for values coercible to objects", () => {
1626 assertEquals(namedKeys("foo"), [
1633 it("[[Call]] throws for null and undefined", () => {
1634 assertThrows(() => namedKeys(null));
1635 assertThrows(() => namedKeys(undefined));
1638 it("[[Construct]] throws an error", () => {
1639 assertThrows(() => new namedKeys({}));
1642 describe(".length", () => {
1643 it("[[Get]] returns the correct length", () => {
1644 assertStrictEquals(namedKeys
.length
, 1);
1648 describe(".name", () => {
1649 it("[[Get]] returns the correct name", () => {
1650 assertStrictEquals(namedKeys
.name
, "namedKeys");
1655 describe("namedValues", () => {
1656 it("[[Call]] gets named values", () => {
1657 assertEquals(namedValues({ success: true }), [true]);
1660 it("[[Call]] works for values coercible to objects", () => {
1661 assertEquals(namedValues("foo"), [
1668 it("[[Call]] throws for null and undefined", () => {
1669 assertThrows(() => namedValues(null));
1670 assertThrows(() => namedValues(undefined));
1673 it("[[Construct]] throws an error", () => {
1674 assertThrows(() => new namedValues({}));
1677 describe(".length", () => {
1678 it("[[Get]] returns the correct length", () => {
1679 assertStrictEquals(namedValues
.length
, 1);
1683 describe(".name", () => {
1684 it("[[Get]] returns the correct name", () => {
1685 assertStrictEquals(namedValues
.name
, "namedValues");
1690 describe("objectCreate", () => {
1691 it("[[Call]] creates an object", () => {
1692 const obj
= objectCreate(null);
1693 assertStrictEquals(Object(obj
), obj
);
1696 it("[[Call]] correctly sets the prototype", () => {
1699 Object
.getPrototypeOf(objectCreate(proto
)),
1703 Object
.getPrototypeOf(objectCreate(null)),
1708 it("[[Call]] correctly sets own properties", () => {
1710 Object
.getOwnPropertyDescriptors(
1711 objectCreate(null, { success: { value: true } }),
1715 configurable: false,
1724 it("[[Call]] throws for coercible primitives", () => {
1725 assertThrows(() => objectCreate(1));
1726 assertThrows(() => objectCreate(Symbol()));
1729 it("[[Call]] throws for undefined", () => {
1730 assertThrows(() => objectCreate(undefined));
1733 it("[[Construct]] throws an error", () => {
1734 assertThrows(() => new objectCreate({}));
1737 describe(".length", () => {
1738 it("[[Get]] returns the correct length", () => {
1739 assertStrictEquals(objectCreate
.length
, 2);
1743 describe(".name", () => {
1744 it("[[Get]] returns the correct name", () => {
1745 assertStrictEquals(objectCreate
.name
, "objectCreate");
1750 describe("objectFromEntries", () => {
1751 it("[[Call]] creates an object", () => {
1752 const obj
= objectFromEntries([]);
1753 assertStrictEquals(Object(obj
), obj
);
1756 it("[[Call]] correctly sets the prototype", () => {
1758 Object
.getPrototypeOf(objectFromEntries([])),
1763 it("[[Call]] correctly sets own properties", () => {
1765 Object
.entries(objectFromEntries([["success", true]])),
1766 [["success", true]],
1770 it("[[Call]] throws if the argument is not a nested arraylike", () => {
1771 assertThrows(() => objectFromEntries(1));
1772 assertThrows(() => objectFromEntries(Symbol()));
1773 assertThrows(() => objectFromEntries(null));
1774 assertThrows(() => objectFromEntries(undefined));
1775 assertThrows(() => objectFromEntries({}));
1776 assertThrows(() => objectFromEntries([undefined]));
1779 it("[[Construct]] throws an error", () => {
1780 assertThrows(() => new objectFromEntries([]));
1783 describe(".length", () => {
1784 it("[[Get]] returns the correct length", () => {
1785 assertStrictEquals(objectFromEntries
.length
, 1);
1789 describe(".name", () => {
1790 it("[[Get]] returns the correct name", () => {
1791 assertStrictEquals(objectFromEntries
.name
, "objectFromEntries");
1796 describe("preventExtensions", () => {
1797 it("[[Call]] prevents extensions on the object", () => {
1799 preventExtensions(obj
);
1800 assert(!Object
.isExtensible(obj
));
1803 it("[[Call]] returns the provided object", () => {
1805 assertStrictEquals(preventExtensions(obj
), obj
);
1808 it("[[Construct]] throws an error", () => {
1809 assertThrows(() => new preventExtensions({}));
1812 describe(".length", () => {
1813 it("[[Get]] returns the correct length", () => {
1814 assertStrictEquals(preventExtensions
.length
, 1);
1818 describe(".name", () => {
1819 it("[[Get]] returns the correct name", () => {
1820 assertStrictEquals(preventExtensions
.name
, "preventExtensions");
1825 describe("seal", () => {
1826 it("[[Call]] seals the object", () => {
1829 assert(Object
.isSealed(obj
));
1832 it("[[Call]] returns the provided object", () => {
1834 assertStrictEquals(seal(obj
), obj
);
1837 it("[[Construct]] throws an error", () => {
1838 assertThrows(() => new seal({}));
1841 describe(".length", () => {
1842 it("[[Get]] returns the correct length", () => {
1843 assertStrictEquals(seal
.length
, 1);
1847 describe(".name", () => {
1848 it("[[Get]] returns the correct name", () => {
1849 assertStrictEquals(seal
.name
, "seal");
1854 describe("setPropertyValue", () => {
1855 it("[[Call]] sets the provided property on the provided object", () => {
1857 setPropertyValue(obj
, "success", true);
1858 assertStrictEquals(obj
.success
, true);
1861 it("[[Call]] calls setters", () => {
1862 const setter
= spy((_
) => {});
1863 const obj
= Object
.create(null, { success: { set: setter
} });
1864 setPropertyValue(obj
, "success", true);
1865 assertSpyCalls(setter
, 1);
1866 assertSpyCall(setter
, 0, {
1872 it("[[Call]] walks the prototype chain", () => {
1873 const setter
= spy((_
) => {});
1874 const obj
= Object
.create(
1875 Object
.create(null, { success: { set: setter
} }),
1877 setPropertyValue(obj
, "success", true);
1878 assertSpyCalls(setter
, 1);
1879 assertSpyCall(setter
, 0, {
1885 it("[[Call]] uses the provided receiver", () => {
1886 const setter
= spy((_
) => {});
1887 const obj
= Object
.create(null, { success: { set: setter
} });
1888 const receiver
= {};
1889 setPropertyValue(obj
, "success", true, receiver
);
1890 assertSpyCalls(setter
, 1);
1891 assertSpyCall(setter
, 0, {
1897 it("[[Call]] throws if the property can’t be set", () => {
1898 const obj
= Object
.freeze({ failure: undefined });
1899 assertThrows(() => setPropertyValue(obj
, "failure", true));
1902 it("[[Call]] returns the provided object", () => {
1904 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
1907 it("[[Construct]] throws an error", () => {
1908 assertThrows(() => new setPropertyValue({}, "", undefined));
1911 describe(".length", () => {
1912 it("[[Get]] returns the correct length", () => {
1913 assertStrictEquals(setPropertyValue
.length
, 3);
1917 describe(".name", () => {
1918 it("[[Get]] returns the correct name", () => {
1919 assertStrictEquals(setPropertyValue
.name
, "setPropertyValue");
1924 describe("setPropertyValues", () => {
1925 it("[[Call]] sets the provided properties on the provided object", () => {
1927 setPropertyValues(obj
, { success: true, all: "good" });
1928 assertStrictEquals(obj
.success
, true);
1929 assertStrictEquals(obj
.all
, "good");
1932 it("[[Call]] can take multiple objects", () => {
1936 { success: false, all: "good" },
1939 assertStrictEquals(obj
.success
, true);
1940 assertStrictEquals(obj
.all
, "good");
1943 it("[[Call]] ignores nullish arguments", () => {
1945 setPropertyValues(obj
, null, undefined, { success: true });
1946 assertStrictEquals(obj
.success
, true);
1949 it("[[Call]] calls setters", () => {
1950 const setter
= spy((_
) => {});
1951 const obj
= Object
.create(null, { success: { set: setter
} });
1952 setPropertyValues(obj
, { success: true });
1953 assertSpyCalls(setter
, 1);
1954 assertSpyCall(setter
, 0, {
1960 it("[[Call]] calls setters multiple times if property appears more than once", () => {
1961 const setter
= spy((_
) => {});
1962 const obj
= Object
.create(null, { success: { set: setter
} });
1963 setPropertyValues(obj
, { success: false }, { success: true });
1964 assertSpyCalls(setter
, 2);
1965 assertSpyCall(setter
, 0, {
1969 assertSpyCall(setter
, 1, {
1975 it("[[Call]] walks the prototype chain", () => {
1976 const setter
= spy((_
) => {});
1977 const obj
= Object
.create(
1978 Object
.create(null, { success: { set: setter
} }),
1980 setPropertyValues(obj
, { success: true });
1981 assertSpyCalls(setter
, 1);
1982 assertSpyCall(setter
, 0, {
1988 it("[[Call]] throws if the property can’t be set", () => {
1989 const obj
= Object
.freeze({ failure: undefined });
1990 assertThrows(() => setPropertyValues(obj
, { failure: true }));
1993 it("[[Call]] returns the provided object", () => {
1995 assertStrictEquals(setPropertyValues(obj
, { "": undefined }), obj
);
1998 it("[[Construct]] throws an error", () => {
1999 assertThrows(() => new setPropertyValues(obj
, { "": undefined }));
2002 describe(".length", () => {
2003 it("[[Get]] returns the correct length", () => {
2004 assertStrictEquals(setPropertyValues
.length
, 2);
2008 describe(".name", () => {
2009 it("[[Get]] returns the correct name", () => {
2010 assertStrictEquals(setPropertyValues
.name
, "setPropertyValues");
2015 describe("setPrototype", () => {
2016 it("[[Call]] sets object prototypes", () => {
2019 setPrototype(obj
, proto
);
2020 assertStrictEquals(Object
.getPrototypeOf(obj
), proto
);
2023 it("[[Call]] sets null prototypes", () => {
2025 setPrototype(obj
, null);
2026 assertStrictEquals(Object
.getPrototypeOf(obj
), null);
2029 it("[[Call]] can set coercible primitives to their same prototype", () => {
2030 setPrototype(1, Number
.prototype);
2031 setPrototype(Symbol(), Symbol
.prototype);
2034 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
2035 assertThrows(() => setPrototype(1, Object
.prototype));
2036 assertThrows(() => setPrototype(Symbol(), Object
.prototype));
2039 it("[[Call]] throws for null and undefined", () => {
2040 assertThrows(() => setPrototype(null, Object
.prototype));
2041 assertThrows(() => setPrototype(undefined, Object
.prototype));
2044 it("[[Call]] returns the provided value", () => {
2046 assertStrictEquals(setPrototype(obj
, null), obj
);
2047 assertStrictEquals(setPrototype(1, Number
.prototype), 1);
2050 it("[[Construct]] throws an error", () => {
2051 assertThrows(() => new setPrototype({}, null));
2054 describe(".length", () => {
2055 it("[[Get]] returns the correct length", () => {
2056 assertStrictEquals(setPrototype
.length
, 2);
2060 describe(".name", () => {
2061 it("[[Get]] returns the correct name", () => {
2062 assertStrictEquals(setPrototype
.name
, "setPrototype");
2067 describe("toObject", () => {
2068 it("returns the input for objects", () => {
2070 assertStrictEquals(toObject(obj
), obj
);
2073 it("throws for nullish values", () => {
2074 assertThrows(() => toObject(null));
2075 assertThrows(() => toObject(void {}));
2078 it("returns a wrapper object for other primitives", () => {
2079 const sym
= Symbol();
2080 assertStrictEquals(typeof toObject(sym
), "object");
2081 assertStrictEquals(toObject(sym
).valueOf(), sym
);
2084 it("[[Construct]] throws an error", () => {
2085 assertThrows(() => new toObject({}));
2088 describe(".length", () => {
2089 it("[[Get]] returns the correct length", () => {
2090 assertStrictEquals(toObject
.length
, 1);
2094 describe(".name", () => {
2095 it("[[Get]] returns the correct name", () => {
2096 assertStrictEquals(toObject
.name
, "toObject");
2101 describe("toPropertyDescriptorRecord", () => {
2102 it("[[Call]] creates a new property descriptor record", () => {
2104 const desc
= toPropertyDescriptorRecord(obj
);
2105 assertEquals(obj
, desc
);
2106 assertNotStrictEquals(obj
, desc
);
2109 it("[[Call]] coerces the values", () => {
2111 toPropertyDescriptorRecord({
2112 configurable: undefined,
2113 enumerable: undefined,
2114 writable: undefined,
2116 { configurable: false, enumerable: false, writable: false },
2120 it("[[Construct]] throws for primitives", () => {
2121 assertThrows(() => toPropertyDescriptorRecord(undefined));
2122 assertThrows(() => toPropertyDescriptorRecord("failure"));
2125 it("[[Construct]] throws an error", () => {
2126 assertThrows(() => new toPropertyDescriptorRecord({}));
2129 describe(".length", () => {
2130 it("[[Get]] returns the correct length", () => {
2131 assertStrictEquals(toPropertyDescriptorRecord
.length
, 1);
2135 describe(".name", () => {
2136 it("[[Get]] returns the correct name", () => {
2138 toPropertyDescriptorRecord
.name
,
2139 "toPropertyDescriptorRecord",
2144 describe("~configurable", () => {
2145 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2146 const desc
= toPropertyDescriptorRecord({});
2147 Object
.defineProperty(desc
, "configurable", {});
2148 assertStrictEquals(desc
.configurable
, false);
2151 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2152 const desc
= toPropertyDescriptorRecord({});
2154 Object
.defineProperty(desc
, "configurable", { get: undefined })
2158 it("[[Set]] coerces to a boolean", () => {
2159 const desc
= toPropertyDescriptorRecord({});
2160 desc
.configurable
= undefined;
2161 assertStrictEquals(desc
.configurable
, false);
2164 it("[[Delete]] works", () => {
2165 const desc
= toPropertyDescriptorRecord({ configurable: false });
2166 delete desc
.configurable
;
2167 assert(!("configurable" in desc
));
2171 describe("~enumerable", () => {
2172 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2173 const desc
= toPropertyDescriptorRecord({});
2174 Object
.defineProperty(desc
, "enumerable", {});
2175 assertStrictEquals(desc
.enumerable
, false);
2178 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2179 const desc
= toPropertyDescriptorRecord({});
2181 Object
.defineProperty(desc
, "enumerable", { get: undefined })
2185 it("[[Set]] coerces to a boolean", () => {
2186 const desc
= toPropertyDescriptorRecord({});
2187 desc
.enumerable
= undefined;
2188 assertStrictEquals(desc
.enumerable
, false);
2191 it("[[Delete]] works", () => {
2192 const desc
= toPropertyDescriptorRecord({ enumerable: false });
2193 delete desc
.enumerable
;
2194 assert(!("enumerable" in desc
));
2198 describe("~get", () => {
2199 it("[[DefineOwnProperty]] works", () => {
2200 const desc
= toPropertyDescriptorRecord({});
2201 Object
.defineProperty(desc
, "get", {});
2202 assertStrictEquals(desc
.get, undefined);
2205 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2206 const desc
= toPropertyDescriptorRecord({});
2208 Object
.defineProperty(desc
, "get", { get: undefined })
2212 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
2213 const desc
= toPropertyDescriptorRecord({});
2215 () => Object
.defineProperty(desc
, "get", { value: null }),
2219 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
2220 const desc
= toPropertyDescriptorRecord({ value: undefined });
2221 assertThrows(() => Object
.defineProperty(desc
, "get", {}));
2224 it("[[Set]] works", () => {
2225 const desc
= toPropertyDescriptorRecord({});
2226 const fn
= () => {};
2228 assertStrictEquals(desc
.get, fn
);
2231 it("[[Set]] throws if not callable or undefined", () => {
2232 const desc
= toPropertyDescriptorRecord({});
2233 assertThrows(() => desc
.get = null);
2236 it("[[Set]] throws if a data property is defined", () => {
2237 const desc
= toPropertyDescriptorRecord({ value: undefined });
2238 assertThrows(() => desc
.get = undefined);
2241 it("[[Delete]] works", () => {
2242 const desc
= toPropertyDescriptorRecord({ get: undefined });
2244 assert(!("get" in desc
));
2248 describe("~set", () => {
2249 it("[[DefineOwnProperty]] works", () => {
2250 const desc
= toPropertyDescriptorRecord({});
2251 Object
.defineProperty(desc
, "set", {});
2252 assertStrictEquals(desc
.set, undefined);
2255 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2256 const desc
= toPropertyDescriptorRecord({});
2258 Object
.defineProperty(desc
, "set", { get: undefined })
2262 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
2263 const desc
= toPropertyDescriptorRecord({});
2265 () => Object
.defineProperty(desc
, "set", { value: null }),
2269 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
2270 const desc
= toPropertyDescriptorRecord({ value: undefined });
2271 assertThrows(() => Object
.defineProperty(desc
, "set", {}));
2274 it("[[Set]] works", () => {
2275 const desc
= toPropertyDescriptorRecord({});
2276 const fn
= (_
) => {};
2278 assertStrictEquals(desc
.set, fn
);
2281 it("[[Set]] throws if not callable or undefined", () => {
2282 const desc
= toPropertyDescriptorRecord({});
2283 assertThrows(() => desc
.set = null);
2286 it("[[Set]] throws if a data property is defined", () => {
2287 const desc
= toPropertyDescriptorRecord({ value: undefined });
2288 assertThrows(() => desc
.set = undefined);
2291 it("[[Delete]] works", () => {
2292 const desc
= toPropertyDescriptorRecord({ set: undefined });
2294 assert(!("set" in desc
));
2298 describe("~value", () => {
2299 it("[[DefineOwnProperty]] works", () => {
2300 const desc
= toPropertyDescriptorRecord({});
2301 Object
.defineProperty(desc
, "value", {});
2302 assertStrictEquals(desc
.value
, undefined);
2305 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2306 const desc
= toPropertyDescriptorRecord({});
2308 Object
.defineProperty(desc
, "value", { get: undefined })
2312 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
2313 const desc
= toPropertyDescriptorRecord({ get: undefined });
2314 assertThrows(() => Object
.defineProperty(desc
, "value", {}));
2317 it("[[Set]] works", () => {
2318 const desc
= toPropertyDescriptorRecord({});
2319 desc
.value
= "success";
2320 assertStrictEquals(desc
.value
, "success");
2323 it("[[Set]] throws if an accessor property is defined", () => {
2324 const desc
= toPropertyDescriptorRecord({ get: undefined });
2325 assertThrows(() => desc
.value
= null);
2328 it("[[Delete]] works", () => {
2329 const desc
= toPropertyDescriptorRecord({ value: undefined });
2331 assert(!("value" in desc
));
2335 describe("~writable", () => {
2336 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2337 const desc
= toPropertyDescriptorRecord({});
2338 Object
.defineProperty(desc
, "writable", {});
2339 assertStrictEquals(desc
.writable
, false);
2342 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2343 const desc
= toPropertyDescriptorRecord({});
2345 Object
.defineProperty(desc
, "writable", { get: undefined })
2349 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
2350 const desc
= toPropertyDescriptorRecord({ get: undefined });
2351 assertThrows(() => Object
.defineProperty(desc
, "writable", {}));
2354 it("[[Set]] coerces to a boolean", () => {
2355 const desc
= toPropertyDescriptorRecord({});
2356 desc
.writable
= undefined;
2357 assertStrictEquals(desc
.writable
, false);
2360 it("[[Set]] throws if an accessor property is defined", () => {
2361 const desc
= toPropertyDescriptorRecord({ get: undefined });
2362 assertThrows(() => desc
.writable
= false);
2365 it("[[Delete]] works", () => {
2366 const desc
= toPropertyDescriptorRecord({ writable: false });
2367 delete desc
.writable
;
2368 assert(!("writable" in desc
));