// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
import {
+ assert,
+ assertEquals,
+ assertNotStrictEquals,
assertStrictEquals,
assertThrows,
describe,
} from "./dev-deps.js";
import {
ASYNC_ITERATOR,
+ completePropertyDescriptor,
HAS_INSTANCE,
IS_CONCAT_SPREADABLE,
+ isAccessorDescriptor,
+ isDataDescriptor,
+ isFullyPopulatedDescriptor,
+ isGenericDescriptor,
+ isPropertyDescriptorRecord,
ITERATOR,
LN10,
LN2,
toIndex,
toLength,
toPrimitive,
+ toPropertyDescriptor,
type,
UNDEFINED,
UNSCOPABLES,
});
});
-describe("Ε", () => {
- it("[[Get]] is ε", () => {
- assertStrictEquals(Ε, Number.EPSILON);
+describe("completePropertyDescriptor", () => {
+ it("[[Call]] completes a generic descriptor", () => {
+ const desc = {};
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ value: undefined,
+ writable: false,
+ });
+ });
+
+ it("[[Call]] completes a data descriptor", () => {
+ const desc = { value: undefined };
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ value: undefined,
+ writable: false,
+ });
+ });
+
+ it("[[Call]] completes an accessor descriptor", () => {
+ const desc = { get: undefined };
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ get: undefined,
+ set: undefined,
+ });
+ });
+
+ it("[[Call]] throws an error when the descriptor is undefined", () => {
+ assertThrows(() => new completePropertyDescriptor(undefined));
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new completePropertyDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(completePropertyDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ completePropertyDescriptor.name,
+ "completePropertyDescriptor",
+ );
+ });
});
});
-describe("Π", () => {
- it("[[Get]] is π", () => {
- assertStrictEquals(Π, Math.PI);
+describe("isAccessorDescriptor", () => {
+ it("[[Call]] returns false for a generic descriptor", () => {
+ assertStrictEquals(isAccessorDescriptor({}), false);
+ });
+
+ it("[[Get]] returns false for a data descriptor", () => {
+ assertStrictEquals(
+ isAccessorDescriptor({ value: undefined }),
+ false,
+ );
+ assertStrictEquals(
+ isAccessorDescriptor({ writable: undefined }),
+ false,
+ );
+ });
+
+ it("[[Get]] returns true for an accessor descriptor", () => {
+ assertStrictEquals(isAccessorDescriptor({ get: undefined }), true);
+ assertStrictEquals(isAccessorDescriptor({ set: undefined }), true);
+ });
+
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isAccessorDescriptor(undefined), false);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new isAccessorDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isAccessorDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isAccessorDescriptor.name,
+ "isAccessorDescriptor",
+ );
+ });
});
});
-describe("ℇ", () => {
- it("[[Get]] is ℇ", () => {
- assertStrictEquals(ℇ, Math.E);
+describe("isDataDescriptor", () => {
+ it("[[Call]] returns false for a generic descriptor", () => {
+ assertStrictEquals(isDataDescriptor({}), false);
+ });
+
+ it("[[Get]] returns true for a data descriptor", () => {
+ assertStrictEquals(isDataDescriptor({ value: undefined }), true);
+ assertStrictEquals(isDataDescriptor({ writable: true }), true);
+ });
+
+ it("[[Get]] returns false for an accessor descriptor", () => {
+ assertStrictEquals(isDataDescriptor({ get: undefined }), false);
+ assertStrictEquals(isDataDescriptor({ set: undefined }), false);
+ });
+
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isDataDescriptor(undefined), false);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new isDataDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isDataDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(isDataDescriptor.name, "isDataDescriptor");
+ });
+ });
+});
+
+describe("isFullyPopulatedDescriptor", () => {
+ it("[[Call]] returns false for a generic descriptor", () => {
+ assertStrictEquals(isFullyPopulatedDescriptor({}), false);
+ });
+
+ it("[[Get]] returns false for a non‐fully‐populated data descriptor", () => {
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({ value: undefined }),
+ false,
+ );
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({ writable: true }),
+ false,
+ );
+ });
+
+ it("[[Get]] returns true for a fully‐populated data descriptor", () => {
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({
+ configurable: true,
+ enumerable: true,
+ value: undefined,
+ writable: true,
+ }),
+ true,
+ );
+ });
+
+ it("[[Get]] returns false for a non‐fully‐populated accessor descriptor", () => {
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({ get: undefined }),
+ false,
+ );
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({ set: undefined }),
+ false,
+ );
+ });
+
+ it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
+ assertStrictEquals(
+ isFullyPopulatedDescriptor({
+ configurable: true,
+ enumerable: true,
+ get: undefined,
+ set: undefined,
+ }),
+ true,
+ );
+ });
+
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isFullyPopulatedDescriptor(undefined), false);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new isFullyPopulatedDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isFullyPopulatedDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isFullyPopulatedDescriptor.name,
+ "isFullyPopulatedDescriptor",
+ );
+ });
+ });
+});
+
+describe("isGenericDescriptor", () => {
+ it("[[Call]] returns true for a generic descriptor", () => {
+ assertStrictEquals(isGenericDescriptor({}), true);
+ });
+
+ it("[[Get]] returns false for a data descriptor", () => {
+ assertStrictEquals(
+ isGenericDescriptor({ value: undefined }),
+ false,
+ );
+ assertStrictEquals(isGenericDescriptor({ writable: true }), false);
+ });
+
+ it("[[Get]] returns false for an accessor descriptor", () => {
+ assertStrictEquals(isGenericDescriptor({ get: undefined }), false);
+ assertStrictEquals(isGenericDescriptor({ set: undefined }), false);
+ });
+
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isGenericDescriptor(undefined), false);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new isGenericDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isGenericDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isGenericDescriptor.name,
+ "isGenericDescriptor",
+ );
+ });
+ });
+});
+
+describe("isPropertyDescriptorRecord", () => {
+ it("[[Call]] returns true for objects created by toPropertyDescriptor", () => {
+ assertStrictEquals(
+ isPropertyDescriptorRecord(toPropertyDescriptor({})),
+ true,
+ );
+ });
+
+ it("[[Get]] returns false for other objects", () => {
+ assertStrictEquals(
+ isPropertyDescriptorRecord(Object.create(null)),
+ false,
+ );
+ });
+
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isPropertyDescriptorRecord(undefined), false);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new isPropertyDescriptorRecord({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isPropertyDescriptorRecord.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isPropertyDescriptorRecord.name,
+ "isPropertyDescriptorRecord",
+ );
+ });
});
});
});
});
+describe("toPropertyDescriptor", () => {
+ it("[[Call]] creates a new property descriptor record", () => {
+ const obj = {};
+ const desc = toPropertyDescriptor(obj);
+ assertEquals(obj, desc);
+ assertNotStrictEquals(obj, desc);
+ });
+
+ it("[[Call]] coerces the values", () => {
+ assertEquals(
+ toPropertyDescriptor({
+ configurable: undefined,
+ enumerable: undefined,
+ writable: undefined,
+ }),
+ { configurable: false, enumerable: false, writable: false },
+ );
+ });
+
+ it("[[Construct]] throws for primitives", () => {
+ assertThrows(() => toPropertyDescriptor(undefined));
+ assertThrows(() => toPropertyDescriptor("failure"));
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toPropertyDescriptor({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toPropertyDescriptor.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ toPropertyDescriptor.name,
+ "toPropertyDescriptor",
+ );
+ });
+ });
+
+ describe("~configurable", () => {
+ it("[[DefineOwnProperty]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "configurable", {});
+ assertStrictEquals(desc.configurable, false);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "configurable", { get: undefined })
+ );
+ });
+
+ it("[[Set]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ desc.configurable = undefined;
+ assertStrictEquals(desc.configurable, false);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ configurable: false });
+ delete desc.configurable;
+ assert(!("configurable" in desc));
+ });
+ });
+
+ describe("~enumerable", () => {
+ it("[[DefineOwnProperty]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "enumerable", {});
+ assertStrictEquals(desc.enumerable, false);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "enumerable", { get: undefined })
+ );
+ });
+
+ it("[[Set]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ desc.enumerable = undefined;
+ assertStrictEquals(desc.enumerable, false);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ enumerable: false });
+ delete desc.enumerable;
+ assert(!("enumerable" in desc));
+ });
+ });
+
+ describe("~get", () => {
+ it("[[DefineOwnProperty]] works", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "get", {});
+ assertStrictEquals(desc.get, undefined);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "get", { get: undefined })
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(
+ () => Object.defineProperty(desc, "get", { value: null }),
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if a data property is defined", () => {
+ const desc = toPropertyDescriptor({ value: undefined });
+ assertThrows(() => Object.defineProperty(desc, "get", {}));
+ });
+
+ it("[[Set]] works", () => {
+ const desc = toPropertyDescriptor({});
+ const fn = () => {};
+ desc.get = fn;
+ assertStrictEquals(desc.get, fn);
+ });
+
+ it("[[Set]] throws if not callable or undefined", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() => desc.get = null);
+ });
+
+ it("[[Set]] throws if a data property is defined", () => {
+ const desc = toPropertyDescriptor({ value: undefined });
+ assertThrows(() => desc.get = undefined);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ get: undefined });
+ delete desc.get;
+ assert(!("get" in desc));
+ });
+ });
+
+ describe("~set", () => {
+ it("[[DefineOwnProperty]] works", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "set", {});
+ assertStrictEquals(desc.set, undefined);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "set", { get: undefined })
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if not callable or undefined", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(
+ () => Object.defineProperty(desc, "set", { value: null }),
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if a data property is defined", () => {
+ const desc = toPropertyDescriptor({ value: undefined });
+ assertThrows(() => Object.defineProperty(desc, "set", {}));
+ });
+
+ it("[[Set]] works", () => {
+ const desc = toPropertyDescriptor({});
+ const fn = (_) => {};
+ desc.set = fn;
+ assertStrictEquals(desc.set, fn);
+ });
+
+ it("[[Set]] throws if not callable or undefined", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() => desc.set = null);
+ });
+
+ it("[[Set]] throws if a data property is defined", () => {
+ const desc = toPropertyDescriptor({ value: undefined });
+ assertThrows(() => desc.set = undefined);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ set: undefined });
+ delete desc.set;
+ assert(!("set" in desc));
+ });
+ });
+
+ describe("~value", () => {
+ it("[[DefineOwnProperty]] works", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "value", {});
+ assertStrictEquals(desc.value, undefined);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "value", { get: undefined })
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
+ const desc = toPropertyDescriptor({ get: undefined });
+ assertThrows(() => Object.defineProperty(desc, "value", {}));
+ });
+
+ it("[[Set]] works", () => {
+ const desc = toPropertyDescriptor({});
+ desc.value = "success";
+ assertStrictEquals(desc.value, "success");
+ });
+
+ it("[[Set]] throws if an accessor property is defined", () => {
+ const desc = toPropertyDescriptor({ get: undefined });
+ assertThrows(() => desc.value = null);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ value: undefined });
+ delete desc.value;
+ assert(!("value" in desc));
+ });
+ });
+
+ describe("~writable", () => {
+ it("[[DefineOwnProperty]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ Object.defineProperty(desc, "writable", {});
+ assertStrictEquals(desc.writable, false);
+ });
+
+ it("[[DefineOwnProperty]] throws for accessor properties", () => {
+ const desc = toPropertyDescriptor({});
+ assertThrows(() =>
+ Object.defineProperty(desc, "writable", { get: undefined })
+ );
+ });
+
+ it("[[DefineOwnProperty]] throws if an accessor property is defined", () => {
+ const desc = toPropertyDescriptor({ get: undefined });
+ assertThrows(() => Object.defineProperty(desc, "writable", {}));
+ });
+
+ it("[[Set]] coerces to a boolean", () => {
+ const desc = toPropertyDescriptor({});
+ desc.writable = undefined;
+ assertStrictEquals(desc.writable, false);
+ });
+
+ it("[[Set]] throws if an accessor property is defined", () => {
+ const desc = toPropertyDescriptor({ get: undefined });
+ assertThrows(() => desc.writable = false);
+ });
+
+ it("[[Delete]] works", () => {
+ const desc = toPropertyDescriptor({ writable: false });
+ delete desc.writable;
+ assert(!("writable" in desc));
+ });
+ });
+});
+
describe("type", () => {
it('[[Call]] returns "null" for null', () => {
assertStrictEquals(type(null), "null");
});
});
});
+
+describe("Ε", () => {
+ it("[[Get]] is ε", () => {
+ assertStrictEquals(Ε, Number.EPSILON);
+ });
+});
+
+describe("Π", () => {
+ it("[[Get]] is π", () => {
+ assertStrictEquals(Π, Math.PI);
+ });
+});
+
+describe("ℇ", () => {
+ it("[[Get]] is ℇ", () => {
+ assertStrictEquals(ℇ, Math.E);
+ });
+});