]> Ladyโ€™s Gitweb - Pisces/blobdiff - string.test.js
Support unicode sets in Matchers
[Pisces] / string.test.js
index 4f257f9f96f28a8d799cb0fd447c28895e429c00..147e109c6ee692b07cf9f7dfb21d5a2118fe2293 100644 (file)
@@ -1,11 +1,14 @@
-// โ™“๐ŸŒŸ Piscฤ“s โˆท string.test.js
-// ====================================================================
-//
-// Copyright ยฉ 2022โ€“2023 Lady [@ Ladyโ€™s Computer].
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
+// SPDX-FileCopyrightText: 2022, 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
+// SPDX-License-Identifier: MPL-2.0
+/**
+ * โŒ โ™“๐Ÿงฉ Piscฤ“s โˆท string.test.js
+ *
+ * Copyright ยฉ 2022โ€“2023, 2025 Lady [@ Ladys Computer].
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
+ */
 
 import {
   assert,
@@ -20,6 +23,7 @@ import {
 import {
   asciiLowercase,
   asciiUppercase,
+  canonicalNumericIndexString,
   characters,
   codepoints,
   codeUnits,
@@ -28,12 +32,13 @@ import {
   getCodeUnit,
   getFirstSubstringIndex,
   getLastSubstringIndex,
+  isArrayIndexString,
+  isIntegerIndexString,
   join,
   Matcher,
   rawString,
   scalarValues,
-  scalarValueString,
-  splitOnASCIIWhitespace,
+  splitOnAsciiWhitespace,
   splitOnCommas,
   stringCatenate,
   stringEndsWith,
@@ -53,9 +58,10 @@ import {
   stringSplit,
   stringStartsWith,
   stringValue,
-  stripAndCollapseASCIIWhitespace,
-  stripLeadingAndTrailingASCIIWhitespace,
+  stripAndCollapseAsciiWhitespace,
+  stripLeadingAndTrailingAsciiWhitespace,
   substring,
+  toScalarValueString,
   toString,
 } from "./string.js";
 
@@ -72,7 +78,11 @@ describe("Matcher", () => {
     assert(new Matcher(/(?:)/u));
   });
 
-  it("[[Construct]] throws with a nonยทunicode regular expression first argument", () => {
+  it("[[Construct]] accepts a unicode sets regular expression first argument", () => {
+    assert(new Matcher(/(?:)/v));
+  });
+
+  it("[[Construct]] throws with a nonยทunicodeยทaware regular expression first argument", () => {
     assertThrows(() => new Matcher(/(?:)/));
   });
 
@@ -107,6 +117,12 @@ describe("Matcher", () => {
     });
   });
 
+  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);
@@ -116,7 +132,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).dotAll, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -128,7 +144,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -191,6 +207,11 @@ describe("Matcher", () => {
       );
     });
 
+    it("[[Construct]] throws an error", () => {
+      const matcher = new Matcher("");
+      assertThrows(() => new matcher.exec());
+    });
+
     describe(".length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(Matcher.prototype.exec.length, 1);
@@ -213,7 +234,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).global, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -225,7 +246,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -247,7 +268,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).hasIndices, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -259,7 +280,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -281,7 +302,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).ignoreCase, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -293,7 +314,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -315,7 +336,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).multiline, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -327,7 +348,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -346,7 +367,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/.*/su).source, ".*");
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -358,7 +379,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -380,7 +401,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).sticky, false);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -392,7 +413,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -409,6 +430,26 @@ describe("Matcher", () => {
     it("[[Call]] returns the string source", () => {
       assertStrictEquals(new Matcher(/(?:)/u).toString(), "/(?:)/u");
     });
+
+    it("[[Construct]] throws an error", () => {
+      const matcher = new Matcher("");
+      assertThrows(() => new matcher.toString());
+    });
+
+    describe(".length", () => {
+      it("[[Get]] returns the correct length", () => {
+        assertStrictEquals(Matcher.prototype.toString.length, 0);
+      });
+    });
+
+    describe(".name", () => {
+      it("[[Get]] returns the correct name", () => {
+        assertStrictEquals(
+          Matcher.prototype.toString.name,
+          "toString",
+        );
+      });
+    });
   });
 
   describe("::unicode", () => {
@@ -416,7 +457,7 @@ describe("Matcher", () => {
       assertStrictEquals(new Matcher(/(?:)/u).unicode, true);
     });
 
-    describe(".length", () => {
+    describe("[[GetOwnProperty]].get.length", () => {
       it("[[Get]] returns the correct length", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -428,7 +469,7 @@ describe("Matcher", () => {
       });
     });
 
-    describe(".name", () => {
+    describe("[[GetOwnProperty]].get.name", () => {
       it("[[Get]] returns the correct name", () => {
         assertStrictEquals(
           Object.getOwnPropertyDescriptor(
@@ -441,6 +482,36 @@ describe("Matcher", () => {
     });
   });
 
+  describe("::unicodeSets", () => {
+    it("[[Get]] returns true when the unicode sets flag is present", () => {
+      assertStrictEquals(new Matcher(/(?:)/v).unicodeSets, true);
+    });
+
+    describe("[[GetOwnProperty]].get.length", () => {
+      it("[[Get]] returns the correct length", () => {
+        assertStrictEquals(
+          Object.getOwnPropertyDescriptor(
+            Matcher.prototype,
+            "unicodeSets",
+          ).get.length,
+          0,
+        );
+      });
+    });
+
+    describe("[[GetOwnProperty]].get.name", () => {
+      it("[[Get]] returns the correct name", () => {
+        assertStrictEquals(
+          Object.getOwnPropertyDescriptor(
+            Matcher.prototype,
+            "unicodeSets",
+          ).get.name,
+          "get unicodeSets",
+        );
+      });
+    });
+  });
+
   describe("~", () => {
     it("[[Call]] returns true for a complete match", () => {
       assertStrictEquals(new Matcher("")(""), true);
@@ -482,6 +553,11 @@ describe("Matcher", () => {
         false,
       );
     });
+
+    it("[[Construct]] throws an error", () => {
+      const matcher = new Matcher("");
+      assertThrows(() => new matcher(""));
+    });
   });
 
   describe("~lastIndex", () => {
@@ -559,6 +635,59 @@ describe("asciiUppercase", () => {
   });
 });
 
+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(
@@ -879,82 +1008,182 @@ describe("getLastSubstringIndex", () => {
   });
 });
 
-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");
     });
   });
 });
@@ -1011,67 +1240,67 @@ describe("scalarValues", () => {
   });
 });
 
-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",
       ),
       ["๐Ÿ…ฐ๏ธ", "๐Ÿ…ฑ๏ธ", "๐Ÿ†Ž", "๐Ÿ…พ๏ธ"],
@@ -1079,20 +1308,20 @@ describe("splitOnASCIIWhitespace", () => {
   });
 
   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",
       );
     });
   });
@@ -1546,8 +1775,8 @@ describe("stringReplace", () => {
         "very success full",
         /([sc]+)[ue]?/g,
         (...$s) =>
-          `${$s[0].length}`.repeat($s[1].length) +
-          $s[0].substring($s[1].length),
+          `${$s[0].length}`.repeat($s[1].length)
+          $s[0].substring($s[1].length),
       ),
       "very 2u33e22 full",
     );
@@ -1581,8 +1810,8 @@ describe("stringReplaceAll", () => {
         "very success full",
         /([sc]+)[ue]?/g,
         (...$s) =>
-          `${$s[0].length}`.repeat($s[1].length) +
-          $s[0].substring($s[1].length),
+          `${$s[0].length}`.repeat($s[1].length)
+          $s[0].substring($s[1].length),
       ),
       "very 2u33e22 full",
     );
@@ -1778,17 +2007,17 @@ describe("stringStartsWith", () => {
   });
 });
 
-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",
       ),
       "๐Ÿ…ฐ๏ธ ๐Ÿ…ฑ๏ธ ๐Ÿ†Ž ๐Ÿ…พ๏ธ",
@@ -1797,42 +2026,42 @@ describe("stripAndCollapseASCIIWhitespace", () => {
 
   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",
       ),
       "๐Ÿ…ฐ๏ธ๐Ÿ…ฑ๏ธ๐Ÿ†Ž๐Ÿ…พ๏ธ",
@@ -1841,14 +2070,14 @@ describe("stripLeadingAndTrailingASCIIWhitespace", () => {
 
   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",
@@ -1857,19 +2086,19 @@ describe("stripLeadingAndTrailingASCIIWhitespace", () => {
 
   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,
       );
     });
@@ -1878,8 +2107,8 @@ describe("stripLeadingAndTrailingASCIIWhitespace", () => {
   describe(".name", () => {
     it("[[Get]] returns the correct name", () => {
       assertStrictEquals(
-        stripLeadingAndTrailingASCIIWhitespace.name,
-        "stripLeadingAndTrailingASCIIWhitespace",
+        stripLeadingAndTrailingAsciiWhitespace.name,
+        "stripLeadingAndTrailingAsciiWhitespace",
       );
     });
   });
@@ -1914,6 +2143,34 @@ describe("substring", () => {
   });
 });
 
+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(
This page took 0.341018 seconds and 4 git commands to generate.