import {
asciiLowercase,
asciiUppercase,
+ canonicalNumericIndexString,
characters,
codepoints,
codeUnits,
getCodeUnit,
getFirstSubstringIndex,
getLastSubstringIndex,
+ isArrayIndexString,
+ isIntegerIndexString,
join,
Matcher,
rawString,
scalarValues,
- scalarValueString,
- splitOnASCIIWhitespace,
+ splitOnAsciiWhitespace,
splitOnCommas,
stringCatenate,
stringEndsWith,
stringSplit,
stringStartsWith,
stringValue,
- stripAndCollapseASCIIWhitespace,
- stripLeadingAndTrailingASCIIWhitespace,
+ stripAndCollapseAsciiWhitespace,
+ stripLeadingAndTrailingAsciiWhitespace,
substring,
+ toScalarValueString,
toString,
} from "./string.js";
});
});
+ describe("::constructor", () => {
+ it("[[Get]] returns the same constructor", () => {
+ assertStrictEquals(new Matcher(/(?:)/su).constructor, Matcher);
+ });
+ });
+
describe("::dotAll", () => {
it("[[Get]] returns true when the dotAll flag is present", () => {
assertStrictEquals(new Matcher(/(?:)/su).dotAll, true);
});
});
+describe("canonicalNumericIndexString", () => {
+ it("[[Call]] returns undefined for nonstrings", () => {
+ assertStrictEquals(canonicalNumericIndexString(1), void {});
+ });
+
+ it("[[Call]] returns undefined for noncanonical strings", () => {
+ assertStrictEquals(canonicalNumericIndexString(""), void {});
+ assertStrictEquals(canonicalNumericIndexString("01"), void {});
+ assertStrictEquals(
+ canonicalNumericIndexString("9007199254740993"),
+ void {},
+ );
+ });
+
+ it('[[Call]] returns -0 for "-0"', () => {
+ assertStrictEquals(canonicalNumericIndexString("-0"), -0);
+ });
+
+ it("[[Call]] returns the corresponding number for canonical strings", () => {
+ assertStrictEquals(canonicalNumericIndexString("0"), 0);
+ assertStrictEquals(canonicalNumericIndexString("-0.25"), -0.25);
+ assertStrictEquals(
+ canonicalNumericIndexString("9007199254740992"),
+ 9007199254740992,
+ );
+ assertStrictEquals(canonicalNumericIndexString("NaN"), 0 / 0);
+ assertStrictEquals(canonicalNumericIndexString("Infinity"), 1 / 0);
+ assertStrictEquals(
+ canonicalNumericIndexString("-Infinity"),
+ -1 / 0,
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new canonicalNumericIndexString(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(canonicalNumericIndexString.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ canonicalNumericIndexString.name,
+ "canonicalNumericIndexString",
+ );
+ });
+ });
+});
+
describe("characters", () => {
it("[[Call]] returns an iterable", () => {
assertStrictEquals(
});
});
-describe("join", () => {
- it("[[Call]] joins the provided iterator with the provided separartor", () => {
- assertStrictEquals(join([1, 2, 3, 4].values(), "☂"), "1☂2☂3☂4");
+describe("isArrayIndexString", () => {
+ it("[[Call]] returns false for nonstrings", () => {
+ assertStrictEquals(isArrayIndexString(1), false);
});
- it('[[Call]] uses "," if no separator is provided', () => {
- assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
+ it("[[Call]] returns false for noncanonical strings", () => {
+ assertStrictEquals(isArrayIndexString(""), false);
+ assertStrictEquals(isArrayIndexString("01"), false);
+ assertStrictEquals(isArrayIndexString("9007199254740993"), false);
});
- it("[[Call]] uses the empty sting for nullish values", () => {
+ it("[[Call]] returns false for nonfinite numbers", () => {
+ assertStrictEquals(isArrayIndexString("NaN"), false);
+ assertStrictEquals(isArrayIndexString("Infinity"), false);
+ assertStrictEquals(isArrayIndexString("-Infinity"), false);
+ });
+
+ it("[[Call]] returns false for negative numbers", () => {
+ assertStrictEquals(isArrayIndexString("-0"), false);
+ assertStrictEquals(isArrayIndexString("-1"), false);
+ });
+
+ it("[[Call]] returns false for nonintegers", () => {
+ assertStrictEquals(isArrayIndexString("0.25"), false);
+ assertStrictEquals(isArrayIndexString("1.1"), false);
+ });
+
+ it("[[Call]] returns false for numbers greater than or equal to -1 >>> 0", () => {
+ assertStrictEquals(isArrayIndexString(String(-1 >>> 0)), false);
assertStrictEquals(
- join([null, , null, undefined].values(), "☂"),
- "☂☂☂",
+ isArrayIndexString(String((-1 >>> 0) + 1)),
+ false,
+ );
+ });
+
+ it("[[Call]] returns true for array lengths less than -1 >>> 0", () => {
+ assertStrictEquals(isArrayIndexString("0"), true);
+ assertStrictEquals(
+ isArrayIndexString(String((-1 >>> 0) - 1)),
+ true,
);
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new join([]));
+ assertThrows(() => new isArrayIndexString("0"));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(join.length, 2);
+ assertStrictEquals(isArrayIndexString.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
- assertStrictEquals(join.name, "join");
+ assertStrictEquals(
+ isArrayIndexString.name,
+ "isArrayIndexString",
+ );
});
});
});
-describe("rawString", () => {
- it("[[Call]] acts like String.raw", () => {
- assertStrictEquals(rawString`\nraw${" string"}`, "\\nraw string");
+describe("isIntegerIndexString", () => {
+ it("[[Call]] returns false for nonstrings", () => {
+ assertStrictEquals(isIntegerIndexString(1), false);
+ });
+
+ it("[[Call]] returns false for noncanonical strings", () => {
+ assertStrictEquals(isIntegerIndexString(""), false);
+ assertStrictEquals(isIntegerIndexString("01"), false);
+ assertStrictEquals(
+ isIntegerIndexString("9007199254740993"),
+ false,
+ );
+ });
+
+ it("[[Call]] returns false for nonfinite numbers", () => {
+ assertStrictEquals(isIntegerIndexString("NaN"), false);
+ assertStrictEquals(isIntegerIndexString("Infinity"), false);
+ assertStrictEquals(isIntegerIndexString("-Infinity"), false);
+ });
+
+ it("[[Call]] returns false for negative numbers", () => {
+ assertStrictEquals(isIntegerIndexString("-0"), false);
+ assertStrictEquals(isIntegerIndexString("-1"), false);
+ });
+
+ it("[[Call]] returns false for nonintegers", () => {
+ assertStrictEquals(isIntegerIndexString("0.25"), false);
+ assertStrictEquals(isIntegerIndexString("1.1"), false);
+ });
+
+ it("[[Call]] returns false for numbers greater than or equal to 2 ** 53", () => {
+ assertStrictEquals(
+ isIntegerIndexString("9007199254740992"),
+ false,
+ );
+ });
+
+ it("[[Call]] returns true for safe canonical integer strings", () => {
+ assertStrictEquals(isIntegerIndexString("0"), true);
+ assertStrictEquals(isIntegerIndexString("9007199254740991"), true);
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new rawString(["string"]));
+ assertThrows(() => new isIntegerIndexString("0"));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(rawString.length, 1);
+ assertStrictEquals(isIntegerIndexString.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
- assertStrictEquals(rawString.name, "rawString");
+ assertStrictEquals(
+ isIntegerIndexString.name,
+ "isIntegerIndexString",
+ );
});
});
});
-describe("scalarValueString", () => {
- it("[[Call]] replaces invalid values", () => {
+describe("join", () => {
+ it("[[Call]] joins the provided iterator with the provided separartor", () => {
+ assertStrictEquals(join([1, 2, 3, 4].values(), "☂"), "1☂2☂3☂4");
+ });
+
+ it('[[Call]] uses "," if no separator is provided', () => {
+ assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
+ });
+
+ it("[[Call]] uses the empty sting for nullish values", () => {
assertStrictEquals(
- scalarValueString("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
- "Ii🎙\uFFFD\uFFFD\uFFFD\uFFFD🆗☺",
+ join([null, , null, undefined].values(), "☂"),
+ "☂☂☂",
);
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new scalarValueString(""));
+ assertThrows(() => new join([]));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(join.length, 2);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(join.name, "join");
+ });
+ });
+});
+
+describe("rawString", () => {
+ it("[[Call]] acts like String.raw", () => {
+ assertStrictEquals(rawString`\nraw${" string"}`, "\\nraw string");
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new rawString(["string"]));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(scalarValueString.length, 1);
+ assertStrictEquals(rawString.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
- assertStrictEquals(scalarValueString.name, "scalarValueString");
+ assertStrictEquals(rawString.name, "rawString");
});
});
});
});
});
-describe("splitOnASCIIWhitespace", () => {
+describe("splitOnAsciiWhitespace", () => {
it("[[Call]] splits on sequences of spaces", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️ 🅱️ 🆎 🅾️"),
+ splitOnAsciiWhitespace("🅰️ 🅱️ 🆎 🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] splits on sequences of tabs", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
+ splitOnAsciiWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] splits on sequences of carriage returns", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
+ splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] splits on sequences of newlines", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
+ splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] splits on sequences of form feeds", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
+ splitOnAsciiWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] splits on mixed whitespace", () => {
assertEquals(
- splitOnASCIIWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
+ splitOnAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
["🅰️", "🅱️", "🆎", "🅾️"],
);
});
it("[[Call]] returns an array of just the empty string for the empty string", () => {
- assertEquals(splitOnASCIIWhitespace(""), [""]);
+ assertEquals(splitOnAsciiWhitespace(""), [""]);
});
it("[[Call]] returns a single token if there are no spaces", () => {
- assertEquals(splitOnASCIIWhitespace("abcd"), ["abcd"]);
+ assertEquals(splitOnAsciiWhitespace("abcd"), ["abcd"]);
});
it("[[Call]] does not split on other kinds of whitespace", () => {
assertEquals(
- splitOnASCIIWhitespace("a\u202F\u205F\xa0\v\0\bb"),
+ splitOnAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
["a\u202F\u205F\xa0\v\0\bb"],
);
});
it("[[Call]] trims leading and trailing whitespace", () => {
assertEquals(
- splitOnASCIIWhitespace(
+ splitOnAsciiWhitespace(
"\f\r\n\r\n \n\t🅰️\f \t\n🅱️\r🆎\n\f🅾️\n\f",
),
["🅰️", "🅱️", "🆎", "🅾️"],
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new splitOnASCIIWhitespace(""));
+ assertThrows(() => new splitOnAsciiWhitespace(""));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(splitOnASCIIWhitespace.length, 1);
+ assertStrictEquals(splitOnAsciiWhitespace.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(
- splitOnASCIIWhitespace.name,
- "splitOnASCIIWhitespace",
+ splitOnAsciiWhitespace.name,
+ "splitOnAsciiWhitespace",
);
});
});
});
});
-describe("stripAndCollapseASCIIWhitespace", () => {
+describe("stripAndCollapseAsciiWhitespace", () => {
it("[[Call]] collapses mixed inner whitespace", () => {
assertEquals(
- stripAndCollapseASCIIWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
+ stripAndCollapseAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
"🅰️ 🅱️ 🆎 🅾️",
);
});
it("[[Call]] trims leading and trailing whitespace", () => {
assertStrictEquals(
- stripAndCollapseASCIIWhitespace(
+ stripAndCollapseAsciiWhitespace(
"\f\r\n\r\n \n\t\f 🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️\n\f",
),
"🅰️ 🅱️ 🆎 🅾️",
it("[[Call]] returns the empty string for strings of whitespace", () => {
assertStrictEquals(
- stripAndCollapseASCIIWhitespace("\f\r\n\r\n \n\t\f \n\f"),
+ stripAndCollapseAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
"",
);
});
it("[[Call]] does not collapse other kinds of whitespace", () => {
assertEquals(
- stripAndCollapseASCIIWhitespace("a\u202F\u205F\xa0\v\0\bb"),
+ stripAndCollapseAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
"a\u202F\u205F\xa0\v\0\bb",
);
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new stripAndCollapseASCIIWhitespace(""));
+ assertThrows(() => new stripAndCollapseAsciiWhitespace(""));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
- assertStrictEquals(stripAndCollapseASCIIWhitespace.length, 1);
+ assertStrictEquals(stripAndCollapseAsciiWhitespace.length, 1);
});
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(
- stripAndCollapseASCIIWhitespace.name,
- "stripAndCollapseASCIIWhitespace",
+ stripAndCollapseAsciiWhitespace.name,
+ "stripAndCollapseAsciiWhitespace",
);
});
});
});
-describe("stripLeadingAndTrailingASCIIWhitespace", () => {
+describe("stripLeadingAndTrailingAsciiWhitespace", () => {
it("[[Call]] trims leading and trailing whitespace", () => {
assertStrictEquals(
- stripLeadingAndTrailingASCIIWhitespace(
+ stripLeadingAndTrailingAsciiWhitespace(
"\f\r\n\r\n \n\t\f 🅰️🅱️🆎🅾️\n\f",
),
"🅰️🅱️🆎🅾️",
it("[[Call]] returns the empty string for strings of whitespace", () => {
assertStrictEquals(
- stripLeadingAndTrailingASCIIWhitespace("\f\r\n\r\n \n\t\f \n\f"),
+ stripLeadingAndTrailingAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
"",
);
});
it("[[Call]] does not trim other kinds of whitespace", () => {
assertEquals(
- stripLeadingAndTrailingASCIIWhitespace(
+ stripLeadingAndTrailingAsciiWhitespace(
"\v\u202F\u205Fx\0\b\xa0",
),
"\v\u202F\u205Fx\0\b\xa0",
it("[[Call]] does not adjust inner whitespace", () => {
assertEquals(
- stripLeadingAndTrailingASCIIWhitespace("a b"),
+ stripLeadingAndTrailingAsciiWhitespace("a b"),
"a b",
);
});
it("[[Construct]] throws an error", () => {
- assertThrows(() => new stripLeadingAndTrailingASCIIWhitespace(""));
+ assertThrows(() => new stripLeadingAndTrailingAsciiWhitespace(""));
});
describe(".length", () => {
it("[[Get]] returns the correct length", () => {
assertStrictEquals(
- stripLeadingAndTrailingASCIIWhitespace.length,
+ stripLeadingAndTrailingAsciiWhitespace.length,
1,
);
});
describe(".name", () => {
it("[[Get]] returns the correct name", () => {
assertStrictEquals(
- stripLeadingAndTrailingASCIIWhitespace.name,
- "stripLeadingAndTrailingASCIIWhitespace",
+ stripLeadingAndTrailingAsciiWhitespace.name,
+ "stripLeadingAndTrailingAsciiWhitespace",
);
});
});
});
});
+describe("toScalarValueString", () => {
+ it("[[Call]] replaces invalid values", () => {
+ assertStrictEquals(
+ toScalarValueString("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
+ "Ii🎙\uFFFD\uFFFD\uFFFD\uFFFD🆗☺",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new toScalarValueString(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(toScalarValueString.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ toScalarValueString.name,
+ "toScalarValueString",
+ );
+ });
+ });
+});
+
describe("toString", () => {
it("[[Call]] converts to a string", () => {
assertStrictEquals(