// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
import {
+ assertEquals,
assertStrictEquals,
assertThrows,
describe,
} from "./dev-deps.js";
import {
ASYNC_ITERATOR,
+ completePropertyDescriptor,
HAS_INSTANCE,
IS_CONCAT_SPREADABLE,
+ isAccessorDescriptor,
+ isDataDescriptor,
+ isFullyPopulatedDescriptor,
+ isGenericDescriptor,
ITERATOR,
+ LN10,
+ LN2,
+ LOG10ℇ,
+ LOG2ℇ,
MATCH,
MATCH_ALL,
+ MAXIMUM_NUMBER,
+ MAXIMUM_SAFE_INTEGRAL_NUMBER,
+ MINIMUM_NUMBER,
+ MINIMUM_SAFE_INTEGRAL_NUMBER,
+ NAN,
+ NEGATIVE_INFINITY,
+ NEGATIVE_ZERO,
NULL,
ordinaryToPrimitive,
+ POSITIVE_INFINITY,
+ POSITIVE_ZERO,
+ RECIPROCAL_SQRT2,
REPLACE,
sameValue,
sameValueZero,
SPECIES,
SPLIT,
+ SQRT2,
TO_PRIMITIVE,
TO_STRING_TAG,
+ toFunctionName,
+ toIndex,
+ toLength,
toPrimitive,
+ toPropertyKey,
type,
UNDEFINED,
UNSCOPABLES,
+ Ε,
+ Π,
+ ℇ,
} from "./value.js";
describe("ASYNC_ITERATOR", () => {
});
});
+describe("LN10", () => {
+ it("[[Get]] is ln(10)", () => {
+ assertStrictEquals(LN10, Math.LN10);
+ });
+});
+
+describe("LN2", () => {
+ it("[[Get]] is ln(2)", () => {
+ assertStrictEquals(LN2, Math.LN2);
+ });
+});
+
+describe("LOG10ℇ", () => {
+ it("[[Get]] is log10(ℇ)", () => {
+ assertStrictEquals(LOG10ℇ, Math.LOG10E);
+ });
+});
+
+describe("LOG2ℇ", () => {
+ it("[[Get]] is log2(ℇ)", () => {
+ assertStrictEquals(LOG2ℇ, Math.LOG2E);
+ });
+});
+
describe("MATCH", () => {
it("[[Get]] is @@match", () => {
assertStrictEquals(MATCH, Symbol.match);
});
});
+describe("MAXIMUM_NUMBER", () => {
+ it("[[Get]] is the maximum number", () => {
+ assertStrictEquals(MAXIMUM_NUMBER, Number.MAX_VALUE);
+ });
+});
+
+describe("MAXIMUM_SAFE_INTEGRAL_NUMBER", () => {
+ it("[[Get]] is the maximum safe integral number", () => {
+ assertStrictEquals(
+ MAXIMUM_SAFE_INTEGRAL_NUMBER,
+ Number.MAX_SAFE_INTEGER,
+ );
+ });
+});
+
+describe("MINIMUM_NUMBER", () => {
+ it("[[Get]] is the minimum number", () => {
+ assertStrictEquals(MINIMUM_NUMBER, Number.MIN_VALUE);
+ });
+});
+
+describe("MINIMUM_SAFE_INTEGRAL_NUMBER", () => {
+ it("[[Get]] is the minimum safe integral number", () => {
+ assertStrictEquals(
+ MINIMUM_SAFE_INTEGRAL_NUMBER,
+ Number.MIN_SAFE_INTEGER,
+ );
+ });
+});
+
+describe("NAN", () => {
+ it("[[Get]] is nan", () => {
+ assertStrictEquals(NAN, NaN);
+ });
+});
+
+describe("NEGATIVE_INFINITY", () => {
+ it("[[Get]] is negative infinity", () => {
+ assertStrictEquals(NEGATIVE_INFINITY, -Infinity);
+ });
+});
+
+describe("NEGATIVE_ZERO", () => {
+ it("[[Get]] is negative zero", () => {
+ assertStrictEquals(NEGATIVE_ZERO, -0);
+ });
+});
+
describe("NULL", () => {
it("[[Get]] is null", () => {
assertStrictEquals(NULL, null);
});
});
+describe("POSITIVE_INFINITY", () => {
+ it("[[Get]] is negative infinity", () => {
+ assertStrictEquals(POSITIVE_INFINITY, Infinity);
+ });
+});
+
+describe("POSITIVE_ZERO", () => {
+ it("[[Get]] is positive zero", () => {
+ assertStrictEquals(POSITIVE_ZERO, 0);
+ });
+});
+
+describe("RECIPROCAL_SQRT2", () => {
+ it("[[Get]] is sqrt(½)", () => {
+ assertStrictEquals(RECIPROCAL_SQRT2, Math.SQRT1_2);
+ });
+});
+
describe("REPLACE", () => {
it("[[Get]] is @@replace", () => {
assertStrictEquals(REPLACE, Symbol.replace);
});
});
+describe("SQRT2", () => {
+ it("[[Get]] is sqrt(2)", () => {
+ assertStrictEquals(SQRT2, Math.SQRT2);
+ });
+});
+
describe("TO_PRIMITIVE", () => {
it("[[Get]] is @@toPrimitive", () => {
assertStrictEquals(TO_PRIMITIVE, Symbol.toPrimitive);
});
});
+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("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("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("ordinaryToPrimitive", () => {
it("[[Call]] prefers `valueOf` by default", () => {
const obj = {
assertThrows(() => ordinaryToPrimitive(obj));
});
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new ordinaryToPrimitive(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(ordinaryToPrimitive.length, 2);
+ });
+ });
+
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(
assertStrictEquals(sameValue(false, new Boolean(false)), false);
});
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new sameValue(true, true));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(sameValue.length, 2);
+ });
+ });
+
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(sameValue.name, "sameValue");
);
});
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new sameValueZero(true, true));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(sameValueZero.length, 2);
+ });
+ });
+
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(sameValueZero.name, "sameValueZero");
});
});
+describe("toFunctionName", () => {
+ it("[[Call]] works with strings and no prefix", () => {
+ assertStrictEquals(toFunctionName("etaoin"), "etaoin");
+ });
+
+ it("[[Call]] works with objects and no prefix", () => {
+ assertStrictEquals(
+ toFunctionName({
+ toString() {
+ return "etaoin";
+ },
+ }),
+ "etaoin",
+ );
+ });
+
+ it("[[Call]] works with descriptionless symbols and no prefix", () => {
+ assertStrictEquals(toFunctionName(Symbol()), "");
+ });
+
+ it("[[Call]] works with empty description symbols and no prefix", () => {
+ assertStrictEquals(toFunctionName(Symbol("")), "[]");
+ });
+
+ it("[[Call]] works with described symbols and no prefix", () => {
+ assertStrictEquals(toFunctionName(Symbol("etaoin")), "[etaoin]");
+ });
+
+ it("[[Call]] works with strings and a prefix", () => {
+ assertStrictEquals(toFunctionName("etaoin", "foo"), "foo etaoin");
+ });
+
+ it("[[Call]] works with objects and no prefix", () => {
+ assertStrictEquals(
+ toFunctionName({
+ toString() {
+ return "etaoin";
+ },
+ }, "foo"),
+ "foo etaoin",
+ );
+ });
+
+ it("[[Call]] works with descriptionless symbols and no prefix", () => {
+ assertStrictEquals(toFunctionName(Symbol(), "foo"), "foo ");
+ });
+
+ it("[[Call]] works with empty description symbols and no prefix", () => {
+ assertStrictEquals(toFunctionName(Symbol(""), "foo"), "foo []");
+ });
+
+ it("[[Call]] works with described symbols and no prefix", () => {
+ assertStrictEquals(
+ toFunctionName(Symbol("etaoin"), "foo"),
+ "foo [etaoin]",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toFunctionName(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toFunctionName.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ toFunctionName.name,
+ "toFunctionName",
+ );
+ });
+ });
+});
+
+describe("toIndex", () => {
+ it("[[Call]] returns an index", () => {
+ assertStrictEquals(toIndex(9007199254740991), 9007199254740991);
+ });
+
+ it("[[Call]] returns zero for a zerolike argument", () => {
+ assertStrictEquals(toIndex(NaN), 0);
+ assertStrictEquals(toIndex("failure"), 0);
+ assertStrictEquals(toIndex(-0), 0);
+ });
+
+ it("[[Call]] rounds down to the nearest integer", () => {
+ assertStrictEquals(toIndex(0.25), 0);
+ assertStrictEquals(toIndex(1.1), 1);
+ });
+
+ it("[[Call]] throws when provided a negative number", () => {
+ assertThrows(() => toIndex(-1));
+ assertThrows(() => toIndex(-Infinity));
+ });
+
+ it("[[Call]] throws when provided a number greater than or equal to 2 ** 53", () => {
+ assertThrows(() => toIndex(9007199254740992));
+ assertThrows(() => toIndex(Infinity));
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toIndex(0));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toIndex.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(toIndex.name, "toIndex");
+ });
+ });
+});
+
+describe("toLength", () => {
+ it("[[Call]] returns a length", () => {
+ assertStrictEquals(toLength(9007199254740991), 9007199254740991);
+ });
+
+ it("[[Call]] returns zero for a nan argument", () => {
+ assertStrictEquals(toLength(NaN), 0);
+ assertStrictEquals(toLength("failure"), 0);
+ });
+
+ it("[[Call]] rounds down to the nearest integer", () => {
+ assertStrictEquals(toLength(0.25), 0);
+ assertStrictEquals(toLength(1.1), 1);
+ });
+
+ it("[[Call]] returns a result greater than or equal to zero", () => {
+ assertStrictEquals(toLength(-0), 0);
+ assertStrictEquals(toLength(-1), 0);
+ assertStrictEquals(toLength(-Infinity), 0);
+ });
+
+ it("[[Call]] returns a result less than 2 ** 53", () => {
+ assertStrictEquals(toLength(9007199254740992), 9007199254740991);
+ assertStrictEquals(toLength(Infinity), 9007199254740991);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toLength(0));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toLength.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(toLength.name, "toLength");
+ });
+ });
+});
+
describe("toPrimitive", () => {
it("[[Call]] returns the argument when passed a primitive", () => {
const value = Symbol();
},
},
);
- assertStrictEquals(toPrimitive(value, "default"), "success");
+ assertStrictEquals(toPrimitive(value), "success");
});
it("[[Call]] throws for an invalid hint", () => {
assertThrows(() => toPrimitive(true, "badhint"));
});
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toPrimitive(true));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toPrimitive.length, 1);
+ });
+ });
+
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(toPrimitive.name, "toPrimitive");
});
});
+describe("toPropertyKey", () => {
+ it("returns a string or symbol", () => {
+ const sym = Symbol();
+ assertStrictEquals(toPropertyKey(sym), sym);
+ assertStrictEquals(
+ toPropertyKey(new String("success")),
+ "success",
+ );
+ });
+
+ it("favours the `toString` representation", () => {
+ assertStrictEquals(
+ toPropertyKey({
+ toString() {
+ return "success";
+ },
+ valueOf() {
+ return "failure";
+ },
+ }),
+ "success",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toPropertyKey(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toPropertyKey.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(toPropertyKey.name, "toPropertyKey");
+ });
+ });
+});
+
describe("type", () => {
it('[[Call]] returns "null" for null', () => {
assertStrictEquals(type(null), "null");
assertStrictEquals(type(class {}), "object");
});
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new type({}));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(type.length, 1);
+ });
+ });
+
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(type.name, "type");
});
});
});
+
+describe("Ε", () => {
+ it("[[Get]] is ε", () => {
+ assertStrictEquals(Ε, Number.EPSILON);
+ });
+});
+
+describe("Π", () => {
+ it("[[Get]] is π", () => {
+ assertStrictEquals(Π, Math.PI);
+ });
+});
+
+describe("ℇ", () => {
+ it("[[Get]] is ℇ", () => {
+ assertStrictEquals(ℇ, Math.E);
+ });
+});