1 // SPDX-FileCopyrightText: 2022, 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
2 // SPDX-License-Identifier: MPL-2.0
4 * ⁌ ♓🧩 Piscēs ∷ string.test.js
6 * Copyright © 2022–2023, 2025 Lady [@ Ladys Computer].
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
22 } from "./dev-deps.js";
26 canonicalNumericIndexString
,
33 getFirstSubstringIndex
,
34 getLastSubstringIndex
,
41 splitOnAsciiWhitespace
,
61 stripAndCollapseAsciiWhitespace
,
62 stripLeadingAndTrailingAsciiWhitespace
,
68 describe("Matcher", () => {
69 it("[[Call]] throws an error", () => {
70 assertThrows(() => Matcher(""));
73 it("[[Construct]] accepts a string first argument", () => {
74 assert(new Matcher(""));
77 it("[[Construct]] accepts a unicode regular expression first argument", () => {
78 assert(new Matcher(/(?:)/u));
81 it("[[Construct]] accepts a unicode sets regular expression first argument", () => {
82 assert(new Matcher(/(?:)/v
));
85 it("[[Construct]] throws with a non·unicode·aware regular expression first argument", () => {
86 assertThrows(() => new Matcher(/(?:)/));
89 it("[[Construct]] creates a callable object", () => {
90 assertStrictEquals(typeof new Matcher(""), "function");
93 it("[[Construct]] creates a new Matcher", () => {
95 Object
.getPrototypeOf(new Matcher("")),
100 it("[[Construct]] creates an object which inherits from RegExp", () => {
101 assert(new Matcher("") instanceof RegExp
);
104 it("[[Construct]] throws when provided with a noncallable, non·null third argument", () => {
105 assertThrows(() => new Matcher("", undefined, "failure"));
108 describe(".length", () => {
109 it("[[Get]] returns the correct length", () => {
110 assertStrictEquals(Matcher
.length
, 1);
114 describe(".name", () => {
115 it("[[Get]] returns the correct name", () => {
116 assertStrictEquals(Matcher
.name
, "Matcher");
120 describe("::constructor", () => {
121 it("[[Get]] returns the same constructor", () => {
122 assertStrictEquals(new Matcher(/(?:)/su).constructor, Matcher
);
126 describe("::dotAll", () => {
127 it("[[Get]] returns true when the dotAll flag is present", () => {
128 assertStrictEquals(new Matcher(/(?:)/su).dotAll
, true);
131 it("[[Get]] returns false when the dotAll flag is not present", () => {
132 assertStrictEquals(new Matcher(/(?:)/u).dotAll
, false);
135 describe("[[GetOwnProperty]].get.length", () => {
136 it("[[Get]] returns the correct length", () => {
138 Object
.getOwnPropertyDescriptor(
147 describe("[[GetOwnProperty]].get.name", () => {
148 it("[[Get]] returns the correct name", () => {
150 Object
.getOwnPropertyDescriptor(
160 describe("::exec", () => {
161 it("[[Call]] returns the match object given a complete match", () => {
163 [...new Matcher(/.(?<wow>(?:.(?=.))*)(.)?/u).exec("success")],
164 ["success", "ucces", "s"],
168 /.(?<wow>(?:.(?=.))*)(.)?/u,
170 ($) => $ === "success",
172 ["success", "ucces", "s"],
176 it("[[Call]] calls the constraint if the match succeeds", () => {
177 const constraint
= spy((_
) => true);
178 const matcher
= new Matcher("(.).*", undefined, constraint
);
179 const result
= matcher
.exec({
184 assertEquals([...result
], ["etaoin", "e"]);
185 assertSpyCalls(constraint
, 1);
186 assertStrictEquals(constraint
.calls
[0].args
[0], "etaoin");
187 assertEquals([...constraint
.calls
[0].args
[1]], ["etaoin", "e"]);
188 assertStrictEquals(constraint
.calls
[0].args
[2], matcher
);
189 assertStrictEquals(constraint
.calls
[0].self
, undefined);
192 it("[[Call]] does not call the constraint if the match fails", () => {
193 const constraint
= spy((_
) => true);
194 const matcher
= new Matcher("", undefined, constraint
);
195 matcher
.exec("failure");
196 assertSpyCalls(constraint
, 0);
199 it("[[Call]] returns null given a partial match", () => {
200 assertStrictEquals(new Matcher("").exec("failure"), null);
203 it("[[Call]] returns null if the constraint fails", () => {
205 new Matcher(".*", undefined, () => false).exec(""),
210 it("[[Construct]] throws an error", () => {
211 const matcher
= new Matcher("");
212 assertThrows(() => new matcher
.exec());
215 describe(".length", () => {
216 it("[[Get]] returns the correct length", () => {
217 assertStrictEquals(Matcher
.prototype.exec
.length
, 1);
221 describe(".name", () => {
222 it("[[Get]] returns the correct name", () => {
223 assertStrictEquals(Matcher
.prototype.exec
.name
, "exec");
228 describe("::global", () => {
229 it("[[Get]] returns true when the global flag is present", () => {
230 assertStrictEquals(new Matcher(/(?:)/gu).global
, true);
233 it("[[Get]] returns false when the global flag is not present", () => {
234 assertStrictEquals(new Matcher(/(?:)/u).global
, false);
237 describe("[[GetOwnProperty]].get.length", () => {
238 it("[[Get]] returns the correct length", () => {
240 Object
.getOwnPropertyDescriptor(
249 describe("[[GetOwnProperty]].get.name", () => {
250 it("[[Get]] returns the correct name", () => {
252 Object
.getOwnPropertyDescriptor(
262 describe("::hasIndices", () => {
263 it("[[Get]] returns true when the hasIndices flag is present", () => {
264 assertStrictEquals(new Matcher(/(?:)/du).hasIndices
, true);
267 it("[[Get]] returns false when the hasIndices flag is not present", () => {
268 assertStrictEquals(new Matcher(/(?:)/u).hasIndices
, false);
271 describe("[[GetOwnProperty]].get.length", () => {
272 it("[[Get]] returns the correct length", () => {
274 Object
.getOwnPropertyDescriptor(
283 describe("[[GetOwnProperty]].get.name", () => {
284 it("[[Get]] returns the correct name", () => {
286 Object
.getOwnPropertyDescriptor(
296 describe("::ignoreCase", () => {
297 it("[[Get]] returns true when the ignoreCase flag is present", () => {
298 assertStrictEquals(new Matcher(/(?:)/iu).ignoreCase
, true);
301 it("[[Get]] returns false when the ignoreCase flag is not present", () => {
302 assertStrictEquals(new Matcher(/(?:)/u).ignoreCase
, false);
305 describe("[[GetOwnProperty]].get.length", () => {
306 it("[[Get]] returns the correct length", () => {
308 Object
.getOwnPropertyDescriptor(
317 describe("[[GetOwnProperty]].get.name", () => {
318 it("[[Get]] returns the correct name", () => {
320 Object
.getOwnPropertyDescriptor(
330 describe("::multiline", () => {
331 it("[[Get]] returns true when the multiline flag is present", () => {
332 assertStrictEquals(new Matcher(/(?:)/mu).multiline
, true);
335 it("[[Get]] returns false when the multiline flag is not present", () => {
336 assertStrictEquals(new Matcher(/(?:)/u).multiline
, false);
339 describe("[[GetOwnProperty]].get.length", () => {
340 it("[[Get]] returns the correct length", () => {
342 Object
.getOwnPropertyDescriptor(
351 describe("[[GetOwnProperty]].get.name", () => {
352 it("[[Get]] returns the correct name", () => {
354 Object
.getOwnPropertyDescriptor(
364 describe("::source", () => {
365 it("[[Get]] returns the RegExp source", () => {
366 assertStrictEquals(new Matcher("").source
, "(?:)");
367 assertStrictEquals(new Matcher(/.*/su).source
, ".*");
370 describe("[[GetOwnProperty]].get.length", () => {
371 it("[[Get]] returns the correct length", () => {
373 Object
.getOwnPropertyDescriptor(
382 describe("[[GetOwnProperty]].get.name", () => {
383 it("[[Get]] returns the correct name", () => {
385 Object
.getOwnPropertyDescriptor(
395 describe("::sticky", () => {
396 it("[[Get]] returns true when the sticky flag is present", () => {
397 assertStrictEquals(new Matcher(/(?:)/uy).sticky
, true);
400 it("[[Get]] returns false when the sticky flag is not present", () => {
401 assertStrictEquals(new Matcher(/(?:)/u).sticky
, false);
404 describe("[[GetOwnProperty]].get.length", () => {
405 it("[[Get]] returns the correct length", () => {
407 Object
.getOwnPropertyDescriptor(
416 describe("[[GetOwnProperty]].get.name", () => {
417 it("[[Get]] returns the correct name", () => {
419 Object
.getOwnPropertyDescriptor(
429 describe("::toString", () => {
430 it("[[Call]] returns the string source", () => {
431 assertStrictEquals(new Matcher(/(?:)/u).toString(), "/(?:)/u");
434 it("[[Construct]] throws an error", () => {
435 const matcher
= new Matcher("");
436 assertThrows(() => new matcher
.toString());
439 describe(".length", () => {
440 it("[[Get]] returns the correct length", () => {
441 assertStrictEquals(Matcher
.prototype.toString
.length
, 0);
445 describe(".name", () => {
446 it("[[Get]] returns the correct name", () => {
448 Matcher
.prototype.toString
.name
,
455 describe("::unicode", () => {
456 it("[[Get]] returns true when the unicode flag is present", () => {
457 assertStrictEquals(new Matcher(/(?:)/u).unicode
, true);
460 describe("[[GetOwnProperty]].get.length", () => {
461 it("[[Get]] returns the correct length", () => {
463 Object
.getOwnPropertyDescriptor(
472 describe("[[GetOwnProperty]].get.name", () => {
473 it("[[Get]] returns the correct name", () => {
475 Object
.getOwnPropertyDescriptor(
485 describe("::unicodeSets", () => {
486 it("[[Get]] returns true when the unicode sets flag is present", () => {
487 assertStrictEquals(new Matcher(/(?:)/v
).unicodeSets
, true);
490 describe("[[GetOwnProperty]].get.length", () => {
491 it("[[Get]] returns the correct length", () => {
493 Object
.getOwnPropertyDescriptor(
502 describe("[[GetOwnProperty]].get.name", () => {
503 it("[[Get]] returns the correct name", () => {
505 Object
.getOwnPropertyDescriptor(
515 describe("~", () => {
516 it("[[Call]] returns true for a complete match", () => {
517 assertStrictEquals(new Matcher("")(""), true);
518 assertStrictEquals(new Matcher(/.*/su)("success\nyay"), true);
520 new Matcher(/.*/su, undefined, ($) => $ === "success")(
527 it("[[Call]] calls the constraint if the match succeeds", () => {
528 const constraint
= spy((_
) => true);
529 const matcher
= new Matcher("(.).*", undefined, constraint
);
531 assertSpyCalls(constraint
, 1);
532 assertStrictEquals(constraint
.calls
[0].args
[0], "etaoin");
533 assertEquals([...constraint
.calls
[0].args
[1]], ["etaoin", "e"]);
534 assertStrictEquals(constraint
.calls
[0].args
[2], matcher
);
535 assertStrictEquals(constraint
.calls
[0].self
, undefined);
538 it("[[Call]] does not call the constraint if the match fails", () => {
539 const constraint
= spy((_
) => true);
540 const matcher
= new Matcher("", undefined, constraint
);
542 assertSpyCalls(constraint
, 0);
545 it("[[Call]] returns false for a partial match", () => {
546 assertStrictEquals(new Matcher("")("failure"), false);
547 assertStrictEquals(new Matcher(/.*/u)("failure\nno"), false);
550 it("[[Call]] returns false if the constraint fails", () => {
552 new Matcher(".*", undefined, () => false)(""),
557 it("[[Construct]] throws an error", () => {
558 const matcher
= new Matcher("");
559 assertThrows(() => new matcher(""));
563 describe("~lastIndex", () => {
564 it("[[Get]] returns zero", () => {
565 assertStrictEquals(new Matcher("").lastIndex
, 0);
568 it("[[Set]] fails", () => {
569 assertThrows(() => (new Matcher("").lastIndex
= 1));
573 describe("~length", () => {
574 it("[[Get]] returns one", () => {
575 assertStrictEquals(new Matcher("").length
, 1);
579 describe("~name", () => {
580 it("[[Get]] wraps the stringified regular expression if no name was provided", () => {
581 assertStrictEquals(new Matcher("").name
, "Matcher(/(?:)/u)");
583 new Matcher(/.*/gsu).name
,
588 it("[[Get]] uses the provided name if one was provided", () => {
589 assertStrictEquals(new Matcher("", "success").name
, "success");
594 describe("asciiLowercase", () => {
595 it("[[Call]] lowercases (just) A·S·C·I·I letters", () => {
596 assertStrictEquals(asciiLowercase("aBſÆss FtɁɂß"), "abſÆss ftɁɂß");
599 it("[[Construct]] throws an error", () => {
600 assertThrows(() => new asciiLowercase(""));
603 describe(".length", () => {
604 it("[[Get]] returns the correct length", () => {
605 assertStrictEquals(asciiLowercase
.length
, 1);
609 describe(".name", () => {
610 it("[[Get]] returns the correct name", () => {
611 assertStrictEquals(asciiLowercase
.name
, "asciiLowercase");
616 describe("asciiUppercase", () => {
617 it("[[Call]] uppercases (just) A·S·C·I·I letters", () => {
618 assertStrictEquals(asciiUppercase("aBſÆss FtɁɂß"), "ABſÆSS FTɁɂß");
621 it("[[Construct]] throws an error", () => {
622 assertThrows(() => new asciiUppercase(""));
625 describe(".length", () => {
626 it("[[Get]] returns the correct length", () => {
627 assertStrictEquals(asciiUppercase
.length
, 1);
631 describe(".name", () => {
632 it("[[Get]] returns the correct name", () => {
633 assertStrictEquals(asciiUppercase
.name
, "asciiUppercase");
638 describe("canonicalNumericIndexString", () => {
639 it("[[Call]] returns undefined for nonstrings", () => {
640 assertStrictEquals(canonicalNumericIndexString(1), void {});
643 it("[[Call]] returns undefined for noncanonical strings", () => {
644 assertStrictEquals(canonicalNumericIndexString(""), void {});
645 assertStrictEquals(canonicalNumericIndexString("01"), void {});
647 canonicalNumericIndexString("9007199254740993"),
652 it('[[Call]] returns -0 for "-0"', () => {
653 assertStrictEquals(canonicalNumericIndexString("-0"), -0);
656 it("[[Call]] returns the corresponding number for canonical strings", () => {
657 assertStrictEquals(canonicalNumericIndexString("0"), 0);
658 assertStrictEquals(canonicalNumericIndexString("-0.25"), -0.25);
660 canonicalNumericIndexString("9007199254740992"),
663 assertStrictEquals(canonicalNumericIndexString("NaN"), 0 / 0);
664 assertStrictEquals(canonicalNumericIndexString("Infinity"), 1 / 0);
666 canonicalNumericIndexString("-Infinity"),
671 it("[[Construct]] throws an error", () => {
672 assertThrows(() => new canonicalNumericIndexString(""));
675 describe(".length", () => {
676 it("[[Get]] returns the correct length", () => {
677 assertStrictEquals(canonicalNumericIndexString
.length
, 1);
681 describe(".name", () => {
682 it("[[Get]] returns the correct name", () => {
684 canonicalNumericIndexString
.name
,
685 "canonicalNumericIndexString",
691 describe("characters", () => {
692 it("[[Call]] returns an iterable", () => {
694 typeof characters("")[Symbol
.iterator
],
699 it("[[Call]] returns an iterator", () => {
700 assertStrictEquals(typeof characters("").next
, "function");
703 it("[[Call]] returns a string character iterator", () => {
705 characters("")[Symbol
.toStringTag
],
706 "String Character Iterator",
710 it("[[Call]] iterates over the characters", () => {
712 ...characters("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
726 it("[[Construct]] throws an error", () => {
727 assertThrows(() => new characters(""));
730 describe(".length", () => {
731 it("[[Get]] returns the correct length", () => {
732 assertStrictEquals(characters
.length
, 1);
736 describe(".name", () => {
737 it("[[Get]] returns the correct name", () => {
738 assertStrictEquals(characters
.name
, "characters");
743 describe("codeUnits", () => {
744 it("[[Call]] returns an iterable", () => {
746 typeof codeUnits("")[Symbol
.iterator
],
751 it("[[Call]] returns an iterator", () => {
752 assertStrictEquals(typeof codeUnits("").next
, "function");
755 it("[[Call]] returns a string code unit iterator", () => {
757 codeUnits("")[Symbol
.toStringTag
],
758 "String Code Unit Iterator",
762 it("[[Call]] iterates over the code units", () => {
764 ...codeUnits("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
780 it("[[Construct]] throws an error", () => {
781 assertThrows(() => new codeUnits(""));
784 describe(".length", () => {
785 it("[[Get]] returns the correct length", () => {
786 assertStrictEquals(codeUnits
.length
, 1);
790 describe(".name", () => {
791 it("[[Get]] returns the correct name", () => {
792 assertStrictEquals(codeUnits
.name
, "codeUnits");
797 describe("codepoints", () => {
798 it("[[Call]] returns an iterable", () => {
800 typeof codepoints("")[Symbol
.iterator
],
805 it("[[Call]] returns an iterator", () => {
806 assertStrictEquals(typeof codepoints("").next
, "function");
809 it("[[Call]] returns a string codepoint iterator", () => {
811 codepoints("")[Symbol
.toStringTag
],
812 "String Codepoint Iterator",
816 it("[[Call]] iterates over the codepoints", () => {
818 ...codepoints("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
832 it("[[Construct]] throws an error", () => {
833 assertThrows(() => new codepoints(""));
836 describe(".length", () => {
837 it("[[Get]] returns the correct length", () => {
838 assertStrictEquals(codepoints
.length
, 1);
842 describe(".name", () => {
843 it("[[Get]] returns the correct name", () => {
844 assertStrictEquals(codepoints
.name
, "codepoints");
849 describe("getCharacter", () => {
850 it("[[Call]] returns the character at the provided position", () => {
851 assertStrictEquals(getCharacter("Ii🎙🆗☺", 4), "🆗");
854 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
855 assertStrictEquals(getCharacter("Ii🎙🆗☺", 5), "\uDD97");
858 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
859 assertStrictEquals(getCharacter("Ii🎙🆗☺", -1), undefined);
860 assertStrictEquals(getCharacter("Ii🎙🆗☺", 7), undefined);
863 it("[[Construct]] throws an error", () => {
864 assertThrows(() => new getCharacter("a", 0));
867 describe(".length", () => {
868 it("[[Get]] returns the correct length", () => {
869 assertStrictEquals(getCharacter
.length
, 2);
873 describe(".name", () => {
874 it("[[Get]] returns the correct name", () => {
875 assertStrictEquals(getCharacter
.name
, "getCharacter");
880 describe("getCodeUnit", () => {
881 it("[[Call]] returns the code unit at the provided position", () => {
882 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 4), 0xD83C);
885 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
886 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 5), 0xDD97);
889 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
890 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", -1), undefined);
891 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 7), undefined);
894 it("[[Construct]] throws an error", () => {
895 assertThrows(() => new getCodeUnit("a", 0));
898 describe(".length", () => {
899 it("[[Get]] returns the correct length", () => {
900 assertStrictEquals(getCodeUnit
.length
, 2);
904 describe(".name", () => {
905 it("[[Get]] returns the correct name", () => {
906 assertStrictEquals(getCodeUnit
.name
, "getCodeUnit");
911 describe("getCodepoint", () => {
912 it("[[Call]] returns the character at the provided position", () => {
913 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 4), 0x1F197);
916 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
917 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 5), 0xDD97);
920 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
921 assertStrictEquals(getCodepoint("Ii🎙🆗☺", -1), undefined);
922 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 7), undefined);
925 it("[[Construct]] throws an error", () => {
926 assertThrows(() => new getCodepoint("a", 0));
929 describe(".length", () => {
930 it("[[Get]] returns the correct length", () => {
931 assertStrictEquals(getCodepoint
.length
, 2);
935 describe(".name", () => {
936 it("[[Get]] returns the correct name", () => {
937 assertStrictEquals(getCodepoint
.name
, "getCodepoint");
942 describe("getFirstSubstringIndex", () => {
943 it("[[Call]] returns the index of the first match", () => {
944 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 4);
947 it("[[Call]] returns −1 if no match is found", () => {
948 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗🆖"), -1);
951 it("[[Call]] returns 0 when provided with an empty string", () => {
952 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", ""), 0);
955 it("[[Construct]] throws an error", () => {
956 assertThrows(() => new getFirstSubstringIndex("", ""));
959 describe(".length", () => {
960 it("[[Get]] returns the correct length", () => {
961 assertStrictEquals(getFirstSubstringIndex
.length
, 2);
965 describe(".name", () => {
966 it("[[Get]] returns the correct name", () => {
968 getFirstSubstringIndex
.name
,
969 "getFirstSubstringIndex",
975 describe("getLastSubstringIndex", () => {
976 it("[[Call]] returns the index of the first match", () => {
977 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 7);
980 it("[[Call]] returns −1 if no match is found", () => {
981 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆖🆗"), -1);
984 it("[[Call]] returns the length when provided with an empty string", () => {
986 getLastSubstringIndex("Ii🎙🆗☺🆗", ""),
991 it("[[Construct]] throws an error", () => {
992 assertThrows(() => new getLastSubstringIndex("", ""));
995 describe(".length", () => {
996 it("[[Get]] returns the correct length", () => {
997 assertStrictEquals(getLastSubstringIndex
.length
, 2);
1001 describe(".name", () => {
1002 it("[[Get]] returns the correct name", () => {
1004 getLastSubstringIndex
.name
,
1005 "getLastSubstringIndex",
1011 describe("isArrayIndexString", () => {
1012 it("[[Call]] returns false for nonstrings", () => {
1013 assertStrictEquals(isArrayIndexString(1), false);
1016 it("[[Call]] returns false for noncanonical strings", () => {
1017 assertStrictEquals(isArrayIndexString(""), false);
1018 assertStrictEquals(isArrayIndexString("01"), false);
1019 assertStrictEquals(isArrayIndexString("9007199254740993"), false);
1022 it("[[Call]] returns false for nonfinite numbers", () => {
1023 assertStrictEquals(isArrayIndexString("NaN"), false);
1024 assertStrictEquals(isArrayIndexString("Infinity"), false);
1025 assertStrictEquals(isArrayIndexString("-Infinity"), false);
1028 it("[[Call]] returns false for negative numbers", () => {
1029 assertStrictEquals(isArrayIndexString("-0"), false);
1030 assertStrictEquals(isArrayIndexString("-1"), false);
1033 it("[[Call]] returns false for nonintegers", () => {
1034 assertStrictEquals(isArrayIndexString("0.25"), false);
1035 assertStrictEquals(isArrayIndexString("1.1"), false);
1038 it("[[Call]] returns false for numbers greater than or equal to -1 >>> 0", () => {
1039 assertStrictEquals(isArrayIndexString(String(-1 >>> 0)), false);
1041 isArrayIndexString(String((-1 >>> 0) + 1)),
1046 it("[[Call]] returns true for array lengths less than -1 >>> 0", () => {
1047 assertStrictEquals(isArrayIndexString("0"), true);
1049 isArrayIndexString(String((-1 >>> 0) - 1)),
1054 it("[[Construct]] throws an error", () => {
1055 assertThrows(() => new isArrayIndexString("0"));
1058 describe(".length", () => {
1059 it("[[Get]] returns the correct length", () => {
1060 assertStrictEquals(isArrayIndexString
.length
, 1);
1064 describe(".name", () => {
1065 it("[[Get]] returns the correct name", () => {
1067 isArrayIndexString
.name
,
1068 "isArrayIndexString",
1074 describe("isIntegerIndexString", () => {
1075 it("[[Call]] returns false for nonstrings", () => {
1076 assertStrictEquals(isIntegerIndexString(1), false);
1079 it("[[Call]] returns false for noncanonical strings", () => {
1080 assertStrictEquals(isIntegerIndexString(""), false);
1081 assertStrictEquals(isIntegerIndexString("01"), false);
1083 isIntegerIndexString("9007199254740993"),
1088 it("[[Call]] returns false for nonfinite numbers", () => {
1089 assertStrictEquals(isIntegerIndexString("NaN"), false);
1090 assertStrictEquals(isIntegerIndexString("Infinity"), false);
1091 assertStrictEquals(isIntegerIndexString("-Infinity"), false);
1094 it("[[Call]] returns false for negative numbers", () => {
1095 assertStrictEquals(isIntegerIndexString("-0"), false);
1096 assertStrictEquals(isIntegerIndexString("-1"), false);
1099 it("[[Call]] returns false for nonintegers", () => {
1100 assertStrictEquals(isIntegerIndexString("0.25"), false);
1101 assertStrictEquals(isIntegerIndexString("1.1"), false);
1104 it("[[Call]] returns false for numbers greater than or equal to 2 ** 53", () => {
1106 isIntegerIndexString("9007199254740992"),
1111 it("[[Call]] returns true for safe canonical integer strings", () => {
1112 assertStrictEquals(isIntegerIndexString("0"), true);
1113 assertStrictEquals(isIntegerIndexString("9007199254740991"), true);
1116 it("[[Construct]] throws an error", () => {
1117 assertThrows(() => new isIntegerIndexString("0"));
1120 describe(".length", () => {
1121 it("[[Get]] returns the correct length", () => {
1122 assertStrictEquals(isIntegerIndexString
.length
, 1);
1126 describe(".name", () => {
1127 it("[[Get]] returns the correct name", () => {
1129 isIntegerIndexString
.name
,
1130 "isIntegerIndexString",
1136 describe("join", () => {
1137 it("[[Call]] joins the provided iterator with the provided separartor", () => {
1138 assertStrictEquals(join([1, 2, 3, 4].values(), "☂"), "1☂2☂3☂4");
1141 it('[[Call]] uses "," if no separator is provided', () => {
1142 assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
1145 it("[[Call]] uses the empty sting for nullish values", () => {
1147 join([null, , null, undefined].values(), "☂"),
1152 it("[[Construct]] throws an error", () => {
1153 assertThrows(() => new join([]));
1156 describe(".length", () => {
1157 it("[[Get]] returns the correct length", () => {
1158 assertStrictEquals(join
.length
, 2);
1162 describe(".name", () => {
1163 it("[[Get]] returns the correct name", () => {
1164 assertStrictEquals(join
.name
, "join");
1169 describe("rawString", () => {
1170 it("[[Call]] acts like String.raw", () => {
1171 assertStrictEquals(rawString
`\nraw${" string"}`, "\\nraw string");
1174 it("[[Construct]] throws an error", () => {
1175 assertThrows(() => new rawString(["string"]));
1178 describe(".length", () => {
1179 it("[[Get]] returns the correct length", () => {
1180 assertStrictEquals(rawString
.length
, 1);
1184 describe(".name", () => {
1185 it("[[Get]] returns the correct name", () => {
1186 assertStrictEquals(rawString
.name
, "rawString");
1191 describe("scalarValues", () => {
1192 it("[[Call]] returns an iterable", () => {
1194 typeof scalarValues("")[Symbol
.iterator
],
1199 it("[[Call]] returns an iterator", () => {
1200 assertStrictEquals(typeof scalarValues("").next
, "function");
1203 it("[[Call]] returns a string scalar value iterator", () => {
1205 scalarValues("")[Symbol
.toStringTag
],
1206 "String Scalar Value Iterator",
1210 it("[[Call]] iterates over the scalar values", () => {
1212 ...scalarValues("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
1226 it("[[Construct]] throws an error", () => {
1227 assertThrows(() => new scalarValues(""));
1230 describe(".length", () => {
1231 it("[[Get]] returns the correct length", () => {
1232 assertStrictEquals(scalarValues
.length
, 1);
1236 describe(".name", () => {
1237 it("[[Get]] returns the correct name", () => {
1238 assertStrictEquals(scalarValues
.name
, "scalarValues");
1243 describe("splitOnAsciiWhitespace", () => {
1244 it("[[Call]] splits on sequences of spaces", () => {
1246 splitOnAsciiWhitespace("🅰️ 🅱️ 🆎 🅾️"),
1247 ["🅰️", "🅱️", "🆎", "🅾️"],
1251 it("[[Call]] splits on sequences of tabs", () => {
1253 splitOnAsciiWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
1254 ["🅰️", "🅱️", "🆎", "🅾️"],
1258 it("[[Call]] splits on sequences of carriage returns", () => {
1260 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1261 ["🅰️", "🅱️", "🆎", "🅾️"],
1265 it("[[Call]] splits on sequences of newlines", () => {
1267 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1268 ["🅰️", "🅱️", "🆎", "🅾️"],
1272 it("[[Call]] splits on sequences of form feeds", () => {
1274 splitOnAsciiWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
1275 ["🅰️", "🅱️", "🆎", "🅾️"],
1279 it("[[Call]] splits on mixed whitespace", () => {
1281 splitOnAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
1282 ["🅰️", "🅱️", "🆎", "🅾️"],
1286 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1287 assertEquals(splitOnAsciiWhitespace(""), [""]);
1290 it("[[Call]] returns a single token if there are no spaces", () => {
1291 assertEquals(splitOnAsciiWhitespace("abcd"), ["abcd"]);
1294 it("[[Call]] does not split on other kinds of whitespace", () => {
1296 splitOnAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
1297 ["a\u202F\u205F\xa0\v\0\bb"],
1301 it("[[Call]] trims leading and trailing whitespace", () => {
1303 splitOnAsciiWhitespace(
1304 "\f\r\n\r\n \n\t🅰️\f \t\n🅱️\r🆎\n\f🅾️\n\f",
1306 ["🅰️", "🅱️", "🆎", "🅾️"],
1310 it("[[Construct]] throws an error", () => {
1311 assertThrows(() => new splitOnAsciiWhitespace(""));
1314 describe(".length", () => {
1315 it("[[Get]] returns the correct length", () => {
1316 assertStrictEquals(splitOnAsciiWhitespace
.length
, 1);
1320 describe(".name", () => {
1321 it("[[Get]] returns the correct name", () => {
1323 splitOnAsciiWhitespace
.name
,
1324 "splitOnAsciiWhitespace",
1330 describe("splitOnCommas", () => {
1331 it("[[Call]] splits on commas", () => {
1333 splitOnCommas("🅰️,🅱️,🆎,🅾️"),
1334 ["🅰️", "🅱️", "🆎", "🅾️"],
1338 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1339 assertEquals(splitOnCommas(""), [""]);
1342 it("[[Call]] returns a single token if there are no commas", () => {
1343 assertEquals(splitOnCommas("abcd"), ["abcd"]);
1346 it("[[Call]] splits into empty strings if there are only commas", () => {
1347 assertEquals(splitOnCommas(",,,"), ["", "", "", ""]);
1350 it("[[Call]] trims leading and trailing whitespace", () => {
1352 splitOnCommas("\f\r\n\r\n \n\t🅰️,🅱️,🆎,🅾️\n\f"),
1353 ["🅰️", "🅱️", "🆎", "🅾️"],
1356 splitOnCommas("\f\r\n\r\n \n\t,,,\n\f"),
1361 it("[[Call]] removes whitespace from the split tokens", () => {
1364 "\f\r\n\r\n \n\t🅰️\f , \t\n🅱️,\r\n\r🆎\n\f,🅾️\n\f",
1366 ["🅰️", "🅱️", "🆎", "🅾️"],
1369 splitOnCommas("\f\r\n\r\n \n\t\f , \t\n,\r\n\r\n\f,\n\f"),
1374 it("[[Construct]] throws an error", () => {
1375 assertThrows(() => new splitOnCommas(""));
1378 describe(".length", () => {
1379 it("[[Get]] returns the correct length", () => {
1380 assertStrictEquals(splitOnCommas
.length
, 1);
1384 describe(".name", () => {
1385 it("[[Get]] returns the correct name", () => {
1386 assertStrictEquals(splitOnCommas
.name
, "splitOnCommas");
1391 describe("stringCatenate", () => {
1392 it("[[Call]] catenates the values", () => {
1393 assertStrictEquals(stringCatenate("the", " values"), "the values");
1396 it("[[Call]] returns an empty string when called with no values", () => {
1397 assertStrictEquals(stringCatenate(), "");
1400 it('[[Call]] uses "undefined" when explicitly provided undefined', () => {
1402 stringCatenate(undefined, undefined),
1403 "undefinedundefined",
1407 it('[[Call]] uses "null" when provided null', () => {
1408 assertStrictEquals(stringCatenate(null, null), "nullnull");
1411 it("[[Construct]] throws an error", () => {
1412 assertThrows(() => new stringCatenate());
1415 describe(".length", () => {
1416 it("[[Get]] returns the correct length", () => {
1417 assertStrictEquals(stringCatenate
.length
, 2);
1421 describe(".name", () => {
1422 it("[[Get]] returns the correct name", () => {
1423 assertStrictEquals(stringCatenate
.name
, "stringCatenate");
1428 describe("stringEndsWith", () => {
1429 it("[[Call]] returns whether the string ends with the thing", () => {
1431 stringEndsWith("very success", " success"),
1434 assertStrictEquals(stringEndsWith("very fail", " success"), false);
1437 it("[[Call]] accepts an offset", () => {
1439 stringEndsWith("very successful", " success", 12),
1444 it("[[Call]] returns true for an empty string test", () => {
1445 assertStrictEquals(stringEndsWith("", ""), true);
1448 it("[[Construct]] throws an error", () => {
1449 assertThrows(() => new stringEndsWith("", ""));
1452 describe(".length", () => {
1453 it("[[Get]] returns the correct length", () => {
1454 assertStrictEquals(stringEndsWith
.length
, 2);
1458 describe(".name", () => {
1459 it("[[Get]] returns the correct name", () => {
1460 assertStrictEquals(stringEndsWith
.name
, "stringEndsWith");
1465 describe("stringFromCodeUnits", () => {
1466 it("[[Call]] makes the string", () => {
1468 stringFromCodeUnits(0xD83C, 0xDD97),
1473 it("[[Call]] throws with non‐integral arguments", () => {
1474 assertThrows(() => stringFromCodeUnits(NaN
));
1475 assertThrows(() => stringFromCodeUnits(Infinity
));
1476 assertThrows(() => stringFromCodeUnits(0.1));
1479 it("[[Call]] throws with arguments out of range", () => {
1480 assertThrows(() => stringFromCodeUnits(-1));
1481 assertThrows(() => stringFromCodeUnits(0x10000));
1484 it("[[Construct]] throws an error", () => {
1485 assertThrows(() => new stringFromCodeUnits([]));
1488 describe(".length", () => {
1489 it("[[Get]] returns the correct length", () => {
1490 assertStrictEquals(stringFromCodeUnits
.length
, 1);
1494 describe(".name", () => {
1495 it("[[Get]] returns the correct name", () => {
1497 stringFromCodeUnits
.name
,
1498 "stringFromCodeUnits",
1504 describe("stringFromCodepoints", () => {
1505 it("[[Call]] makes the string", () => {
1506 assertStrictEquals(stringFromCodepoints(0x1F197), "🆗");
1509 it("[[Call]] throws with non‐integral arguments", () => {
1510 assertThrows(() => stringFromCodepoints(NaN
));
1511 assertThrows(() => stringFromCodepoints(Infinity
));
1512 assertThrows(() => stringFromCodepoints(0.1));
1515 it("[[Call]] throws with arguments out of range", () => {
1516 assertThrows(() => stringFromCodepoints(-1));
1517 assertThrows(() => stringFromCodepoints(0x110000));
1520 it("[[Construct]] throws an error", () => {
1521 assertThrows(() => new stringFromCodepoints([]));
1524 describe(".length", () => {
1525 it("[[Get]] returns the correct length", () => {
1526 assertStrictEquals(stringFromCodepoints
.length
, 1);
1530 describe(".name", () => {
1531 it("[[Get]] returns the correct name", () => {
1533 stringFromCodepoints
.name
,
1534 "stringFromCodepoints",
1540 describe("stringIncludes", () => {
1541 it("[[Call]] returns whether the string includes the thing", () => {
1543 stringIncludes("very success full", " success "),
1547 stringIncludes("very fail full", " success "),
1552 it("[[Call]] accepts an offset", () => {
1554 stringIncludes("maybe success full", " success ", 4),
1558 stringIncludes("maybe success full", " success ", 5),
1562 stringIncludes("maybe success full", " success ", 6),
1567 it("[[Call]] returns true for an empty string test", () => {
1568 assertStrictEquals(stringIncludes("", ""), true);
1571 it("[[Construct]] throws an error", () => {
1572 assertThrows(() => new stringIncludes("", ""));
1575 describe(".length", () => {
1576 it("[[Get]] returns the correct length", () => {
1577 assertStrictEquals(stringIncludes
.length
, 2);
1581 describe(".name", () => {
1582 it("[[Get]] returns the correct name", () => {
1583 assertStrictEquals(stringIncludes
.name
, "stringIncludes");
1588 describe("stringMatch", () => {
1589 it("[[Call]] does the match akin to String::match", () => {
1591 [...stringMatch("very success full", /([sc]+[ue]?)+/)],
1595 [...stringMatch("very success full", /([sc]+)[ue]?/g)],
1596 ["su", "cce", "ss"],
1600 it("[[Construct]] throws an error", () => {
1601 assertThrows(() => new stringMatch("", /(?:)/));
1604 describe(".length", () => {
1605 it("[[Get]] returns the correct length", () => {
1606 assertStrictEquals(stringMatch
.length
, 2);
1610 describe(".name", () => {
1611 it("[[Get]] returns the correct name", () => {
1612 assertStrictEquals(stringMatch
.name
, "stringMatch");
1617 describe("stringMatchAll", () => {
1618 it("[[Call]] does the match akin to String::matchAll", () => {
1620 [...stringMatchAll("very success full", /([sc]+)[ue]?/g)].map((
1623 [["su", "s"], ["cce", "cc"], ["ss", "ss"]],
1627 it("[[Construct]] throws an error", () => {
1628 assertThrows(() => new stringMatchAll("", /(?:)/g));
1631 describe(".length", () => {
1632 it("[[Get]] returns the correct length", () => {
1633 assertStrictEquals(stringMatchAll
.length
, 2);
1637 describe(".name", () => {
1638 it("[[Get]] returns the correct name", () => {
1639 assertStrictEquals(stringMatchAll
.name
, "stringMatchAll");
1644 describe("stringNormalize", () => {
1645 it("[[Call]] normalizes the string properly", () => {
1646 assertStrictEquals(stringNormalize("ẛ", "NFC"), "\u1E9B");
1647 assertStrictEquals(stringNormalize("ẛ", "NFD"), "\u017F\u0307");
1648 assertStrictEquals(stringNormalize("ẛ", "NFKC"), "\u1E61");
1649 assertStrictEquals(stringNormalize("ẛ", "NFKD"), "\u0073\u0307");
1652 it("[[Call]] assumes NFC", () => {
1653 assertStrictEquals(stringNormalize("\u017F\u0307"), "\u1E9B");
1656 it("[[Call]] throws with an invalid form", () => {
1657 assertThrows(() => stringNormalize("", "NFB"));
1660 it("[[Construct]] throws an error", () => {
1661 assertThrows(() => new stringNormalize("", "NFC"));
1664 describe(".length", () => {
1665 it("[[Get]] returns the correct length", () => {
1666 assertStrictEquals(stringNormalize
.length
, 1);
1670 describe(".name", () => {
1671 it("[[Get]] returns the correct name", () => {
1672 assertStrictEquals(stringNormalize
.name
, "stringNormalize");
1677 describe("stringPadEnd", () => {
1678 it("[[Call]] pads the end of the string", () => {
1679 assertStrictEquals(stringPadEnd("xx", 3), "xx ");
1680 assertStrictEquals(stringPadEnd("xx", 3, "o"), "xxo");
1681 assertStrictEquals(stringPadEnd("", 3, "xo"), "xox");
1682 assertStrictEquals(stringPadEnd("xx", 3, ""), "xx");
1685 it("[[Construct]] throws an error", () => {
1686 assertThrows(() => new stringPadEnd("", 1));
1689 describe(".length", () => {
1690 it("[[Get]] returns the correct length", () => {
1691 assertStrictEquals(stringPadEnd
.length
, 2);
1695 describe(".name", () => {
1696 it("[[Get]] returns the correct name", () => {
1697 assertStrictEquals(stringPadEnd
.name
, "stringPadEnd");
1702 describe("stringPadStart", () => {
1703 it("[[Call]] pads the start of the string", () => {
1704 assertStrictEquals(stringPadStart("xx", 3), " xx");
1705 assertStrictEquals(stringPadStart("xx", 3, "o"), "oxx");
1706 assertStrictEquals(stringPadStart("", 3, "xo"), "xox");
1707 assertStrictEquals(stringPadStart("xx", 3, ""), "xx");
1710 it("[[Construct]] throws an error", () => {
1711 assertThrows(() => new stringPadStart("", 1));
1714 describe(".length", () => {
1715 it("[[Get]] returns the correct length", () => {
1716 assertStrictEquals(stringPadStart
.length
, 2);
1720 describe(".name", () => {
1721 it("[[Get]] returns the correct name", () => {
1722 assertStrictEquals(stringPadStart
.name
, "stringPadStart");
1727 describe("stringRepeat", () => {
1728 it("[[Call]] repeats the string", () => {
1729 assertStrictEquals(stringRepeat("xx", 3), "xxxxxx");
1730 assertStrictEquals(stringRepeat("", 3), "");
1731 assertStrictEquals(stringRepeat("xx", 0), "");
1734 it("[[Call]] throws for negative repititions", () => {
1735 assertThrows(() => stringRepeat("", -1));
1738 it("[[Call]] throws for infinite repititions", () => {
1739 assertThrows(() => stringRepeat("", Infinity
));
1742 it("[[Construct]] throws an error", () => {
1743 assertThrows(() => new stringRepeat("", 1));
1746 describe(".length", () => {
1747 it("[[Get]] returns the correct length", () => {
1748 assertStrictEquals(stringRepeat
.length
, 2);
1752 describe(".name", () => {
1753 it("[[Get]] returns the correct name", () => {
1754 assertStrictEquals(stringRepeat
.name
, "stringRepeat");
1759 describe("stringReplace", () => {
1760 it("[[Call]] does the replacement akin to String::replace", () => {
1762 stringReplace("it’s a failure", "failure", "success"),
1767 "very success full",
1775 "very success full",
1778 `${$s[0].length}`.repeat($s
[1].length
)
1779 + $s
[0].substring($s
[1].length
),
1781 "very 2u33e22 full",
1785 it("[[Construct]] throws an error", () => {
1786 assertThrows(() => new stringReplace("", /(?:)/, ""));
1789 describe(".length", () => {
1790 it("[[Get]] returns the correct length", () => {
1791 assertStrictEquals(stringReplace
.length
, 3);
1795 describe(".name", () => {
1796 it("[[Get]] returns the correct name", () => {
1797 assertStrictEquals(stringReplace
.name
, "stringReplace");
1802 describe("stringReplaceAll", () => {
1803 it("[[Call]] does the match akin to String::replaceAll", () => {
1805 stringReplaceAll("it’s a failure failure", "failure", "success"),
1806 "it’s a success success",
1810 "very success full",
1813 `${$s[0].length}`.repeat($s
[1].length
)
1814 + $s
[0].substring($s
[1].length
),
1816 "very 2u33e22 full",
1820 it("[[Construct]] throws an error", () => {
1821 assertThrows(() => new stringReplaceAll("", /(?:)/g));
1824 describe(".length", () => {
1825 it("[[Get]] returns the correct length", () => {
1826 assertStrictEquals(stringReplaceAll
.length
, 3);
1830 describe(".name", () => {
1831 it("[[Get]] returns the correct name", () => {
1832 assertStrictEquals(stringReplaceAll
.name
, "stringReplaceAll");
1837 describe("stringSearch", () => {
1838 it("[[Call]] does the search akin to String::search", () => {
1840 stringSearch("very success full", /([sc]+)[ue]?/),
1844 stringSearch("very fail full", /([sc]+)[ue]?/),
1849 it("[[Construct]] throws an error", () => {
1850 assertThrows(() => new stringSearch("", /(?:)/));
1853 describe(".length", () => {
1854 it("[[Get]] returns the correct length", () => {
1855 assertStrictEquals(stringSearch
.length
, 2);
1859 describe(".name", () => {
1860 it("[[Get]] returns the correct name", () => {
1861 assertStrictEquals(stringSearch
.name
, "stringSearch");
1866 describe("stringSlice", () => {
1867 it("[[Call]] slices the string akin to String::search", () => {
1869 stringSlice("very success full", 5, 12),
1873 stringSlice("very success full", -12, -5),
1878 it("[[Construct]] throws an error", () => {
1879 assertThrows(() => new stringSlice("", 0, 0));
1882 describe(".length", () => {
1883 it("[[Get]] returns the correct length", () => {
1884 assertStrictEquals(stringSlice
.length
, 3);
1888 describe(".name", () => {
1889 it("[[Get]] returns the correct name", () => {
1890 assertStrictEquals(stringSlice
.name
, "stringSlice");
1895 describe("stringSplit", () => {
1896 it("[[Call]] splits the string akin to String::split", () => {
1897 assertEquals(stringSplit("success", ""), [
1906 assertEquals(stringSplit("success", /(?<=[aeiou])(?=[^aeiou])/), [
1911 assertEquals(stringSplit("success", "failure"), ["success"]);
1914 it("[[Call]] recognizes a limit", () => {
1915 assertEquals(stringSplit("success", "", 4), ["s", "u", "c", "c"]);
1918 it("[[Construct]] throws an error", () => {
1919 assertThrows(() => new stringSplit("", ""));
1922 describe(".length", () => {
1923 it("[[Get]] returns the correct length", () => {
1924 assertStrictEquals(stringSplit
.length
, 3);
1928 describe(".name", () => {
1929 it("[[Get]] returns the correct name", () => {
1930 assertStrictEquals(stringSplit
.name
, "stringSplit");
1935 describe("stringStartsWith", () => {
1936 it("[[Call]] returns whether the string starts with the thing", () => {
1938 stringStartsWith("success is had", "success "),
1942 stringStartsWith("no success is had", "success "),
1947 it("[[Call]] accepts an offset", () => {
1949 stringStartsWith("much success is had", "success ", 5),
1954 it("[[Call]] returns true for an empty string test", () => {
1955 assertStrictEquals(stringEndsWith("", ""), true);
1958 it("[[Construct]] throws an error", () => {
1959 assertThrows(() => new stringStartsWith("", ""));
1962 describe(".length", () => {
1963 it("[[Get]] returns the correct length", () => {
1964 assertStrictEquals(stringStartsWith
.length
, 2);
1968 describe(".name", () => {
1969 it("[[Get]] returns the correct name", () => {
1970 assertStrictEquals(stringStartsWith
.name
, "stringStartsWith");
1975 describe("stringStartsWith", () => {
1976 it("[[Call]] returns the string value of a string literal", () => {
1977 assertStrictEquals(stringValue("success"), "success");
1980 it("[[Call]] returns the string value of a string object", () => {
1981 const string
= new String("success");
1982 Object
.defineProperties(string
, {
1983 toString: { value: () => "failure" },
1984 valueOf: { value: () => "failure" },
1986 assertStrictEquals(stringValue(string
), "success");
1989 it("[[Call]] throws for non‐strings", () => {
1990 assertThrows(() => stringValue(Object
.create(String
.prototype)));
1993 it("[[Construct]] throws an error", () => {
1994 assertThrows(() => new stringValue(""));
1997 describe(".length", () => {
1998 it("[[Get]] returns the correct length", () => {
1999 assertStrictEquals(stringValue
.length
, 1);
2003 describe(".name", () => {
2004 it("[[Get]] returns the correct name", () => {
2005 assertStrictEquals(stringValue
.name
, "stringValue");
2010 describe("stripAndCollapseAsciiWhitespace", () => {
2011 it("[[Call]] collapses mixed inner whitespace", () => {
2013 stripAndCollapseAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
2018 it("[[Call]] trims leading and trailing whitespace", () => {
2020 stripAndCollapseAsciiWhitespace(
2021 "\f\r\n\r\n \n\t\f 🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️\n\f",
2027 it("[[Call]] returns the empty string for strings of whitespace", () => {
2029 stripAndCollapseAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
2034 it("[[Call]] does not collapse other kinds of whitespace", () => {
2036 stripAndCollapseAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
2037 "a\u202F\u205F\xa0\v\0\bb",
2041 it("[[Construct]] throws an error", () => {
2042 assertThrows(() => new stripAndCollapseAsciiWhitespace(""));
2045 describe(".length", () => {
2046 it("[[Get]] returns the correct length", () => {
2047 assertStrictEquals(stripAndCollapseAsciiWhitespace
.length
, 1);
2051 describe(".name", () => {
2052 it("[[Get]] returns the correct name", () => {
2054 stripAndCollapseAsciiWhitespace
.name
,
2055 "stripAndCollapseAsciiWhitespace",
2061 describe("stripLeadingAndTrailingAsciiWhitespace", () => {
2062 it("[[Call]] trims leading and trailing whitespace", () => {
2064 stripLeadingAndTrailingAsciiWhitespace(
2065 "\f\r\n\r\n \n\t\f 🅰️🅱️🆎🅾️\n\f",
2071 it("[[Call]] returns the empty string for strings of whitespace", () => {
2073 stripLeadingAndTrailingAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
2078 it("[[Call]] does not trim other kinds of whitespace", () => {
2080 stripLeadingAndTrailingAsciiWhitespace(
2081 "\v\u202F\u205Fx\0\b\xa0",
2083 "\v\u202F\u205Fx\0\b\xa0",
2087 it("[[Call]] does not adjust inner whitespace", () => {
2089 stripLeadingAndTrailingAsciiWhitespace("a b"),
2094 it("[[Construct]] throws an error", () => {
2095 assertThrows(() => new stripLeadingAndTrailingAsciiWhitespace(""));
2098 describe(".length", () => {
2099 it("[[Get]] returns the correct length", () => {
2101 stripLeadingAndTrailingAsciiWhitespace
.length
,
2107 describe(".name", () => {
2108 it("[[Get]] returns the correct name", () => {
2110 stripLeadingAndTrailingAsciiWhitespace
.name
,
2111 "stripLeadingAndTrailingAsciiWhitespace",
2117 describe("substring", () => {
2118 it("[[Call]] returns the substring", () => {
2120 substring("success", 0),
2124 substring("very success full", 5, 12),
2129 it("[[Construct]] throws an error", () => {
2130 assertThrows(() => new substring("", 0));
2133 describe(".length", () => {
2134 it("[[Get]] returns the correct length", () => {
2135 assertStrictEquals(substring
.length
, 3);
2139 describe(".name", () => {
2140 it("[[Get]] returns the correct name", () => {
2141 assertStrictEquals(substring
.name
, "substring");
2146 describe("toScalarValueString", () => {
2147 it("[[Call]] replaces invalid values", () => {
2149 toScalarValueString("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
2150 "Ii🎙\uFFFD\uFFFD\uFFFD\uFFFD🆗☺",
2154 it("[[Construct]] throws an error", () => {
2155 assertThrows(() => new toScalarValueString(""));
2158 describe(".length", () => {
2159 it("[[Get]] returns the correct length", () => {
2160 assertStrictEquals(toScalarValueString
.length
, 1);
2164 describe(".name", () => {
2165 it("[[Get]] returns the correct name", () => {
2167 toScalarValueString
.name
,
2168 "toScalarValueString",
2174 describe("toString", () => {
2175 it("[[Call]] converts to a string", () => {
2186 it("[[Call]] throws when provided a symbol", () => {
2187 assertThrows(() => toString(Symbol()));
2190 it("[[Construct]] throws an error", () => {
2191 assertThrows(() => new toString(""));
2194 describe(".length", () => {
2195 it("[[Get]] returns the correct length", () => {
2196 assertStrictEquals(toString
.length
, 1);
2200 describe(".name", () => {
2201 it("[[Get]] returns the correct name", () => {
2202 assertStrictEquals(toString
.name
, "toString");