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/>.
13 assertNotStrictEquals
,
21 } from "./dev-deps.js";
23 defineOwnDataProperty
,
24 defineOwnNonenumerableDataProperty
,
31 getOwnPropertyDescriptor
,
32 getOwnPropertyDescriptors
,
33 getOwnPropertyEntries
,
35 getOwnPropertyStrings
,
36 getOwnPropertySymbols
,
44 isConcatSpreadableObject
,
46 isPropertyDescriptorRecord
,
62 toPropertyDescriptorRecord
,
65 describe("LazyLoader", () => {
66 const symbol
= Symbol("foo");
68 const etaoinMethod
= spy(() => "success");
69 const shrdluMethod
= spy(() => "success");
70 const cmfwypMethod
= spy(() => "success");
71 const vbgkqjMethod
= spy(() => "success");
72 const methodsObject
= Object
.create(
102 xz
fiflffffi: { configurable
: true, enumerable
: false, set(_
) {} },
112 it("[[Call]] throws an error", () => {
113 assertThrows(() => LazyLoader({}));
116 it("[[Construct]] creates a new object which inherits from the correct prototype", () => {
118 Object
.getPrototypeOf(new LazyLoader(methodsObject
)),
123 it("[[Construct]] creates a new object with the desired properties", () => {
125 Reflect
.ownKeys(new LazyLoader(methodsObject
)),
126 ["etaoin", "shrdlu", "cmfwyp", "vbgkqj", "xzfiflffffi", symbol
],
130 it("[[Construct]] creates a new object with configurable properties", () => {
134 for (const key
of Reflect
.ownKeys(ll
)) {
137 Object
.getOwnPropertyDescriptor(ll
, key
).configurable
,
140 }(new LazyLoader(methodsObject
)),
153 it("[[Construct]] creates a new object with the correct enumerability", () => {
157 for (const key
of Reflect
.ownKeys(ll
)) {
160 Object
.getOwnPropertyDescriptor(ll
, key
).enumerable
,
163 }(new LazyLoader(methodsObject
)),
176 it("[[Construct]] creates a new object with defined getters", () => {
180 for (const key
of Reflect
.ownKeys(ll
)) {
183 Object
.getOwnPropertyDescriptor(ll
, key
).get?.name
,
186 }(new LazyLoader(methodsObject
)),
189 etaoin
: "get etaoin",
190 shrdlu
: "get shrdlu",
191 cmfwyp
: "get cmfwyp",
192 vbgkqj
: "get vbgkqj",
193 xz
fiflffffi: "get xzfiflffffi",
194 [symbol
]: `get [${symbol.description}]`,
199 it("[[Construct]] creates a new object with defined setters for writable properties only", () => {
203 for (const key
of Reflect
.ownKeys(ll
)) {
206 Object
.getOwnPropertyDescriptor(ll
, key
).set?.name
,
209 }(new LazyLoader(methodsObject
)),
217 [symbol
]: `set [${symbol.description}]`,
222 it("[[Construct]] creates a new object with correct getter behaviour", () => {
223 const ll
= new LazyLoader(methodsObject
);
226 Object
.getOwnPropertyDescriptor(ll
, "etaoin"),
234 assertSpyCalls(etaoinMethod
, 1);
235 assertSpyCall(etaoinMethod
, 0, {
242 Object
.getOwnPropertyDescriptor(ll
, "shrdlu"),
250 assertSpyCalls(shrdluMethod
, 1);
251 assertSpyCall(shrdluMethod
, 0, {
258 Object
.getOwnPropertyDescriptor(ll
, "cmfwyp"),
266 assertSpyCalls(cmfwypMethod
, 1);
267 assertSpyCall(cmfwypMethod
, 0, {
274 Object
.getOwnPropertyDescriptor(ll
, "vbgkqj"),
282 assertSpyCalls(vbgkqjMethod
, 1);
283 assertSpyCall(vbgkqjMethod
, 0, {
288 assertThrows(() => ll
.xz
fiflffffi);
289 assertThrows(() => ll
[symbol
]);
292 it("[[Construct]] creates a new object with correct setter behaviour", () => {
293 const ll
= new LazyLoader(methodsObject
);
294 ll
[symbol
] = "success";
296 Object
.getOwnPropertyDescriptor(ll
, symbol
),
306 describe(".length", () => {
307 it("[[Get]] returns the correct length", () => {
308 assertStrictEquals(LazyLoader
.length
, 1);
312 describe(".name", () => {
313 it("[[Get]] returns the correct name", () => {
314 assertStrictEquals(LazyLoader
.name
, "LazyLoader");
319 describe("defineOwnDataProperty", () => {
320 it("[[Call]] defines the property", () => {
322 defineOwnDataProperty(obj
, "etaoin", "success");
323 assert(Object
.hasOwn(obj
, "etaoin"));
324 assertStrictEquals(obj
.etaoin
, "success");
327 it("[[Call]] defines a configurable, enumerable, writable property", () => {
329 defineOwnDataProperty(obj
, "etaoin", "success");
331 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
341 it("[[Call]] returns the provided object", () => {
344 defineOwnDataProperty(obj
, "etaoin", null),
349 it("[[Construct]] throws an error", () => {
350 assertThrows(() => new defineOwnDataProperty(obj
, "etaoin", null));
353 describe(".length", () => {
354 it("[[Get]] returns the correct length", () => {
355 assertStrictEquals(defineOwnDataProperty
.length
, 3);
359 describe(".name", () => {
360 it("[[Get]] returns the correct name", () => {
362 defineOwnDataProperty
.name
,
363 "defineOwnDataProperty",
369 describe("defineOwnNonenumerableDataProperty", () => {
370 it("[[Call]] defines the property", () => {
372 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
373 assert(Object
.hasOwn(obj
, "etaoin"));
374 assertStrictEquals(obj
.etaoin
, "success");
377 it("[[Call]] defines a configurable, non·enumerable, writable property", () => {
379 defineOwnNonenumerableDataProperty(obj
, "etaoin", "success");
381 Object
.getOwnPropertyDescriptor(obj
, "etaoin"),
391 it("[[Call]] returns the provided object", () => {
394 defineOwnNonenumerableDataProperty(obj
, "etaoin", null),
399 it("[[Construct]] throws an error", () => {
401 new defineOwnNonenumerableDataProperty(obj
, "etaoin", null)
405 describe(".length", () => {
406 it("[[Get]] returns the correct length", () => {
407 assertStrictEquals(defineOwnNonenumerableDataProperty
.length
, 3);
411 describe(".name", () => {
412 it("[[Get]] returns the correct name", () => {
414 defineOwnNonenumerableDataProperty
.name
,
415 "defineOwnNonenumerableDataProperty",
421 describe("defineOwnProperty", () => {
422 it("[[Call]] defines the property", () => {
424 defineOwnProperty(obj
, "etaoin", {});
425 assert(Object
.hasOwn(obj
, "etaoin"));
428 it("[[Call]] returns the provided object", () => {
430 assertStrictEquals(defineOwnProperty(obj
, "etaoin", {}), obj
);
433 it("[[Construct]] throws an error", () => {
434 assertThrows(() => new defineOwnProperty(obj
, "etaoin", {}));
437 describe(".length", () => {
438 it("[[Get]] returns the correct length", () => {
439 assertStrictEquals(defineOwnProperty
.length
, 3);
443 describe(".name", () => {
444 it("[[Get]] returns the correct name", () => {
446 defineOwnProperty
.name
,
453 describe("defineOwnProperties", () => {
454 it("[[Call]] defines properties from the provided objects", () => {
456 defineOwnProperties(obj
, {
460 assert("etaoin" in obj
);
461 assert("shrdlu" in obj
);
462 assert("cmfwyp" in obj
);
465 it("[[Call]] overrides earlier declarations with later ones", () => {
466 const obj
= { etaoin
: undefined };
467 defineOwnProperties(obj
, {
468 etaoin
: { value
: "failure" },
470 etaoin
: { value
: "success" },
472 assertStrictEquals(obj
.etaoin
, "success");
475 it("[[Call]] returns the provided object", () => {
477 assertStrictEquals(defineOwnProperties(obj
), obj
);
480 it("[[Construct]] throws an error", () => {
481 assertThrows(() => new defineOwnProperties({}));
484 describe(".length", () => {
485 it("[[Get]] returns the correct length", () => {
486 assertStrictEquals(defineOwnProperties
.length
, 1);
490 describe(".name", () => {
491 it("[[Get]] returns the correct name", () => {
493 defineOwnProperties
.name
,
494 "defineOwnProperties",
500 describe("deleteOwnProperty", () => {
501 it("[[Call]] deletes the provided property on the provided object", () => {
502 const obj
= { failure
: undefined };
503 deleteOwnProperty(obj
, "failure");
504 assert(!("failure" in obj
));
507 it("[[Call]] does nothing if the property doesn’t exist", () => {
508 const obj
= Object
.freeze({});
509 deleteOwnProperty(obj
, "failure");
510 assert(!("failure" in obj
));
513 it("[[Call]] throws if the property can’t be deleted", () => {
514 const obj
= Object
.seal({ failure
: undefined });
515 assertThrows(() => deleteOwnProperty(obj
, "failure"));
518 it("[[Call]] returns the provided object", () => {
520 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
523 it("[[Construct]] throws an error", () => {
524 assertThrows(() => new deleteOwnProperty({}, ""));
527 describe(".length", () => {
528 it("[[Get]] returns the correct length", () => {
529 assertStrictEquals(deleteOwnProperty
.length
, 2);
533 describe(".name", () => {
534 it("[[Get]] returns the correct name", () => {
535 assertStrictEquals(deleteOwnProperty
.name
, "deleteOwnProperty");
540 describe("freeze", () => {
541 it("[[Call]] freezes the object", () => {
544 assert(Object
.isFrozen(obj
));
547 it("[[Call]] returns the provided object", () => {
549 assertStrictEquals(freeze(obj
), obj
);
552 it("[[Construct]] throws an error", () => {
553 assertThrows(() => new freeze({}));
556 describe(".length", () => {
557 it("[[Get]] returns the correct length", () => {
558 assertStrictEquals(freeze
.length
, 1);
562 describe(".name", () => {
563 it("[[Get]] returns the correct name", () => {
564 assertStrictEquals(freeze
.name
, "freeze");
569 describe("frozenCopy", () => {
570 it("[[Call]] returns a frozen object", () => {
573 frozenCopy(Object
.create(null), {
590 it("[[Call]] ignores non·enumerable properties", () => {
593 Object
.create(null, {
594 data
: { value
: undefined },
595 accessor
: { get: undefined },
602 it("[[Call]] preserves accessor properties", () => {
630 Object
.getOwnPropertyDescriptors(
631 frozenCopy(Object
.create(null, properties
)),
637 it("[[Call]] preserves data properties", () => {
657 Object
.getOwnPropertyDescriptors(
658 frozenCopy(Object
.create(null, properties
)),
662 ...properties
.implied
,
666 writable
: { ...properties
.writable
, writable
: false },
667 nonwritable
: properties
.nonwritable
,
672 it("[[Call]] does not copy properties on the prototype", () => {
675 frozenCopy(Object
.create({ failure
: undefined }))),
679 it("[[Call]] uses the species of the constructor", () => {
680 const species
= { prototype: {} };
682 Object
.getPrototypeOf(
683 frozenCopy({}, { [Symbol
.species
]: species
}),
689 it("[[Call]] uses constructor if no species is defined", () => {
690 const constructor = { [Symbol
.species
]: null, prototype: {} };
692 Object
.getPrototypeOf(frozenCopy({}, constructor)),
693 constructor.prototype,
697 it("[[Call]] uses the constructor on the object if none is provided", () => {
698 const constructor = { [Symbol
.species
]: null, prototype: {} };
700 Object
.getPrototypeOf(frozenCopy({ constructor })),
701 constructor.prototype,
705 it("[[Call]] allows a null constructor", () => {
707 Object
.getPrototypeOf(frozenCopy({}, null)),
712 it("[[Construct]] throws an error", () => {
713 assertThrows(() => new frozenCopy({}));
716 describe(".length", () => {
717 it("[[Get]] returns the correct length", () => {
718 assertStrictEquals(frozenCopy
.length
, 1);
722 describe(".name", () => {
723 it("[[Get]] returns the correct name", () => {
724 assertStrictEquals(frozenCopy
.name
, "frozenCopy");
729 describe("getMethod", () => {
730 it("[[Call]] gets a method", () => {
731 const method
= () => {};
732 assertStrictEquals(getMethod({ method
}, "method"), method
);
735 it("[[Call]] works for values coercible to objects", () => {
736 assertEquals(getMethod("", "toString"), String
.prototype.toString
);
739 it("[[Call]] throws for null and undefined", () => {
740 assertThrows(() => getMethod(null, "valueOf"));
741 assertThrows(() => getMethod(undefined, "valueOf"));
744 it("[[Call]] throws if the resulting value isn’t callable", () => {
745 assertThrows(() => getMethod({ "failure": true }, "failure"));
748 it("[[Construct]] throws an error", () => {
749 assertThrows(() => new getMethod({ method() {} }, "method"));
752 describe(".length", () => {
753 it("[[Get]] returns the correct length", () => {
754 assertStrictEquals(getMethod
.length
, 2);
758 describe(".name", () => {
759 it("[[Get]] returns the correct name", () => {
760 assertStrictEquals(getMethod
.name
, "getMethod");
765 describe("getOwnPropertyDescriptor", () => {
766 it("[[Call]] gets the descriptor", () => {
768 getOwnPropertyDescriptor({ success
: true }, "success"),
778 it("[[Call]] returns undefined for non‐own properties", () => {
780 getOwnPropertyDescriptor({}, "valueOf"),
785 it("[[Construct]] throws an error", () => {
786 assertThrows(() => new getOwnPropertyDescriptor({}, ""));
789 describe(".length", () => {
790 it("[[Get]] returns the correct length", () => {
791 assertStrictEquals(getOwnPropertyDescriptor
.length
, 2);
795 describe(".name", () => {
796 it("[[Get]] returns the correct name", () => {
798 getOwnPropertyDescriptor
.name
,
799 "getOwnPropertyDescriptor",
805 describe("getOwnPropertyDescriptors", () => {
806 it("[[Call]] gets the descriptors", () => {
808 getOwnPropertyDescriptors({ success
: true, etaoin
: "shrdlu" }),
826 it("[[Construct]] throws an error", () => {
827 assertThrows(() => new getOwnPropertyDescriptors({}));
830 describe(".length", () => {
831 it("[[Get]] returns the correct length", () => {
832 assertStrictEquals(getOwnPropertyDescriptors
.length
, 1);
836 describe(".name", () => {
837 it("[[Get]] returns the correct name", () => {
839 getOwnPropertyDescriptors
.name
,
840 "getOwnPropertyDescriptors",
846 describe("getOwnPropertyEntries", () => {
847 it("[[Call]] gets own (but not inherited) property entries", () => {
849 getOwnPropertyEntries({ success
: true }),
854 it("[[Call]] works for values coercible to objects", () => {
856 getOwnPropertyEntries("foo"),
857 [["0", "f"], ["1", "o"], ["2", "o"], ["length", 3]],
861 it("[[Call]] uses the provided receiver", () => {
864 getOwnPropertyEntries({
869 [["success", target
]],
873 it("[[Call]] throws for null and undefined", () => {
874 assertThrows(() => getOwnPropertyEntries(null));
875 assertThrows(() => getOwnPropertyEntries(undefined));
878 it("[[Construct]] throws an error", () => {
879 assertThrows(() => new getOwnPropertyEntries({}));
882 describe(".length", () => {
883 it("[[Get]] returns the correct length", () => {
884 assertStrictEquals(getOwnPropertyEntries
.length
, 1);
888 describe(".name", () => {
889 it("[[Get]] returns the correct name", () => {
891 getOwnPropertyEntries
.name
,
892 "getOwnPropertyEntries",
898 describe("getOwnPropertyKeys", () => {
899 it("[[Call]] gets own (but not inherited) property keys", () => {
900 assertEquals(getOwnPropertyKeys({ success
: true }), ["success"]);
903 it("[[Call]] works for values coercible to objects", () => {
904 assertEquals(getOwnPropertyKeys("foo"), ["0", "1", "2", "length"]);
907 it("[[Call]] throws for null and undefined", () => {
908 assertThrows(() => getOwnPropertyKeys(null));
909 assertThrows(() => getOwnPropertyKeys(undefined));
912 it("[[Construct]] throws an error", () => {
913 assertThrows(() => new getOwnPropertyKeys({}));
916 describe(".length", () => {
917 it("[[Get]] returns the correct length", () => {
918 assertStrictEquals(getOwnPropertyKeys
.length
, 1);
922 describe(".name", () => {
923 it("[[Get]] returns the correct name", () => {
925 getOwnPropertyKeys
.name
,
926 "getOwnPropertyKeys",
932 describe("getOwnPropertyStrings", () => {
933 it("[[Call]] gets own string keys", () => {
934 assertEquals(getOwnPropertyStrings({ success
: true }), [
939 it("[[Call]] works for values coercible to objects", () => {
940 assertEquals(getOwnPropertyStrings("foo"), [
948 it("[[Call]] throws for null and undefined", () => {
949 assertThrows(() => getOwnPropertyStrings(null));
950 assertThrows(() => getOwnPropertyStrings(undefined));
953 it("[[Construct]] throws an error", () => {
954 assertThrows(() => new getOwnPropertyStrings({}));
957 describe(".length", () => {
958 it("[[Get]] returns the correct length", () => {
959 assertStrictEquals(getOwnPropertyStrings
.length
, 1);
963 describe(".name", () => {
964 it("[[Get]] returns the correct name", () => {
966 getOwnPropertyStrings
.name
,
967 "getOwnPropertyStrings",
973 describe("getOwnPropertySymbols", () => {
974 it("[[Call]] gets own symbol keys", () => {
975 const sym
= Symbol();
976 assertEquals(getOwnPropertySymbols({ [sym
]: true }), [sym
]);
979 it("[[Call]] works for values coercible to objects", () => {
980 assertEquals(getOwnPropertySymbols("foo"), []);
983 it("[[Call]] throws for null and undefined", () => {
984 assertThrows(() => getOwnPropertySymbols(null));
985 assertThrows(() => getOwnPropertySymbols(undefined));
988 it("[[Construct]] throws an error", () => {
989 assertThrows(() => new getOwnPropertySymbols({}));
992 describe(".length", () => {
993 it("[[Get]] returns the correct length", () => {
994 assertStrictEquals(getOwnPropertySymbols
.length
, 1);
998 describe(".name", () => {
999 it("[[Get]] returns the correct name", () => {
1001 getOwnPropertySymbols
.name
,
1002 "getOwnPropertySymbols",
1008 describe("getOwnPropertyValue", () => {
1009 it("[[Call]] gets the own property value", () => {
1011 getOwnPropertyValue({ success
: true }, "success"),
1016 it("[[Call]] returns undefined for non‐own properties", () => {
1018 getOwnPropertyValue(Object
.create({ success
: true }), "success"),
1023 it("[[Call]] works for values coercible to objects", () => {
1024 assertStrictEquals(getOwnPropertyValue("foo", "length"), 3);
1027 it("[[Call]] uses the provided receiver", () => {
1030 getOwnPropertyValue(
1043 it("[[Call]] throws for null and undefined", () => {
1044 assertThrows(() => getOwnPropertyValue(null));
1045 assertThrows(() => getOwnPropertyValue(undefined));
1048 it("[[Construct]] throws an error", () => {
1049 assertThrows(() => new getOwnPropertyValue({}));
1052 describe(".length", () => {
1053 it("[[Get]] returns the correct length", () => {
1054 assertStrictEquals(getOwnPropertyValue
.length
, 2);
1058 describe(".name", () => {
1059 it("[[Get]] returns the correct name", () => {
1061 getOwnPropertyValue
.name
,
1062 "getOwnPropertyValue",
1068 describe("getOwnPropertyValues", () => {
1069 it("[[Call]] gets own (but not inherited) property values", () => {
1070 assertEquals(getOwnPropertyValues({ success
: true }), [true]);
1073 it("[[Call]] works for values coercible to objects", () => {
1075 getOwnPropertyValues("foo"),
1080 it("[[Call]] uses the provided receiver", () => {
1083 getOwnPropertyValues({
1092 it("[[Call]] throws for null and undefined", () => {
1093 assertThrows(() => getOwnPropertyValues(null));
1094 assertThrows(() => getOwnPropertyValues(undefined));
1097 it("[[Construct]] throws an error", () => {
1098 assertThrows(() => new getOwnPropertyValues({}));
1101 describe(".length", () => {
1102 it("[[Get]] returns the correct length", () => {
1103 assertStrictEquals(getOwnPropertyValues
.length
, 1);
1107 describe(".name", () => {
1108 it("[[Get]] returns the correct name", () => {
1110 getOwnPropertyValues
.name
,
1111 "getOwnPropertyValues",
1117 describe("getPropertyValue", () => {
1118 it("[[Call]] gets property values on the provided object", () => {
1120 getPropertyValue({ success
: true }, "success"),
1125 it("[[Call]] works for values coercible to objects", () => {
1127 getPropertyValue("", "toString"),
1128 String
.prototype.toString
,
1132 it("[[Call]] throws for null and undefined", () => {
1133 assertThrows(() => getPropertyValue(null, "valueOf"));
1134 assertThrows(() => getPropertyValue(undefined, "valueOf"));
1137 it("[[Construct]] throws an error", () => {
1138 assertThrows(() => new getPropertyValue({}, "valueOf"));
1141 describe(".length", () => {
1142 it("[[Get]] returns the correct length", () => {
1143 assertStrictEquals(getPropertyValue
.length
, 2);
1147 describe(".name", () => {
1148 it("[[Get]] returns the correct name", () => {
1149 assertStrictEquals(getPropertyValue
.name
, "getPropertyValue");
1154 describe("getPrototype", () => {
1155 it("[[Call]] gets object prototypes", () => {
1156 assertStrictEquals(getPrototype({}), Object
.prototype);
1158 assertStrictEquals(getPrototype(Object
.create(proto
)), proto
);
1161 it("[[Call]] gets null prototypes", () => {
1162 assertStrictEquals(getPrototype(Object
.create(null)), null);
1165 it("[[Call]] gets prototypes for coercible primitives", () => {
1166 assertStrictEquals(getPrototype(1), Number
.prototype);
1167 assertStrictEquals(getPrototype(Symbol()), Symbol
.prototype);
1170 it("[[Call]] throws for null and undefined", () => {
1171 assertThrows(() => getPrototype(null));
1172 assertThrows(() => getPrototype(undefined));
1175 it("[[Construct]] throws an error", () => {
1176 assertThrows(() => new getPrototype({}));
1179 describe(".length", () => {
1180 it("[[Get]] returns the correct length", () => {
1181 assertStrictEquals(getPrototype
.length
, 1);
1185 describe(".name", () => {
1186 it("[[Get]] returns the correct name", () => {
1187 assertStrictEquals(getPrototype
.name
, "getPrototype");
1192 describe("hasProperty", () => {
1193 it("[[Call]] gets whether a property exists on the provided object", () => {
1195 hasProperty({ success
: "etaoin" }, "success"),
1198 assertStrictEquals(hasProperty({}, "hasOwnProperty"), true);
1201 it("[[Call]] works for values coercible to objects", () => {
1202 assertStrictEquals(hasProperty("", "length"), true);
1203 assertStrictEquals(hasProperty("", "toString"), true);
1206 it("[[Call]] throws for null and undefined", () => {
1207 assertThrows(() => hasProperty(null, "valueOf"));
1208 assertThrows(() => hasProperty(undefined, "valueOf"));
1211 it("[[Construct]] throws an error", () => {
1212 assertThrows(() => new hasProperty({}, "valueOf"));
1215 describe(".length", () => {
1216 it("[[Get]] returns the correct length", () => {
1217 assertStrictEquals(hasProperty
.length
, 2);
1221 describe(".name", () => {
1222 it("[[Get]] returns the correct name", () => {
1223 assertStrictEquals(hasProperty
.name
, "hasProperty");
1228 describe("hasOwnProperty", () => {
1229 it("[[Call]] gets whether an own property exists on the provided object", () => {
1231 hasOwnProperty({ success
: "etaoin" }, "success"),
1234 assertStrictEquals(hasOwnProperty({}, "hasOwnProperty"), false);
1237 it("[[Call]] works for values coercible to objects", () => {
1238 assertStrictEquals(hasOwnProperty("", "length"), true);
1239 assertStrictEquals(hasOwnProperty("", "toString"), false);
1242 it("[[Call]] throws for null and undefined", () => {
1243 assertThrows(() => hasOwnProperty(null, "valueOf"));
1244 assertThrows(() => hasOwnProperty(undefined, "valueOf"));
1247 it("[[Construct]] throws an error", () => {
1248 assertThrows(() => new hasOwnProperty({}, "valueOf"));
1251 describe(".length", () => {
1252 it("[[Get]] returns the correct length", () => {
1253 assertStrictEquals(hasOwnProperty
.length
, 2);
1257 describe(".name", () => {
1258 it("[[Get]] returns the correct name", () => {
1259 assertStrictEquals(hasOwnProperty
.name
, "hasOwnProperty");
1264 describe("isArraylikeObject", () => {
1265 it("[[Call]] returns false for primitives", () => {
1266 assertStrictEquals(isArraylikeObject("failure"), false);
1269 it("[[Call]] returns false if length throws", () => {
1280 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
1281 assertStrictEquals(isArraylikeObject({ length
: 1n
}), false);
1284 it("[[Call]] returns true if length is convertable to a number", () => {
1285 assertStrictEquals(isArraylikeObject({ length
: -0 }), true);
1286 assertStrictEquals(isArraylikeObject({ length
: 1 }), true);
1287 assertStrictEquals(isArraylikeObject({ length
: -1.25 }), true);
1289 isArraylikeObject({ length
: 9007199254740992 }),
1292 assertStrictEquals(isArraylikeObject({ length
: Infinity
}), true);
1293 assertStrictEquals(isArraylikeObject({ length
: "success" }), true);
1296 it("[[Construct]] throws an error", () => {
1297 assertThrows(() => new isArraylikeObject({}));
1300 describe(".length", () => {
1301 it("[[Get]] returns the correct length", () => {
1302 assertStrictEquals(isArraylikeObject
.length
, 1);
1306 describe(".name", () => {
1307 it("[[Get]] returns the correct name", () => {
1309 isArraylikeObject
.name
,
1310 "isArraylikeObject",
1316 describe("isConcatSpreadableObject", () => {
1317 it("[[Call]] returns false for primitives", () => {
1318 assertStrictEquals(isConcatSpreadableObject("failure"), false);
1321 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
1323 isConcatSpreadableObject(
1324 Object
.assign([], { [Symbol
.isConcatSpreadable
]: null }),
1329 isConcatSpreadableObject(
1330 Object
.assign([], { [Symbol
.isConcatSpreadable
]: false }),
1336 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
1338 isConcatSpreadableObject(
1339 Object
.assign([], { [Symbol
.isConcatSpreadable
]: undefined }),
1345 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
1347 isConcatSpreadableObject({ [Symbol
.isConcatSpreadable
]: true }),
1352 it("[[Construct]] throws an error", () => {
1353 assertThrows(() => new isConcatSpreadableObject({}));
1356 describe(".length", () => {
1357 it("[[Get]] returns the correct length", () => {
1358 assertStrictEquals(isConcatSpreadableObject
.length
, 1);
1362 describe(".name", () => {
1363 it("[[Get]] returns the correct name", () => {
1365 isConcatSpreadableObject
.name
,
1366 "isConcatSpreadableObject",
1372 describe("isExtensibleObject", () => {
1373 it("[[Call]] returns true for extensible objects", () => {
1374 assertStrictEquals(isExtensibleObject({}), true);
1377 it("[[Call]] returns false for coercible primitives", () => {
1378 assertStrictEquals(isExtensibleObject(1), false);
1379 assertStrictEquals(isExtensibleObject(Symbol()), false);
1382 it("[[Call]] returns false for non·extensible objects", () => {
1384 isExtensibleObject(Object
.preventExtensions({})),
1389 it("[[Call]] returns false for null and undefined", () => {
1390 assertStrictEquals(isExtensibleObject(null), false);
1391 assertStrictEquals(isExtensibleObject(undefined), false);
1394 it("[[Construct]] throws an error", () => {
1395 assertThrows(() => new isExtensibleObject({}));
1398 describe(".length", () => {
1399 it("[[Get]] returns the correct length", () => {
1400 assertStrictEquals(isExtensibleObject
.length
, 1);
1404 describe(".name", () => {
1405 it("[[Get]] returns the correct name", () => {
1407 isExtensibleObject
.name
,
1408 "isExtensibleObject",
1414 describe("isPropertyDescriptorRecord", () => {
1415 it("[[Call]] returns true for objects created by toPropertyDescriptorRecord", () => {
1417 isPropertyDescriptorRecord(toPropertyDescriptorRecord({})),
1422 it("[[Get]] returns false for other objects", () => {
1424 isPropertyDescriptorRecord(Object
.create(null)),
1429 it("[[Get]] returns false for undefined", () => {
1430 assertStrictEquals(isPropertyDescriptorRecord(undefined), false);
1433 it("[[Construct]] throws an error", () => {
1434 assertThrows(() => new isPropertyDescriptorRecord({}));
1437 describe(".length", () => {
1438 it("[[Get]] returns the correct length", () => {
1439 assertStrictEquals(isPropertyDescriptorRecord
.length
, 1);
1443 describe(".name", () => {
1444 it("[[Get]] returns the correct name", () => {
1446 isPropertyDescriptorRecord
.name
,
1447 "isPropertyDescriptorRecord",
1453 describe("isUnfrozenObject", () => {
1454 it("[[Call]] returns true for unfrozen objects", () => {
1455 assertStrictEquals(isUnfrozenObject({}), true);
1458 it("[[Call]] returns false for coercible primitives", () => {
1459 assertStrictEquals(isUnfrozenObject(1), false);
1460 assertStrictEquals(isUnfrozenObject(Symbol()), false);
1463 it("[[Call]] returns false for frozen objects", () => {
1464 assertStrictEquals(isUnfrozenObject(Object
.freeze({})), false);
1467 it("[[Call]] returns false for null and undefined", () => {
1468 assertStrictEquals(isUnfrozenObject(null), false);
1469 assertStrictEquals(isUnfrozenObject(undefined), false);
1472 it("[[Construct]] throws an error", () => {
1473 assertThrows(() => new isUnfrozenObject({}));
1476 describe(".length", () => {
1477 it("[[Get]] returns the correct length", () => {
1478 assertStrictEquals(isUnfrozenObject
.length
, 1);
1482 describe(".name", () => {
1483 it("[[Get]] returns the correct name", () => {
1484 assertStrictEquals(isUnfrozenObject
.name
, "isUnfrozenObject");
1489 describe("isUnsealedObject", () => {
1490 it("[[Call]] returns true for unsealed objects", () => {
1491 assertStrictEquals(isUnsealedObject({}), true);
1494 it("[[Call]] returns false for coercible primitives", () => {
1495 assertStrictEquals(isUnsealedObject(1), false);
1496 assertStrictEquals(isUnsealedObject(Symbol()), false);
1499 it("[[Call]] returns false for sealed objects", () => {
1500 assertStrictEquals(isUnsealedObject(Object
.seal({})), false);
1503 it("[[Call]] returns false for null and undefined", () => {
1504 assertStrictEquals(isUnsealedObject(null), false);
1505 assertStrictEquals(isUnsealedObject(undefined), false);
1508 it("[[Construct]] throws an error", () => {
1509 assertThrows(() => new isUnsealedObject({}));
1512 describe(".length", () => {
1513 it("[[Get]] returns the correct length", () => {
1514 assertStrictEquals(isUnsealedObject
.length
, 1);
1518 describe(".name", () => {
1519 it("[[Get]] returns the correct name", () => {
1520 assertStrictEquals(isUnsealedObject
.name
, "isUnsealedObject");
1525 describe("lengthOfArraylike", () => {
1526 it("[[Call]] returns the length", () => {
1528 lengthOfArraylike({ length
: 9007199254740991 }),
1533 it("[[Call]] returns a non·nan result", () => {
1534 assertStrictEquals(lengthOfArraylike({ length
: NaN
}), 0);
1535 assertStrictEquals(lengthOfArraylike({ length
: "failure" }), 0);
1538 it("[[Call]] returns an integral result", () => {
1539 assertStrictEquals(lengthOfArraylike({ length
: 0.25 }), 0);
1540 assertStrictEquals(lengthOfArraylike({ length
: 1.1 }), 1);
1543 it("[[Call]] returns a result greater than or equal to zero", () => {
1544 assertStrictEquals(lengthOfArraylike({ length
: -0 }), 0);
1545 assertStrictEquals(lengthOfArraylike({ length
: -1 }), 0);
1546 assertStrictEquals(lengthOfArraylike({ length
: -Infinity
}), 0);
1549 it("[[Call]] returns a result less than 2 ** 53", () => {
1551 lengthOfArraylike({ length
: 9007199254740992 }),
1555 lengthOfArraylike({ length
: Infinity
}),
1560 it("[[Call]] does not require an object argument", () => {
1561 assertStrictEquals(lengthOfArraylike("string"), 6);
1562 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
1565 it("[[Construct]] throws an error", () => {
1566 assertThrows(() => new lengthOfArraylike(""));
1569 describe(".length", () => {
1570 it("[[Get]] returns the correct length", () => {
1571 assertStrictEquals(lengthOfArraylike
.length
, 1);
1575 describe(".name", () => {
1576 it("[[Get]] returns the correct name", () => {
1577 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
1582 describe("namedEntries", () => {
1583 it("[[Call]] gets named entries", () => {
1584 assertEquals(namedEntries({ success
: true }), [["success", true]]);
1587 it("[[Call]] works for values coercible to objects", () => {
1588 assertEquals(namedEntries("foo"), [
1595 it("[[Call]] throws for null and undefined", () => {
1596 assertThrows(() => namedEntries(null));
1597 assertThrows(() => namedEntries(undefined));
1600 it("[[Construct]] throws an error", () => {
1601 assertThrows(() => new namedEntries({}));
1604 describe(".length", () => {
1605 it("[[Get]] returns the correct length", () => {
1606 assertStrictEquals(namedEntries
.length
, 1);
1610 describe(".name", () => {
1611 it("[[Get]] returns the correct name", () => {
1612 assertStrictEquals(namedEntries
.name
, "namedEntries");
1617 describe("namedKeys", () => {
1618 it("[[Call]] gets named keys", () => {
1619 assertEquals(namedKeys({ success
: true }), ["success"]);
1622 it("[[Call]] works for values coercible to objects", () => {
1623 assertEquals(namedKeys("foo"), [
1630 it("[[Call]] throws for null and undefined", () => {
1631 assertThrows(() => namedKeys(null));
1632 assertThrows(() => namedKeys(undefined));
1635 it("[[Construct]] throws an error", () => {
1636 assertThrows(() => new namedKeys({}));
1639 describe(".length", () => {
1640 it("[[Get]] returns the correct length", () => {
1641 assertStrictEquals(namedKeys
.length
, 1);
1645 describe(".name", () => {
1646 it("[[Get]] returns the correct name", () => {
1647 assertStrictEquals(namedKeys
.name
, "namedKeys");
1652 describe("namedValues", () => {
1653 it("[[Call]] gets named values", () => {
1654 assertEquals(namedValues({ success
: true }), [true]);
1657 it("[[Call]] works for values coercible to objects", () => {
1658 assertEquals(namedValues("foo"), [
1665 it("[[Call]] throws for null and undefined", () => {
1666 assertThrows(() => namedValues(null));
1667 assertThrows(() => namedValues(undefined));
1670 it("[[Construct]] throws an error", () => {
1671 assertThrows(() => new namedValues({}));
1674 describe(".length", () => {
1675 it("[[Get]] returns the correct length", () => {
1676 assertStrictEquals(namedValues
.length
, 1);
1680 describe(".name", () => {
1681 it("[[Get]] returns the correct name", () => {
1682 assertStrictEquals(namedValues
.name
, "namedValues");
1687 describe("objectCreate", () => {
1688 it("[[Call]] creates an object", () => {
1689 const obj
= objectCreate(null);
1690 assertStrictEquals(Object(obj
), obj
);
1693 it("[[Call]] correctly sets the prototype", () => {
1696 Object
.getPrototypeOf(objectCreate(proto
)),
1700 Object
.getPrototypeOf(objectCreate(null)),
1705 it("[[Call]] correctly sets own properties", () => {
1707 Object
.getOwnPropertyDescriptors(
1708 objectCreate(null, { success
: { value
: true } }),
1712 configurable
: false,
1721 it("[[Call]] throws for coercible primitives", () => {
1722 assertThrows(() => objectCreate(1));
1723 assertThrows(() => objectCreate(Symbol()));
1726 it("[[Call]] throws for undefined", () => {
1727 assertThrows(() => objectCreate(undefined));
1730 it("[[Construct]] throws an error", () => {
1731 assertThrows(() => new objectCreate({}));
1734 describe(".length", () => {
1735 it("[[Get]] returns the correct length", () => {
1736 assertStrictEquals(objectCreate
.length
, 2);
1740 describe(".name", () => {
1741 it("[[Get]] returns the correct name", () => {
1742 assertStrictEquals(objectCreate
.name
, "objectCreate");
1747 describe("objectFromEntries", () => {
1748 it("[[Call]] creates an object", () => {
1749 const obj
= objectFromEntries([]);
1750 assertStrictEquals(Object(obj
), obj
);
1753 it("[[Call]] correctly sets the prototype", () => {
1755 Object
.getPrototypeOf(objectFromEntries([])),
1760 it("[[Call]] correctly sets own properties", () => {
1762 Object
.entries(objectFromEntries([["success", true]])),
1763 [["success", true]],
1767 it("[[Call]] throws if the argument is not a nested arraylike", () => {
1768 assertThrows(() => objectFromEntries(1));
1769 assertThrows(() => objectFromEntries(Symbol()));
1770 assertThrows(() => objectFromEntries(null));
1771 assertThrows(() => objectFromEntries(undefined));
1772 assertThrows(() => objectFromEntries({}));
1773 assertThrows(() => objectFromEntries([undefined]));
1776 it("[[Construct]] throws an error", () => {
1777 assertThrows(() => new objectFromEntries([]));
1780 describe(".length", () => {
1781 it("[[Get]] returns the correct length", () => {
1782 assertStrictEquals(objectFromEntries
.length
, 1);
1786 describe(".name", () => {
1787 it("[[Get]] returns the correct name", () => {
1788 assertStrictEquals(objectFromEntries
.name
, "objectFromEntries");
1793 describe("preventExtensions", () => {
1794 it("[[Call]] prevents extensions on the object", () => {
1796 preventExtensions(obj
);
1797 assert(!Object
.isExtensible(obj
));
1800 it("[[Call]] returns the provided object", () => {
1802 assertStrictEquals(preventExtensions(obj
), obj
);
1805 it("[[Construct]] throws an error", () => {
1806 assertThrows(() => new preventExtensions({}));
1809 describe(".length", () => {
1810 it("[[Get]] returns the correct length", () => {
1811 assertStrictEquals(preventExtensions
.length
, 1);
1815 describe(".name", () => {
1816 it("[[Get]] returns the correct name", () => {
1817 assertStrictEquals(preventExtensions
.name
, "preventExtensions");
1822 describe("seal", () => {
1823 it("[[Call]] seals the object", () => {
1826 assert(Object
.isSealed(obj
));
1829 it("[[Call]] returns the provided object", () => {
1831 assertStrictEquals(seal(obj
), obj
);
1834 it("[[Construct]] throws an error", () => {
1835 assertThrows(() => new seal({}));
1838 describe(".length", () => {
1839 it("[[Get]] returns the correct length", () => {
1840 assertStrictEquals(seal
.length
, 1);
1844 describe(".name", () => {
1845 it("[[Get]] returns the correct name", () => {
1846 assertStrictEquals(seal
.name
, "seal");
1851 describe("setPropertyValue", () => {
1852 it("[[Call]] sets the provided property on the provided object", () => {
1854 setPropertyValue(obj
, "success", true);
1855 assertStrictEquals(obj
.success
, true);
1858 it("[[Call]] calls setters", () => {
1859 const setter
= spy((_
) => {});
1860 const obj
= Object
.create(null, { success
: { set: setter
} });
1861 setPropertyValue(obj
, "success", true);
1862 assertSpyCalls(setter
, 1);
1863 assertSpyCall(setter
, 0, {
1869 it("[[Call]] walks the prototype chain", () => {
1870 const setter
= spy((_
) => {});
1871 const obj
= Object
.create(
1872 Object
.create(null, { success
: { set: setter
} }),
1874 setPropertyValue(obj
, "success", true);
1875 assertSpyCalls(setter
, 1);
1876 assertSpyCall(setter
, 0, {
1882 it("[[Call]] uses the provided receiver", () => {
1883 const setter
= spy((_
) => {});
1884 const obj
= Object
.create(null, { success
: { set: setter
} });
1885 const receiver
= {};
1886 setPropertyValue(obj
, "success", true, receiver
);
1887 assertSpyCalls(setter
, 1);
1888 assertSpyCall(setter
, 0, {
1894 it("[[Call]] throws if the property can’t be set", () => {
1895 const obj
= Object
.freeze({ failure
: undefined });
1896 assertThrows(() => setPropertyValue(obj
, "failure", true));
1899 it("[[Call]] returns the provided object", () => {
1901 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
1904 it("[[Construct]] throws an error", () => {
1905 assertThrows(() => new setPropertyValue({}, "", undefined));
1908 describe(".length", () => {
1909 it("[[Get]] returns the correct length", () => {
1910 assertStrictEquals(setPropertyValue
.length
, 3);
1914 describe(".name", () => {
1915 it("[[Get]] returns the correct name", () => {
1916 assertStrictEquals(setPropertyValue
.name
, "setPropertyValue");
1921 describe("setPropertyValues", () => {
1922 it("[[Call]] sets the provided properties on the provided object", () => {
1924 setPropertyValues(obj
, { success
: true, all
: "good" });
1925 assertStrictEquals(obj
.success
, true);
1926 assertStrictEquals(obj
.all
, "good");
1929 it("[[Call]] can take multiple objects", () => {
1933 { success
: false, all
: "good" },
1936 assertStrictEquals(obj
.success
, true);
1937 assertStrictEquals(obj
.all
, "good");
1940 it("[[Call]] ignores nullish arguments", () => {
1942 setPropertyValues(obj
, null, undefined, { success
: true });
1943 assertStrictEquals(obj
.success
, true);
1946 it("[[Call]] calls setters", () => {
1947 const setter
= spy((_
) => {});
1948 const obj
= Object
.create(null, { success
: { set: setter
} });
1949 setPropertyValues(obj
, { success
: true });
1950 assertSpyCalls(setter
, 1);
1951 assertSpyCall(setter
, 0, {
1957 it("[[Call]] calls setters multiple times if property appears more than once", () => {
1958 const setter
= spy((_
) => {});
1959 const obj
= Object
.create(null, { success
: { set: setter
} });
1960 setPropertyValues(obj
, { success
: false }, { success
: true });
1961 assertSpyCalls(setter
, 2);
1962 assertSpyCall(setter
, 0, {
1966 assertSpyCall(setter
, 1, {
1972 it("[[Call]] walks the prototype chain", () => {
1973 const setter
= spy((_
) => {});
1974 const obj
= Object
.create(
1975 Object
.create(null, { success
: { set: setter
} }),
1977 setPropertyValues(obj
, { success
: true });
1978 assertSpyCalls(setter
, 1);
1979 assertSpyCall(setter
, 0, {
1985 it("[[Call]] throws if the property can’t be set", () => {
1986 const obj
= Object
.freeze({ failure
: undefined });
1987 assertThrows(() => setPropertyValues(obj
, { failure
: true }));
1990 it("[[Call]] returns the provided object", () => {
1992 assertStrictEquals(setPropertyValues(obj
, { "": undefined }), obj
);
1995 it("[[Construct]] throws an error", () => {
1996 assertThrows(() => new setPropertyValues(obj
, { "": undefined }));
1999 describe(".length", () => {
2000 it("[[Get]] returns the correct length", () => {
2001 assertStrictEquals(setPropertyValues
.length
, 2);
2005 describe(".name", () => {
2006 it("[[Get]] returns the correct name", () => {
2007 assertStrictEquals(setPropertyValues
.name
, "setPropertyValues");
2012 describe("setPrototype", () => {
2013 it("[[Call]] sets object prototypes", () => {
2016 setPrototype(obj
, proto
);
2017 assertStrictEquals(Object
.getPrototypeOf(obj
), proto
);
2020 it("[[Call]] sets null prototypes", () => {
2022 setPrototype(obj
, null);
2023 assertStrictEquals(Object
.getPrototypeOf(obj
), null);
2026 it("[[Call]] can set coercible primitives to their same prototype", () => {
2027 setPrototype(1, Number
.prototype);
2028 setPrototype(Symbol(), Symbol
.prototype);
2031 it("[[Call]] throws when setting coercible primitives to a different prototype", () => {
2032 assertThrows(() => setPrototype(1, Object
.prototype));
2033 assertThrows(() => setPrototype(Symbol(), Object
.prototype));
2036 it("[[Call]] throws for null and undefined", () => {
2037 assertThrows(() => setPrototype(null, Object
.prototype));
2038 assertThrows(() => setPrototype(undefined, Object
.prototype));
2041 it("[[Call]] returns the provided value", () => {
2043 assertStrictEquals(setPrototype(obj
, null), obj
);
2044 assertStrictEquals(setPrototype(1, Number
.prototype), 1);
2047 it("[[Construct]] throws an error", () => {
2048 assertThrows(() => new setPrototype({}, null));
2051 describe(".length", () => {
2052 it("[[Get]] returns the correct length", () => {
2053 assertStrictEquals(setPrototype
.length
, 2);
2057 describe(".name", () => {
2058 it("[[Get]] returns the correct name", () => {
2059 assertStrictEquals(setPrototype
.name
, "setPrototype");
2064 describe("toObject", () => {
2065 it("returns the input for objects", () => {
2067 assertStrictEquals(toObject(obj
), obj
);
2070 it("throws for nullish values", () => {
2071 assertThrows(() => toObject(null));
2072 assertThrows(() => toObject(void {}));
2075 it("returns a wrapper object for other primitives", () => {
2076 const sym
= Symbol();
2077 assertStrictEquals(typeof toObject(sym
), "object");
2078 assertStrictEquals(toObject(sym
).valueOf(), sym
);
2081 it("[[Construct]] throws an error", () => {
2082 assertThrows(() => new toObject({}));
2085 describe(".length", () => {
2086 it("[[Get]] returns the correct length", () => {
2087 assertStrictEquals(toObject
.length
, 1);
2091 describe(".name", () => {
2092 it("[[Get]] returns the correct name", () => {
2093 assertStrictEquals(toObject
.name
, "toObject");
2098 describe("toPropertyDescriptorRecord", () => {
2099 it("[[Call]] creates a new property descriptor record", () => {
2101 const desc
= toPropertyDescriptorRecord(obj
);
2102 assertEquals(obj
, desc
);
2103 assertNotStrictEquals(obj
, desc
);
2106 it("[[Call]] coerces the values", () => {
2108 toPropertyDescriptorRecord({
2109 configurable
: undefined,
2110 enumerable
: undefined,
2111 writable
: undefined,
2113 { configurable
: false, enumerable
: false, writable
: false },
2117 it("[[Construct]] throws for primitives", () => {
2118 assertThrows(() => toPropertyDescriptorRecord(undefined));
2119 assertThrows(() => toPropertyDescriptorRecord("failure"));
2122 it("[[Construct]] throws an error", () => {
2123 assertThrows(() => new toPropertyDescriptorRecord({}));
2126 describe(".length", () => {
2127 it("[[Get]] returns the correct length", () => {
2128 assertStrictEquals(toPropertyDescriptorRecord
.length
, 1);
2132 describe(".name", () => {
2133 it("[[Get]] returns the correct name", () => {
2135 toPropertyDescriptorRecord
.name
,
2136 "toPropertyDescriptorRecord",
2141 describe("~configurable", () => {
2142 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2143 const desc
= toPropertyDescriptorRecord({});
2144 Object
.defineProperty(desc
, "configurable", {});
2145 assertStrictEquals(desc
.configurable
, false);
2148 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2149 const desc
= toPropertyDescriptorRecord({});
2151 Object
.defineProperty(desc
, "configurable", { get: undefined })
2155 it("[[Set]] coerces to a boolean", () => {
2156 const desc
= toPropertyDescriptorRecord({});
2157 desc
.configurable
= undefined;
2158 assertStrictEquals(desc
.configurable
, false);
2161 it("[[Delete]] works", () => {
2162 const desc
= toPropertyDescriptorRecord({ configurable
: false });
2163 delete desc
.configurable
;
2164 assert(!("configurable" in desc
));
2168 describe("~enumerable", () => {
2169 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2170 const desc
= toPropertyDescriptorRecord({});
2171 Object
.defineProperty(desc
, "enumerable", {});
2172 assertStrictEquals(desc
.enumerable
, false);
2175 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2176 const desc
= toPropertyDescriptorRecord({});
2178 Object
.defineProperty(desc
, "enumerable", { get: undefined })
2182 it("[[Set]] coerces to a boolean", () => {
2183 const desc
= toPropertyDescriptorRecord({});
2184 desc
.enumerable
= undefined;
2185 assertStrictEquals(desc
.enumerable
, false);
2188 it("[[Delete]] works", () => {
2189 const desc
= toPropertyDescriptorRecord({ enumerable
: false });
2190 delete desc
.enumerable
;
2191 assert(!("enumerable" in desc
));
2195 describe("~get", () => {
2196 it("[[DefineOwnProperty]] works", () => {
2197 const desc
= toPropertyDescriptorRecord({});
2198 Object
.defineProperty(desc
, "get", {});
2199 assertStrictEquals(desc
.get, undefined);
2202 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2203 const desc
= toPropertyDescriptorRecord({});
2205 Object
.defineProperty(desc
, "get", { get: undefined })
2209 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
2210 const desc
= toPropertyDescriptorRecord({});
2212 () => Object
.defineProperty(desc
, "get", { value
: null }),
2216 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
2217 const desc
= toPropertyDescriptorRecord({ value
: undefined });
2218 assertThrows(() => Object
.defineProperty(desc
, "get", {}));
2221 it("[[Set]] works", () => {
2222 const desc
= toPropertyDescriptorRecord({});
2223 const fn
= () => {};
2225 assertStrictEquals(desc
.get, fn
);
2228 it("[[Set]] throws if not callable or undefined", () => {
2229 const desc
= toPropertyDescriptorRecord({});
2230 assertThrows(() => desc
.get = null);
2233 it("[[Set]] throws if a data property is defined", () => {
2234 const desc
= toPropertyDescriptorRecord({ value
: undefined });
2235 assertThrows(() => desc
.get = undefined);
2238 it("[[Delete]] works", () => {
2239 const desc
= toPropertyDescriptorRecord({ get: undefined });
2241 assert(!("get" in desc
));
2245 describe("~set", () => {
2246 it("[[DefineOwnProperty]] works", () => {
2247 const desc
= toPropertyDescriptorRecord({});
2248 Object
.defineProperty(desc
, "set", {});
2249 assertStrictEquals(desc
.set, undefined);
2252 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2253 const desc
= toPropertyDescriptorRecord({});
2255 Object
.defineProperty(desc
, "set", { get: undefined })
2259 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
2260 const desc
= toPropertyDescriptorRecord({});
2262 () => Object
.defineProperty(desc
, "set", { value
: null }),
2266 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
2267 const desc
= toPropertyDescriptorRecord({ value
: undefined });
2268 assertThrows(() => Object
.defineProperty(desc
, "set", {}));
2271 it("[[Set]] works", () => {
2272 const desc
= toPropertyDescriptorRecord({});
2273 const fn
= (_
) => {};
2275 assertStrictEquals(desc
.set, fn
);
2278 it("[[Set]] throws if not callable or undefined", () => {
2279 const desc
= toPropertyDescriptorRecord({});
2280 assertThrows(() => desc
.set = null);
2283 it("[[Set]] throws if a data property is defined", () => {
2284 const desc
= toPropertyDescriptorRecord({ value
: undefined });
2285 assertThrows(() => desc
.set = undefined);
2288 it("[[Delete]] works", () => {
2289 const desc
= toPropertyDescriptorRecord({ set: undefined });
2291 assert(!("set" in desc
));
2295 describe("~value", () => {
2296 it("[[DefineOwnProperty]] works", () => {
2297 const desc
= toPropertyDescriptorRecord({});
2298 Object
.defineProperty(desc
, "value", {});
2299 assertStrictEquals(desc
.value
, undefined);
2302 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2303 const desc
= toPropertyDescriptorRecord({});
2305 Object
.defineProperty(desc
, "value", { get: undefined })
2309 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
2310 const desc
= toPropertyDescriptorRecord({ get: undefined });
2311 assertThrows(() => Object
.defineProperty(desc
, "value", {}));
2314 it("[[Set]] works", () => {
2315 const desc
= toPropertyDescriptorRecord({});
2316 desc
.value
= "success";
2317 assertStrictEquals(desc
.value
, "success");
2320 it("[[Set]] throws if an accessor property is defined", () => {
2321 const desc
= toPropertyDescriptorRecord({ get: undefined });
2322 assertThrows(() => desc
.value
= null);
2325 it("[[Delete]] works", () => {
2326 const desc
= toPropertyDescriptorRecord({ value
: undefined });
2328 assert(!("value" in desc
));
2332 describe("~writable", () => {
2333 it("[[DefineOwnProperty]] coerces to a boolean", () => {
2334 const desc
= toPropertyDescriptorRecord({});
2335 Object
.defineProperty(desc
, "writable", {});
2336 assertStrictEquals(desc
.writable
, false);
2339 it("[[DefineOwnProperty]] throws for accessor properties", () => {
2340 const desc
= toPropertyDescriptorRecord({});
2342 Object
.defineProperty(desc
, "writable", { get: undefined })
2346 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
2347 const desc
= toPropertyDescriptorRecord({ get: undefined });
2348 assertThrows(() => Object
.defineProperty(desc
, "writable", {}));
2351 it("[[Set]] coerces to a boolean", () => {
2352 const desc
= toPropertyDescriptorRecord({});
2353 desc
.writable
= undefined;
2354 assertStrictEquals(desc
.writable
, false);
2357 it("[[Set]] throws if an accessor property is defined", () => {
2358 const desc
= toPropertyDescriptorRecord({ get: undefined });
2359 assertThrows(() => desc
.writable
= false);
2362 it("[[Delete]] works", () => {
2363 const desc
= toPropertyDescriptorRecord({ writable
: false });
2364 delete desc
.writable
;
2365 assert(!("writable" in desc
));