// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
import {
+ assertEquals,
assertStrictEquals,
assertThrows,
describe,
} from "./dev-deps.js";
import {
ASYNC_ITERATOR,
- canonicalNumericIndexString,
+ completePropertyDescriptor,
HAS_INSTANCE,
IS_CONCAT_SPREADABLE,
+ isAccessorDescriptor,
+ isDataDescriptor,
+ isFullyPopulatedDescriptor,
+ isGenericDescriptor,
ITERATOR,
- lengthOfArraylike,
+ 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("canonicalNumericIndexString", () => {
- it("[[Call]] returns undefined for nonstrings", () => {
- assertStrictEquals(canonicalNumericIndexString(1), void {});
+describe("completePropertyDescriptor", () => {
+ it("[[Call]] completes a generic descriptor", () => {
+ const desc = {};
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ value: undefined,
+ writable: false,
+ });
});
- it("[[Call]] returns undefined for noncanonical strings", () => {
- assertStrictEquals(canonicalNumericIndexString(""), void {});
- assertStrictEquals(canonicalNumericIndexString("01"), void {});
- assertStrictEquals(
- canonicalNumericIndexString("9007199254740993"),
- void {},
- );
+ it("[[Call]] completes a data descriptor", () => {
+ const desc = { value: undefined };
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ value: undefined,
+ writable: false,
+ });
});
- it('[[Call]] returns -0 for "-0"', () => {
- assertStrictEquals(canonicalNumericIndexString("-0"), -0);
+ it("[[Call]] completes an accessor descriptor", () => {
+ const desc = { get: undefined };
+ completePropertyDescriptor(desc);
+ assertEquals(desc, {
+ configurable: false,
+ enumerable: false,
+ get: undefined,
+ set: undefined,
+ });
});
- it("[[Call]] returns the corresponding number for canonical strings", () => {
- assertStrictEquals(canonicalNumericIndexString("0"), 0);
- assertStrictEquals(canonicalNumericIndexString("-0.25"), -0.25);
+ 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(
- canonicalNumericIndexString("9007199254740992"),
- 9007199254740992,
+ isAccessorDescriptor({ value: undefined }),
+ false,
);
- assertStrictEquals(canonicalNumericIndexString("NaN"), 0 / 0);
- assertStrictEquals(canonicalNumericIndexString("Infinity"), 1 / 0);
assertStrictEquals(
- canonicalNumericIndexString("-Infinity"),
- -1 / 0,
+ 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 canonicalNumericIndexString(""));
+ assertThrows(() => new isAccessorDescriptor({}));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(canonicalNumericIndexString.length, 1);
+ assertStrictEquals(isAccessorDescriptor.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(
- canonicalNumericIndexString.name,
- "canonicalNumericIndexString",
+ isAccessorDescriptor.name,
+ "isAccessorDescriptor",
);
});
});
});
-describe("lengthOfArraylike", () => {
- it("[[Call]] returns the length", () => {
- assertStrictEquals(
- lengthOfArraylike({ length: 9007199254740991 }),
- 9007199254740991,
- );
+describe("isDataDescriptor", () => {
+ it("[[Call]] returns false for a generic descriptor", () => {
+ assertStrictEquals(isDataDescriptor({}), false);
});
- it("[[Call]] returns a non·nan result", () => {
- assertStrictEquals(lengthOfArraylike({ length: NaN }), 0);
- assertStrictEquals(lengthOfArraylike({ length: "failure" }), 0);
+ it("[[Get]] returns true for a data descriptor", () => {
+ assertStrictEquals(isDataDescriptor({ value: undefined }), true);
+ assertStrictEquals(isDataDescriptor({ writable: true }), true);
});
- it("[[Call]] returns an integral result", () => {
- assertStrictEquals(lengthOfArraylike({ length: 0.25 }), 0);
- assertStrictEquals(lengthOfArraylike({ length: 1.1 }), 1);
+ it("[[Get]] returns false for an accessor descriptor", () => {
+ assertStrictEquals(isDataDescriptor({ get: undefined }), false);
+ assertStrictEquals(isDataDescriptor({ set: undefined }), false);
});
- it("[[Call]] returns a result greater than or equal to zero", () => {
- assertStrictEquals(lengthOfArraylike({ length: -0 }), 0);
- assertStrictEquals(lengthOfArraylike({ length: -1 }), 0);
- assertStrictEquals(lengthOfArraylike({ length: -Infinity }), 0);
+ it("[[Get]] returns false for undefined", () => {
+ assertStrictEquals(isDataDescriptor(undefined), false);
});
- it("[[Call]] returns a result less than 2 ** 53", () => {
+ 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(
- lengthOfArraylike({ length: 9007199254740992 }),
- 9007199254740991,
+ isFullyPopulatedDescriptor({ set: undefined }),
+ false,
);
+ });
+
+ it("[[Get]] returns true for a fully‐populated accessor descriptor", () => {
assertStrictEquals(
- lengthOfArraylike({ length: Infinity }),
- 9007199254740991,
+ isFullyPopulatedDescriptor({
+ configurable: true,
+ enumerable: true,
+ get: undefined,
+ set: undefined,
+ }),
+ true,
);
});
- it("[[Call]] does not require an object argument", () => {
- assertStrictEquals(lengthOfArraylike("string"), 6);
- assertStrictEquals(lengthOfArraylike(Symbol()), 0);
+ 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 lengthOfArraylike(""));
+ assertThrows(() => new isGenericDescriptor({}));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(lengthOfArraylike.length, 1);
+ assertStrictEquals(isGenericDescriptor.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
- assertStrictEquals(lengthOfArraylike.name, "lengthOfArraylike");
+ assertStrictEquals(
+ isGenericDescriptor.name,
+ "isGenericDescriptor",
+ );
});
});
});
});
});
+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);
});
});
+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");
});
});
});
+
+describe("Ε", () => {
+ it("[[Get]] is ε", () => {
+ assertStrictEquals(Ε, Number.EPSILON);
+ });
+});
+
+describe("Π", () => {
+ it("[[Get]] is π", () => {
+ assertStrictEquals(Π, Math.PI);
+ });
+});
+
+describe("ℇ", () => {
+ it("[[Get]] is ℇ", () => {
+ assertStrictEquals(ℇ, Math.E);
+ });
+});