-describe("PropertyDescriptor", () => {
- it("[[Call]] throws an error", () => {
- assertThrows(() => PropertyDescriptor({}));
- });
-
- it("[[Construct]] creates a new PropertyDescriptor", () => {
- assertStrictEquals(
- Object.getPrototypeOf(new PropertyDescriptor({})),
- PropertyDescriptor.prototype,
- );
- });
-
- it("[[Construct]] throws for primitives", () => {
- assertThrows(() => new PropertyDescriptor("failure"));
- });
-
- describe(".length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(PropertyDescriptor.length, 1);
- });
- });
-
- describe(".name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- PropertyDescriptor.name,
- "PropertyDescriptor",
- );
- });
- });
-
- describe("::complete", () => {
- it("[[Call]] completes a generic descriptor", () => {
- const desc = {};
- PropertyDescriptor.prototype.complete.call(desc);
- assertEquals(desc, {
- configurable: false,
- enumerable: false,
- value: undefined,
- writable: false,
- });
- });
-
- it("[[Call]] completes a data descriptor", () => {
- const desc = { value: undefined };
- PropertyDescriptor.prototype.complete.call(desc);
- assertEquals(desc, {
- configurable: false,
- enumerable: false,
- value: undefined,
- writable: false,
- });
- });
-
- it("[[Call]] completes an accessor descriptor", () => {
- const desc = { get: undefined };
- PropertyDescriptor.prototype.complete.call(desc);
- assertEquals(desc, {
- configurable: false,
- enumerable: false,
- get: undefined,
- set: undefined,
- });
- });
-
- describe(".length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(
- PropertyDescriptor.prototype.complete.length,
- 0,
- );
- });
- });
-
- describe(".name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- PropertyDescriptor.prototype.complete.name,
- "complete",
- );
- });
- });
- });
-
- describe("::isAccessorDescriptor", () => {
- it("[[Get]] returns false for a generic descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isAccessorDescriptor",
- {},
- ),
- false,
- );
- });
-
- it("[[Get]] returns false for a data descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isAccessorDescriptor",
- { value: undefined },
- ),
- false,
- );
- });
-
- it("[[Get]] returns true for an accessor descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isAccessorDescriptor",
- { get: undefined },
- ),
- true,
- );
- });
-
- describe("[[GetOwnProperty]].get.length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isAccessorDescriptor",
- ).get.length,
- 0,
- );
- });
- });
-
- describe("[[GetOwnProperty]].get.name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isAccessorDescriptor",
- ).get.name,
- "get isAccessorDescriptor",
- );
- });
- });
- });
-
- describe("::isDataDescriptor", () => {
- it("[[Get]] returns false for a generic descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isDataDescriptor",
- {},
- ),
- false,
- );
- });
-
- it("[[Get]] returns true for a data descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isDataDescriptor",
- { value: undefined },
- ),
- true,
- );
- });
-
- it("[[Get]] returns false for an accessor descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isDataDescriptor",
- { get: undefined },
- ),
- false,
- );
- });
-
- describe("[[GetOwnProperty]].get.length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isDataDescriptor",
- ).get.length,
- 0,
- );
- });
- });
-
- describe("[[GetOwnProperty]].get.name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isDataDescriptor",
- ).get.name,
- "get isDataDescriptor",
- );
- });
- });
- });
-
- describe("::isFullyPopulated", () => {
- it("[[Get]] returns false for a generic descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isFullyPopulated",
- {},
- ),
- false,
- );
- });
-
- it("[[Get]] returns false for a non‐fully‐populated data descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isFullyPopulated",
- { value: undefined },
- ),
- false,
- );
- });
-
- it("[[Get]] returns true for a fully‐populated data descriptor", () => {
- assertStrictEquals(
- Reflect.get(PropertyDescriptor.prototype, "isFullyPopulated", {
- configurable: true,
- enumerable: true,
- value: undefined,
- writable: true,
- }),
- true,
- );
- });
-
- it("[[Get]] returns false for a non‐fully‐populated accessor descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isFullyPopulated",
- { get: undefined },
- ),
- false,
- );
- });
-
- it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
- assertStrictEquals(
- Reflect.get(PropertyDescriptor.prototype, "isFullyPopulated", {
- configurable: true,
- enumerable: true,
- get: undefined,
- set: undefined,
- }),
- true,
- );
- });
-
- describe("[[GetOwnProperty]].get.length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isFullyPopulated",
- ).get.length,
- 0,
- );
- });
- });
-
- describe("[[GetOwnProperty]].get.name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isFullyPopulated",
- ).get.name,
- "get isFullyPopulated",
- );
- });
- });
- });
-
- describe("::isGenericDescriptor", () => {
- it("[[Get]] returns true for a generic descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isGenericDescriptor",
- {},
- ),
- true,
- );
- });
-
- it("[[Get]] returns true for a data descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isGenericDescriptor",
- { value: undefined },
- ),
- false,
- );
- });
-
- it("[[Get]] returns false for an accessor descriptor", () => {
- assertStrictEquals(
- Reflect.get(
- PropertyDescriptor.prototype,
- "isGenericDescriptor",
- { get: undefined },
- ),
- false,
- );
- });
-
- describe("[[GetOwnProperty]].get.length", () => {
- it("[[Get]] returns the correct length", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isGenericDescriptor",
- ).get.length,
- 0,
- );
- });
- });
-
- describe("[[GetOwnProperty]].get.name", () => {
- it("[[Get]] returns the correct name", () => {
- assertStrictEquals(
- Object.getOwnPropertyDescriptor(
- PropertyDescriptor.prototype,
- "isGenericDescriptor",
- ).get.name,
- "get isGenericDescriptor",
- );
- });
- });
- });
-
- describe("~configurable", () => {
- it("[[DefineOwnProperty]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "configurable", {});
- assertStrictEquals(desc.configurable, false);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "configurable", { get: undefined })
- );
- });
-
- it("[[Set]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- desc.configurable = undefined;
- assertStrictEquals(desc.configurable, false);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ configurable: false });
- delete desc.configurable;
- assert(!("configurable" in desc));
- });
- });
-
- describe("~enumerable", () => {
- it("[[DefineOwnProperty]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "enumerable", {});
- assertStrictEquals(desc.enumerable, false);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "enumerable", { get: undefined })
- );
- });
-
- it("[[Set]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- desc.enumerable = undefined;
- assertStrictEquals(desc.enumerable, false);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ enumerable: false });
- delete desc.enumerable;
- assert(!("enumerable" in desc));
- });
- });
-
- describe("~get", () => {
- it("[[DefineOwnProperty]] works", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "get", {});
- assertStrictEquals(desc.get, undefined);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "get", { get: undefined })
- );
- });
-
- it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(
- () => Object.defineProperty(desc, "get", { value: null }),
- );
- });
-
- it("[[DefineOwnProperty]] throws if a data property is defined", () => {
- const desc = new PropertyDescriptor({ value: undefined });
- assertThrows(() => Object.defineProperty(desc, "get", {}));
- });
-
- it("[[Set]] works", () => {
- const desc = new PropertyDescriptor({});
- const fn = () => {};
- desc.get = fn;
- assertStrictEquals(desc.get, fn);
- });
-
- it("[[Set]] throws if not callable or undefined", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() => desc.get = null);
- });
-
- it("[[Set]] throws if a data property is defined", () => {
- const desc = new PropertyDescriptor({ value: undefined });
- assertThrows(() => desc.get = undefined);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ get: undefined });
- delete desc.get;
- assert(!("get" in desc));
- });
- });
-
- describe("~set", () => {
- it("[[DefineOwnProperty]] works", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "set", {});
- assertStrictEquals(desc.set, undefined);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "set", { get: undefined })
- );
- });
-
- it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(
- () => Object.defineProperty(desc, "set", { value: null }),
- );
- });
-
- it("[[DefineOwnProperty]] throws if a data property is defined", () => {
- const desc = new PropertyDescriptor({ value: undefined });
- assertThrows(() => Object.defineProperty(desc, "set", {}));
- });
-
- it("[[Set]] works", () => {
- const desc = new PropertyDescriptor({});
- const fn = (_) => {};
- desc.set = fn;
- assertStrictEquals(desc.set, fn);
- });
-
- it("[[Set]] throws if not callable or undefined", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() => desc.set = null);
- });
-
- it("[[Set]] throws if a data property is defined", () => {
- const desc = new PropertyDescriptor({ value: undefined });
- assertThrows(() => desc.set = undefined);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ set: undefined });
- delete desc.set;
- assert(!("set" in desc));
- });
- });
-
- describe("~value", () => {
- it("[[DefineOwnProperty]] works", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "value", {});
- assertStrictEquals(desc.value, undefined);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "value", { get: undefined })
- );
- });
-
- it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
- const desc = new PropertyDescriptor({ get: undefined });
- assertThrows(() => Object.defineProperty(desc, "value", {}));
- });
-
- it("[[Set]] works", () => {
- const desc = new PropertyDescriptor({});
- desc.value = "success";
- assertStrictEquals(desc.value, "success");
- });
-
- it("[[Set]] throws if an accessor property is defined", () => {
- const desc = new PropertyDescriptor({ get: undefined });
- assertThrows(() => desc.value = null);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ value: undefined });
- delete desc.value;
- assert(!("value" in desc));
- });
- });
-
- describe("~writable", () => {
- it("[[DefineOwnProperty]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- Object.defineProperty(desc, "writable", {});
- assertStrictEquals(desc.writable, false);
- });
-
- it("[[DefineOwnProperty]] throws for accessor properties", () => {
- const desc = new PropertyDescriptor({});
- assertThrows(() =>
- Object.defineProperty(desc, "writable", { get: undefined })
- );
- });
-
- it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
- const desc = new PropertyDescriptor({ get: undefined });
- assertThrows(() => Object.defineProperty(desc, "writable", {}));
- });
-
- it("[[Set]] coerces to a boolean", () => {
- const desc = new PropertyDescriptor({});
- desc.writable = undefined;
- assertStrictEquals(desc.writable, false);
- });
-
- it("[[Set]] throws if an accessor property is defined", () => {
- const desc = new PropertyDescriptor({ get: undefined });
- assertThrows(() => desc.writable = false);
- });
-
- it("[[Delete]] works", () => {
- const desc = new PropertyDescriptor({ writable: false });
- delete desc.writable;
- assert(!("writable" in desc));
- });
- });
-});
-