]>
Lady’s Gitweb - Pisces/blob - object.test.js
1 // ♓🌟 Piscēs ∷ object.test.js
2 // ====================================================================
4 // Copyright © 2022 Lady [@ Lady’s Computer].
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
20 } from "./dev-deps.js";
31 describe("PropertyDescriptor", () => {
32 it("[[Construct]] creates a new PropertyDescriptor", () => {
34 Object
.getPrototypeOf(new PropertyDescriptor({})),
35 PropertyDescriptor
.prototype,
39 it("[[Construct]] throws for primitives", () => {
40 assertThrows(() => new PropertyDescriptor("failure"));
43 describe("::complete", () => {
44 it("[[Call]] completes a generic descriptor", () => {
46 PropertyDescriptor
.prototype.complete
.call(desc
);
55 it("[[Call]] completes a data descriptor", () => {
56 const desc
= { value
: undefined };
57 PropertyDescriptor
.prototype.complete
.call(desc
);
66 it("[[Call]] completes an accessor descriptor", () => {
67 const desc
= { get: undefined };
68 PropertyDescriptor
.prototype.complete
.call(desc
);
78 describe("::isAccessorDescriptor", () => {
79 it("[[Get]] returns false for a generic descriptor", () => {
82 PropertyDescriptor
.prototype,
83 "isAccessorDescriptor",
90 it("[[Get]] returns false for a data descriptor", () => {
93 PropertyDescriptor
.prototype,
94 "isAccessorDescriptor",
101 it("[[Get]] returns true for an accessor descriptor", () => {
104 PropertyDescriptor
.prototype,
105 "isAccessorDescriptor",
113 describe("::isDataDescriptor", () => {
114 it("[[Get]] returns false for a generic descriptor", () => {
117 PropertyDescriptor
.prototype,
125 it("[[Get]] returns true for a data descriptor", () => {
128 PropertyDescriptor
.prototype,
130 { value
: undefined },
136 it("[[Get]] returns false for an accessor descriptor", () => {
139 PropertyDescriptor
.prototype,
148 describe("::isFullyPopulated", () => {
149 it("[[Get]] returns false for a generic descriptor", () => {
152 PropertyDescriptor
.prototype,
160 it("[[Get]] returns false for a non‐fully‐populated data descriptor", () => {
163 PropertyDescriptor
.prototype,
165 { value
: undefined },
171 it("[[Get]] returns true for a fully‐populated data descriptor", () => {
173 Reflect
.get(PropertyDescriptor
.prototype, "isFullyPopulated", {
183 it("[[Get]] returns false for a non‐fully‐populated accessor descriptor", () => {
186 PropertyDescriptor
.prototype,
194 it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
196 Reflect
.get(PropertyDescriptor
.prototype, "isFullyPopulated", {
207 describe("::isGenericDescriptor", () => {
208 it("[[Get]] returns true for a generic descriptor", () => {
211 PropertyDescriptor
.prototype,
212 "isGenericDescriptor",
219 it("[[Get]] returns true for a data descriptor", () => {
222 PropertyDescriptor
.prototype,
223 "isGenericDescriptor",
224 { value
: undefined },
230 it("[[Get]] returns false for an accessor descriptor", () => {
233 PropertyDescriptor
.prototype,
234 "isGenericDescriptor",
242 describe("~configurable", () => {
243 it("[[DefineOwnProperty]] coerces to a boolean", () => {
244 const desc
= new PropertyDescriptor({});
245 Object
.defineProperty(desc
, "configurable", {});
246 assertStrictEquals(desc
.configurable
, false);
249 it("[[DefineOwnProperty]] throws for accessor properties", () => {
250 const desc
= new PropertyDescriptor({});
252 Object
.defineProperty(desc
, "configurable", { get: undefined })
256 it("[[Set]] coerces to a boolean", () => {
257 const desc
= new PropertyDescriptor({});
258 desc
.configurable
= undefined;
259 assertStrictEquals(desc
.configurable
, false);
262 it("[[Delete]] works", () => {
263 const desc
= new PropertyDescriptor({ configurable
: false });
264 delete desc
.configurable
;
265 assert(!("configurable" in desc
));
269 describe("~enumerable", () => {
270 it("[[DefineOwnProperty]] coerces to a boolean", () => {
271 const desc
= new PropertyDescriptor({});
272 Object
.defineProperty(desc
, "enumerable", {});
273 assertStrictEquals(desc
.enumerable
, false);
276 it("[[DefineOwnProperty]] throws for accessor properties", () => {
277 const desc
= new PropertyDescriptor({});
279 Object
.defineProperty(desc
, "enumerable", { get: undefined })
283 it("[[Set]] coerces to a boolean", () => {
284 const desc
= new PropertyDescriptor({});
285 desc
.enumerable
= undefined;
286 assertStrictEquals(desc
.enumerable
, false);
289 it("[[Delete]] works", () => {
290 const desc
= new PropertyDescriptor({ enumerable
: false });
291 delete desc
.enumerable
;
292 assert(!("enumerable" in desc
));
296 describe("~get", () => {
297 it("[[DefineOwnProperty]] works", () => {
298 const desc
= new PropertyDescriptor({});
299 Object
.defineProperty(desc
, "get", {});
300 assertStrictEquals(desc
.get, undefined);
303 it("[[DefineOwnProperty]] throws for accessor properties", () => {
304 const desc
= new PropertyDescriptor({});
306 Object
.defineProperty(desc
, "get", { get: undefined })
310 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
311 const desc
= new PropertyDescriptor({});
313 () => Object
.defineProperty(desc
, "get", { value
: null }),
317 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
318 const desc
= new PropertyDescriptor({ value
: undefined });
319 assertThrows(() => Object
.defineProperty(desc
, "get", {}));
322 it("[[Set]] works", () => {
323 const desc
= new PropertyDescriptor({});
326 assertStrictEquals(desc
.get, fn
);
329 it("[[Set]] throws if not callable or undefined", () => {
330 const desc
= new PropertyDescriptor({});
331 assertThrows(() => desc
.get = null);
334 it("[[Set]] throws if a data property is defined", () => {
335 const desc
= new PropertyDescriptor({ value
: undefined });
336 assertThrows(() => desc
.get = undefined);
339 it("[[Delete]] works", () => {
340 const desc
= new PropertyDescriptor({ get: undefined });
342 assert(!("get" in desc
));
346 describe("~set", () => {
347 it("[[DefineOwnProperty]] works", () => {
348 const desc
= new PropertyDescriptor({});
349 Object
.defineProperty(desc
, "set", {});
350 assertStrictEquals(desc
.set, undefined);
353 it("[[DefineOwnProperty]] throws for accessor properties", () => {
354 const desc
= new PropertyDescriptor({});
356 Object
.defineProperty(desc
, "set", { get: undefined })
360 it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
361 const desc
= new PropertyDescriptor({});
363 () => Object
.defineProperty(desc
, "set", { value
: null }),
367 it("[[DefineOwnProperty]] throws if a data property is defined", () => {
368 const desc
= new PropertyDescriptor({ value
: undefined });
369 assertThrows(() => Object
.defineProperty(desc
, "set", {}));
372 it("[[Set]] works", () => {
373 const desc
= new PropertyDescriptor({});
374 const fn
= (_
) => {};
376 assertStrictEquals(desc
.set, fn
);
379 it("[[Set]] throws if not callable or undefined", () => {
380 const desc
= new PropertyDescriptor({});
381 assertThrows(() => desc
.set = null);
384 it("[[Set]] throws if a data property is defined", () => {
385 const desc
= new PropertyDescriptor({ value
: undefined });
386 assertThrows(() => desc
.set = undefined);
389 it("[[Delete]] works", () => {
390 const desc
= new PropertyDescriptor({ set: undefined });
392 assert(!("set" in desc
));
396 describe("~value", () => {
397 it("[[DefineOwnProperty]] works", () => {
398 const desc
= new PropertyDescriptor({});
399 Object
.defineProperty(desc
, "value", {});
400 assertStrictEquals(desc
.value
, undefined);
403 it("[[DefineOwnProperty]] throws for accessor properties", () => {
404 const desc
= new PropertyDescriptor({});
406 Object
.defineProperty(desc
, "value", { get: undefined })
410 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
411 const desc
= new PropertyDescriptor({ get: undefined });
412 assertThrows(() => Object
.defineProperty(desc
, "value", {}));
415 it("[[Set]] works", () => {
416 const desc
= new PropertyDescriptor({});
417 desc
.value
= "success";
418 assertStrictEquals(desc
.value
, "success");
421 it("[[Set]] throws if an accessor property is defined", () => {
422 const desc
= new PropertyDescriptor({ get: undefined });
423 assertThrows(() => desc
.value
= null);
426 it("[[Delete]] works", () => {
427 const desc
= new PropertyDescriptor({ value
: undefined });
429 assert(!("value" in desc
));
433 describe("~writable", () => {
434 it("[[DefineOwnProperty]] coerces to a boolean", () => {
435 const desc
= new PropertyDescriptor({});
436 Object
.defineProperty(desc
, "writable", {});
437 assertStrictEquals(desc
.writable
, false);
440 it("[[DefineOwnProperty]] throws for accessor properties", () => {
441 const desc
= new PropertyDescriptor({});
443 Object
.defineProperty(desc
, "writable", { get: undefined })
447 it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
448 const desc
= new PropertyDescriptor({ get: undefined });
449 assertThrows(() => Object
.defineProperty(desc
, "writable", {}));
452 it("[[Set]] coerces to a boolean", () => {
453 const desc
= new PropertyDescriptor({});
454 desc
.writable
= undefined;
455 assertStrictEquals(desc
.writable
, false);
458 it("[[Set]] throws if an accessor property is defined", () => {
459 const desc
= new PropertyDescriptor({ get: undefined });
460 assertThrows(() => desc
.writable
= false);
463 it("[[Delete]] works", () => {
464 const desc
= new PropertyDescriptor({ writable
: false });
465 delete desc
.writable
;
466 assert(!("writable" in desc
));
471 describe("defineOwnProperties", () => {
472 it("[[Call]] defines properties from the provided objects", () => {
474 defineOwnProperties(obj
, {
478 assert("etaoin" in obj
);
479 assert("shrdlu" in obj
);
480 assert("cmfwyp" in obj
);
483 it("[[Call]] overrides earlier declarations with later ones", () => {
484 const obj
= { etaoin
: undefined };
485 defineOwnProperties(obj
, {
486 etaoin
: { value
: "failure" },
488 etaoin
: { value
: "success" },
490 assertStrictEquals(obj
.etaoin
, "success");
493 it("[[Call]] returns the provided object", () => {
495 assertStrictEquals(defineOwnProperties(obj
), obj
);
499 describe("deleteOwnProperty", () => {
500 it("[[Call]] deletes the provided property on the provided object", () => {
501 const obj
= { failure
: undefined };
502 deleteOwnProperty(obj
, "failure");
503 assert(!("failure" in obj
));
506 it("[[Call]] does nothing if the property doesn’t exist", () => {
507 const obj
= Object
.freeze({});
508 deleteOwnProperty(obj
, "failure");
509 assert(!("failure" in obj
));
512 it("[[Call]] throws if the property can’t be deleted", () => {
513 const obj
= Object
.seal({ failure
: undefined });
514 assertThrows(() => deleteOwnProperty(obj
, "failure"));
517 it("[[Call]] returns the provided object", () => {
519 assertStrictEquals(deleteOwnProperty(obj
, ""), obj
);
523 describe("frozenCopy", () => {
524 it("[[Call]] returns a frozen object", () => {
527 frozenCopy(Object
.create(null), {
544 it("[[Call]] ignores non·enumerable properties", () => {
547 Object
.create(null, {
548 data
: { value
: undefined },
549 accessor
: { get: undefined },
556 it("[[Call]] preserves accessor properties", () => {
584 Object
.getOwnPropertyDescriptors(
585 frozenCopy(Object
.create(null, properties
)),
591 it("[[Call]] does not copy properties on the prototype", () => {
594 frozenCopy(Object
.create({ failure
: undefined }), {
600 accessor
: { configurable
: true, get: undefined },
605 it("[[Call]] uses the species of the constructor", () => {
606 const species
= { prototype: {} };
608 Object
.getPrototypeOf(
609 frozenCopy({}, { [Symbol
.species
]: species
}),
615 it("[[Call]] uses constructor if no species is defined", () => {
616 const constructor = { [Symbol
.species
]: null, prototype: {} };
618 Object
.getPrototypeOf(frozenCopy({}, constructor)),
619 constructor.prototype,
623 it("[[Call]] uses the constructor on the object if none is provided", () => {
624 const constructor = { [Symbol
.species
]: null, prototype: {} };
626 Object
.getPrototypeOf(frozenCopy({ constructor })),
627 constructor.prototype,
631 it("[[Call]] allows a null constructor", () => {
633 Object
.getPrototypeOf(frozenCopy({}, null)),
639 describe("setPropertyValue", () => {
640 it("[[Call]] sets the provided property on the provided object", () => {
642 setPropertyValue(obj
, "success", true);
643 assertStrictEquals(obj
.success
, true);
646 it("[[Call]] calls setters", () => {
647 const setter
= spy((_
) => {});
648 const obj
= Object
.create(null, { success
: { set: setter
} });
649 setPropertyValue(obj
, "success", true);
650 assertSpyCalls(setter
, 1);
651 assertSpyCall(setter
, 0, {
657 it("[[Call]] walks the prototype chain", () => {
658 const setter
= spy((_
) => {});
659 const obj
= Object
.create(
660 Object
.create(null, { success
: { set: setter
} }),
662 setPropertyValue(obj
, "success", true);
663 assertSpyCalls(setter
, 1);
664 assertSpyCall(setter
, 0, {
670 it("[[Call]] uses the provided receiver", () => {
671 const setter
= spy((_
) => {});
672 const obj
= Object
.create(null, { success
: { set: setter
} });
674 setPropertyValue(obj
, "success", true, receiver
);
675 assertSpyCalls(setter
, 1);
676 assertSpyCall(setter
, 0, {
682 it("[[Call]] throws if the property can’t be set", () => {
683 const obj
= Object
.freeze({ failure
: undefined });
684 assertThrows(() => setPropertyValue(obj
, "failure", true));
687 it("[[Call]] returns the provided object", () => {
689 assertStrictEquals(setPropertyValue(obj
, "", undefined), obj
);
693 describe("toObject", () => {
694 it("returns the input for objects", () => {
696 assertStrictEquals(toObject(obj
), obj
);
699 it("returns a new object for nullish values", () => {
700 assertEquals(toObject(null), {});
701 assertEquals(toObject(void {}), {});
704 it("returns a wrapper object for other primitives", () => {
705 const sym
= Symbol();
706 assertStrictEquals(typeof toObject(sym
), "object");
707 assertStrictEquals(toObject(sym
).valueOf(), sym
);
711 describe("toPropertyKey", () => {
712 it("returns a string or symbol", () => {
713 const sym
= Symbol();
714 assertStrictEquals(toPropertyKey(sym
), sym
);
716 toPropertyKey(new String("success")),
721 it("favours the `toString` representation", () => {
This page took 0.114433 seconds and 5 git commands to generate.