+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ getFirstSubstringIndex.name,
+ "getFirstSubstringIndex",
+ );
+ });
+ });
+});
+
+describe("getLastSubstringIndex", () => {
+ it("[[Call]] returns the index of the first match", () => {
+ assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 7);
+ });
+
+ it("[[Call]] returns −1 if no match is found", () => {
+ assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆖🆗"), -1);
+ });
+
+ it("[[Call]] returns the length when provided with an empty string", () => {
+ assertStrictEquals(
+ getLastSubstringIndex("Ii🎙🆗☺🆗", ""),
+ "Ii🎙🆗☺🆗".length,
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new getLastSubstringIndex("", ""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(getLastSubstringIndex.length, 2);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ getLastSubstringIndex.name,
+ "getLastSubstringIndex",
+ );
+ });
+ });
+});
+
+describe("isArrayIndexString", () => {
+ it("[[Call]] returns false for nonstrings", () => {
+ assertStrictEquals(isArrayIndexString(1), false);
+ });
+
+ it("[[Call]] returns false for noncanonical strings", () => {
+ assertStrictEquals(isArrayIndexString(""), false);
+ assertStrictEquals(isArrayIndexString("01"), false);
+ assertStrictEquals(isArrayIndexString("9007199254740993"), false);
+ });
+
+ 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(
+ 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 isArrayIndexString("0"));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isArrayIndexString.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isArrayIndexString.name,
+ "isArrayIndexString",
+ );
+ });
+ });
+});
+
+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 isIntegerIndexString("0"));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(isIntegerIndexString.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ isIntegerIndexString.name,
+ "isIntegerIndexString",
+ );
+ });
+ });
+});
+
+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(
+ join([null, , null, undefined].values(), "☂"),
+ "☂☂☂",
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ 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(rawString.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(rawString.name, "rawString");
+ });
+ });
+});
+
+describe("scalarValues", () => {
+ it("[[Call]] returns an iterable", () => {
+ assertStrictEquals(
+ typeof scalarValues("")[Symbol.iterator],
+ "function",
+ );
+ });
+
+ it("[[Call]] returns an iterator", () => {
+ assertStrictEquals(typeof scalarValues("").next, "function");
+ });
+
+ it("[[Call]] returns a string scalar value iterator", () => {
+ assertStrictEquals(
+ scalarValues("")[Symbol.toStringTag],
+ "String Scalar Value Iterator",
+ );
+ });
+
+ it("[[Call]] iterates over the scalar values", () => {
+ assertEquals([
+ ...scalarValues("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
+ ], [
+ 0x49,
+ 0x69,
+ 0x1F399,
+ 0xFFFD,
+ 0xFFFD,
+ 0xFFFD,
+ 0xFFFD,
+ 0x1F197,
+ 0x263A,
+ ]);
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new scalarValues(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(scalarValues.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(scalarValues.name, "scalarValues");
+ });
+ });
+});
+
+describe("splitOnAsciiWhitespace", () => {
+ it("[[Call]] splits on sequences of spaces", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("🅰️ 🅱️ 🆎 🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] splits on sequences of tabs", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] splits on sequences of carriage returns", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] splits on sequences of newlines", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] splits on sequences of form feeds", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] splits on mixed whitespace", () => {
+ assertEquals(
+ 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(""), [""]);
+ });
+
+ it("[[Call]] returns a single token if there are no spaces", () => {
+ assertEquals(splitOnAsciiWhitespace("abcd"), ["abcd"]);
+ });
+
+ it("[[Call]] does not split on other kinds of whitespace", () => {
+ assertEquals(
+ splitOnAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
+ ["a\u202F\u205F\xa0\v\0\bb"],
+ );
+ });
+
+ it("[[Call]] trims leading and trailing whitespace", () => {
+ assertEquals(
+ splitOnAsciiWhitespace(
+ "\f\r\n\r\n \n\t🅰️\f \t\n🅱️\r🆎\n\f🅾️\n\f",
+ ),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Construct]] throws an error", () => {
+ assertThrows(() => new splitOnAsciiWhitespace(""));
+ });
+
+ describe(".length", () => {
+ it("[[Get]] returns the correct length", () => {
+ assertStrictEquals(splitOnAsciiWhitespace.length, 1);
+ });
+ });
+
+ describe(".name", () => {
+ it("[[Get]] returns the correct name", () => {
+ assertStrictEquals(
+ splitOnAsciiWhitespace.name,
+ "splitOnAsciiWhitespace",
+ );
+ });
+ });
+});
+
+describe("splitOnCommas", () => {
+ it("[[Call]] splits on commas", () => {
+ assertEquals(
+ splitOnCommas("🅰️,🅱️,🆎,🅾️"),
+ ["🅰️", "🅱️", "🆎", "🅾️"],
+ );
+ });
+
+ it("[[Call]] returns an array of just the empty string for the empty string", () => {
+ assertEquals(splitOnCommas(""), [""]);