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";
32 getFirstSubstringIndex
,
33 getLastSubstringIndex
,
38 splitOnAsciiWhitespace
,
58 stripAndCollapseAsciiWhitespace
,
59 stripLeadingAndTrailingAsciiWhitespace
,
65 describe("Matcher", () => {
66 it("[[Call]] throws an error", () => {
67 assertThrows(() => Matcher(""));
70 it("[[Construct]] accepts a string first argument", () => {
71 assert(new Matcher(""));
74 it("[[Construct]] accepts a unicode regular expression first argument", () => {
75 assert(new Matcher(/(?:)/u));
78 it("[[Construct]] accepts a unicode sets regular expression first argument", () => {
79 assert(new Matcher(/(?:)/v
));
82 it("[[Construct]] throws with a non·unicode·aware regular expression first argument", () => {
83 assertThrows(() => new Matcher(/(?:)/));
86 it("[[Construct]] creates a callable object", () => {
87 assertStrictEquals(typeof new Matcher(""), "function");
90 it("[[Construct]] creates a new Matcher", () => {
92 Object
.getPrototypeOf(new Matcher("")),
97 it("[[Construct]] creates an object which inherits from RegExp", () => {
98 assert(new Matcher("") instanceof RegExp
);
101 it("[[Construct]] throws when provided with a noncallable, non·null third argument", () => {
102 assertThrows(() => new Matcher("", undefined, "failure"));
105 describe(".length", () => {
106 it("[[Get]] returns the correct length", () => {
107 assertStrictEquals(Matcher
.length
, 1);
111 describe(".name", () => {
112 it("[[Get]] returns the correct name", () => {
113 assertStrictEquals(Matcher
.name
, "Matcher");
117 describe("::constructor", () => {
118 it("[[Get]] returns the same constructor", () => {
119 assertStrictEquals(new Matcher(/(?:)/su).constructor, Matcher
);
123 describe("::dotAll", () => {
124 it("[[Get]] returns true when the dotAll flag is present", () => {
125 assertStrictEquals(new Matcher(/(?:)/su).dotAll
, true);
128 it("[[Get]] returns false when the dotAll flag is not present", () => {
129 assertStrictEquals(new Matcher(/(?:)/u).dotAll
, false);
132 describe("[[GetOwnProperty]].get.length", () => {
133 it("[[Get]] returns the correct length", () => {
135 Object
.getOwnPropertyDescriptor(
144 describe("[[GetOwnProperty]].get.name", () => {
145 it("[[Get]] returns the correct name", () => {
147 Object
.getOwnPropertyDescriptor(
157 describe("::exec", () => {
158 it("[[Call]] returns the match object given a complete match", () => {
160 [...new Matcher(/.(?<wow>(?:.(?=.))*)(.)?/u).exec("success")],
161 ["success", "ucces", "s"],
165 /.(?<wow>(?:.(?=.))*)(.)?/u,
167 ($) => $ === "success",
169 ["success", "ucces", "s"],
173 it("[[Call]] calls the constraint if the match succeeds", () => {
174 const constraint
= spy((_
) => true);
175 const matcher
= new Matcher("(.).*", undefined, constraint
);
176 const result
= matcher
.exec({
181 assertEquals([...result
], ["etaoin", "e"]);
182 assertSpyCalls(constraint
, 1);
183 assertStrictEquals(constraint
.calls
[0].args
[0], "etaoin");
184 assertEquals([...constraint
.calls
[0].args
[1]], ["etaoin", "e"]);
185 assertStrictEquals(constraint
.calls
[0].args
[2], matcher
);
186 assertStrictEquals(constraint
.calls
[0].self
, undefined);
189 it("[[Call]] does not call the constraint if the match fails", () => {
190 const constraint
= spy((_
) => true);
191 const matcher
= new Matcher("", undefined, constraint
);
192 matcher
.exec("failure");
193 assertSpyCalls(constraint
, 0);
196 it("[[Call]] returns null given a partial match", () => {
197 assertStrictEquals(new Matcher("").exec("failure"), null);
200 it("[[Call]] returns null if the constraint fails", () => {
202 new Matcher(".*", undefined, () => false).exec(""),
207 it("[[Construct]] throws an error", () => {
208 const matcher
= new Matcher("");
209 assertThrows(() => new matcher
.exec());
212 describe(".length", () => {
213 it("[[Get]] returns the correct length", () => {
214 assertStrictEquals(Matcher
.prototype.exec
.length
, 1);
218 describe(".name", () => {
219 it("[[Get]] returns the correct name", () => {
220 assertStrictEquals(Matcher
.prototype.exec
.name
, "exec");
225 describe("::global", () => {
226 it("[[Get]] returns true when the global flag is present", () => {
227 assertStrictEquals(new Matcher(/(?:)/gu).global
, true);
230 it("[[Get]] returns false when the global flag is not present", () => {
231 assertStrictEquals(new Matcher(/(?:)/u).global
, false);
234 describe("[[GetOwnProperty]].get.length", () => {
235 it("[[Get]] returns the correct length", () => {
237 Object
.getOwnPropertyDescriptor(
246 describe("[[GetOwnProperty]].get.name", () => {
247 it("[[Get]] returns the correct name", () => {
249 Object
.getOwnPropertyDescriptor(
259 describe("::hasIndices", () => {
260 it("[[Get]] returns true when the hasIndices flag is present", () => {
261 assertStrictEquals(new Matcher(/(?:)/du).hasIndices
, true);
264 it("[[Get]] returns false when the hasIndices flag is not present", () => {
265 assertStrictEquals(new Matcher(/(?:)/u).hasIndices
, false);
268 describe("[[GetOwnProperty]].get.length", () => {
269 it("[[Get]] returns the correct length", () => {
271 Object
.getOwnPropertyDescriptor(
280 describe("[[GetOwnProperty]].get.name", () => {
281 it("[[Get]] returns the correct name", () => {
283 Object
.getOwnPropertyDescriptor(
293 describe("::ignoreCase", () => {
294 it("[[Get]] returns true when the ignoreCase flag is present", () => {
295 assertStrictEquals(new Matcher(/(?:)/iu).ignoreCase
, true);
298 it("[[Get]] returns false when the ignoreCase flag is not present", () => {
299 assertStrictEquals(new Matcher(/(?:)/u).ignoreCase
, false);
302 describe("[[GetOwnProperty]].get.length", () => {
303 it("[[Get]] returns the correct length", () => {
305 Object
.getOwnPropertyDescriptor(
314 describe("[[GetOwnProperty]].get.name", () => {
315 it("[[Get]] returns the correct name", () => {
317 Object
.getOwnPropertyDescriptor(
327 describe("::multiline", () => {
328 it("[[Get]] returns true when the multiline flag is present", () => {
329 assertStrictEquals(new Matcher(/(?:)/mu).multiline
, true);
332 it("[[Get]] returns false when the multiline flag is not present", () => {
333 assertStrictEquals(new Matcher(/(?:)/u).multiline
, false);
336 describe("[[GetOwnProperty]].get.length", () => {
337 it("[[Get]] returns the correct length", () => {
339 Object
.getOwnPropertyDescriptor(
348 describe("[[GetOwnProperty]].get.name", () => {
349 it("[[Get]] returns the correct name", () => {
351 Object
.getOwnPropertyDescriptor(
361 describe("::source", () => {
362 it("[[Get]] returns the RegExp source", () => {
363 assertStrictEquals(new Matcher("").source
, "(?:)");
364 assertStrictEquals(new Matcher(/.*/su).source
, ".*");
367 describe("[[GetOwnProperty]].get.length", () => {
368 it("[[Get]] returns the correct length", () => {
370 Object
.getOwnPropertyDescriptor(
379 describe("[[GetOwnProperty]].get.name", () => {
380 it("[[Get]] returns the correct name", () => {
382 Object
.getOwnPropertyDescriptor(
392 describe("::sticky", () => {
393 it("[[Get]] returns true when the sticky flag is present", () => {
394 assertStrictEquals(new Matcher(/(?:)/uy).sticky
, true);
397 it("[[Get]] returns false when the sticky flag is not present", () => {
398 assertStrictEquals(new Matcher(/(?:)/u).sticky
, false);
401 describe("[[GetOwnProperty]].get.length", () => {
402 it("[[Get]] returns the correct length", () => {
404 Object
.getOwnPropertyDescriptor(
413 describe("[[GetOwnProperty]].get.name", () => {
414 it("[[Get]] returns the correct name", () => {
416 Object
.getOwnPropertyDescriptor(
426 describe("::toString", () => {
427 it("[[Call]] returns the string source", () => {
428 assertStrictEquals(new Matcher(/(?:)/u).toString(), "/(?:)/u");
431 it("[[Construct]] throws an error", () => {
432 const matcher
= new Matcher("");
433 assertThrows(() => new matcher
.toString());
436 describe(".length", () => {
437 it("[[Get]] returns the correct length", () => {
438 assertStrictEquals(Matcher
.prototype.toString
.length
, 0);
442 describe(".name", () => {
443 it("[[Get]] returns the correct name", () => {
445 Matcher
.prototype.toString
.name
,
452 describe("::unicode", () => {
453 it("[[Get]] returns true when the unicode flag is present", () => {
454 assertStrictEquals(new Matcher(/(?:)/u).unicode
, true);
457 describe("[[GetOwnProperty]].get.length", () => {
458 it("[[Get]] returns the correct length", () => {
460 Object
.getOwnPropertyDescriptor(
469 describe("[[GetOwnProperty]].get.name", () => {
470 it("[[Get]] returns the correct name", () => {
472 Object
.getOwnPropertyDescriptor(
482 describe("::unicodeSets", () => {
483 it("[[Get]] returns true when the unicode sets flag is present", () => {
484 assertStrictEquals(new Matcher(/(?:)/v
).unicodeSets
, true);
487 describe("[[GetOwnProperty]].get.length", () => {
488 it("[[Get]] returns the correct length", () => {
490 Object
.getOwnPropertyDescriptor(
499 describe("[[GetOwnProperty]].get.name", () => {
500 it("[[Get]] returns the correct name", () => {
502 Object
.getOwnPropertyDescriptor(
512 describe("~", () => {
513 it("[[Call]] returns true for a complete match", () => {
514 assertStrictEquals(new Matcher("")(""), true);
515 assertStrictEquals(new Matcher(/.*/su)("success\nyay"), true);
517 new Matcher(/.*/su, undefined, ($) => $ === "success")(
524 it("[[Call]] calls the constraint if the match succeeds", () => {
525 const constraint
= spy((_
) => true);
526 const matcher
= new Matcher("(.).*", undefined, constraint
);
528 assertSpyCalls(constraint
, 1);
529 assertStrictEquals(constraint
.calls
[0].args
[0], "etaoin");
530 assertEquals([...constraint
.calls
[0].args
[1]], ["etaoin", "e"]);
531 assertStrictEquals(constraint
.calls
[0].args
[2], matcher
);
532 assertStrictEquals(constraint
.calls
[0].self
, undefined);
535 it("[[Call]] does not call the constraint if the match fails", () => {
536 const constraint
= spy((_
) => true);
537 const matcher
= new Matcher("", undefined, constraint
);
539 assertSpyCalls(constraint
, 0);
542 it("[[Call]] returns false for a partial match", () => {
543 assertStrictEquals(new Matcher("")("failure"), false);
544 assertStrictEquals(new Matcher(/.*/u)("failure\nno"), false);
547 it("[[Call]] returns false if the constraint fails", () => {
549 new Matcher(".*", undefined, () => false)(""),
554 it("[[Construct]] throws an error", () => {
555 const matcher
= new Matcher("");
556 assertThrows(() => new matcher(""));
560 describe("~lastIndex", () => {
561 it("[[Get]] returns zero", () => {
562 assertStrictEquals(new Matcher("").lastIndex
, 0);
565 it("[[Set]] fails", () => {
566 assertThrows(() => (new Matcher("").lastIndex
= 1));
570 describe("~length", () => {
571 it("[[Get]] returns one", () => {
572 assertStrictEquals(new Matcher("").length
, 1);
576 describe("~name", () => {
577 it("[[Get]] wraps the stringified regular expression if no name was provided", () => {
578 assertStrictEquals(new Matcher("").name
, "Matcher(/(?:)/u)");
580 new Matcher(/.*/gsu).name
,
585 it("[[Get]] uses the provided name if one was provided", () => {
586 assertStrictEquals(new Matcher("", "success").name
, "success");
591 describe("asciiLowercase", () => {
592 it("[[Call]] lowercases (just) A·S·C·I·I letters", () => {
593 assertStrictEquals(asciiLowercase("aBſÆss FtɁɂß"), "abſÆss ftɁɂß");
596 it("[[Construct]] throws an error", () => {
597 assertThrows(() => new asciiLowercase(""));
600 describe(".length", () => {
601 it("[[Get]] returns the correct length", () => {
602 assertStrictEquals(asciiLowercase
.length
, 1);
606 describe(".name", () => {
607 it("[[Get]] returns the correct name", () => {
608 assertStrictEquals(asciiLowercase
.name
, "asciiLowercase");
613 describe("asciiUppercase", () => {
614 it("[[Call]] uppercases (just) A·S·C·I·I letters", () => {
615 assertStrictEquals(asciiUppercase("aBſÆss FtɁɂß"), "ABſÆSS FTɁɂß");
618 it("[[Construct]] throws an error", () => {
619 assertThrows(() => new asciiUppercase(""));
622 describe(".length", () => {
623 it("[[Get]] returns the correct length", () => {
624 assertStrictEquals(asciiUppercase
.length
, 1);
628 describe(".name", () => {
629 it("[[Get]] returns the correct name", () => {
630 assertStrictEquals(asciiUppercase
.name
, "asciiUppercase");
635 describe("characters", () => {
636 it("[[Call]] returns an iterable", () => {
638 typeof characters("")[Symbol
.iterator
],
643 it("[[Call]] returns an iterator", () => {
644 assertStrictEquals(typeof characters("").next
, "function");
647 it("[[Call]] returns a string character iterator", () => {
649 characters("")[Symbol
.toStringTag
],
650 "String Character Iterator",
654 it("[[Call]] iterates over the characters", () => {
656 ...characters("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
670 it("[[Construct]] throws an error", () => {
671 assertThrows(() => new characters(""));
674 describe(".length", () => {
675 it("[[Get]] returns the correct length", () => {
676 assertStrictEquals(characters
.length
, 1);
680 describe(".name", () => {
681 it("[[Get]] returns the correct name", () => {
682 assertStrictEquals(characters
.name
, "characters");
687 describe("codeUnits", () => {
688 it("[[Call]] returns an iterable", () => {
690 typeof codeUnits("")[Symbol
.iterator
],
695 it("[[Call]] returns an iterator", () => {
696 assertStrictEquals(typeof codeUnits("").next
, "function");
699 it("[[Call]] returns a string code unit iterator", () => {
701 codeUnits("")[Symbol
.toStringTag
],
702 "String Code Unit Iterator",
706 it("[[Call]] iterates over the code units", () => {
708 ...codeUnits("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
724 it("[[Construct]] throws an error", () => {
725 assertThrows(() => new codeUnits(""));
728 describe(".length", () => {
729 it("[[Get]] returns the correct length", () => {
730 assertStrictEquals(codeUnits
.length
, 1);
734 describe(".name", () => {
735 it("[[Get]] returns the correct name", () => {
736 assertStrictEquals(codeUnits
.name
, "codeUnits");
741 describe("codepoints", () => {
742 it("[[Call]] returns an iterable", () => {
744 typeof codepoints("")[Symbol
.iterator
],
749 it("[[Call]] returns an iterator", () => {
750 assertStrictEquals(typeof codepoints("").next
, "function");
753 it("[[Call]] returns a string codepoint iterator", () => {
755 codepoints("")[Symbol
.toStringTag
],
756 "String Codepoint Iterator",
760 it("[[Call]] iterates over the codepoints", () => {
762 ...codepoints("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
776 it("[[Construct]] throws an error", () => {
777 assertThrows(() => new codepoints(""));
780 describe(".length", () => {
781 it("[[Get]] returns the correct length", () => {
782 assertStrictEquals(codepoints
.length
, 1);
786 describe(".name", () => {
787 it("[[Get]] returns the correct name", () => {
788 assertStrictEquals(codepoints
.name
, "codepoints");
793 describe("getCharacter", () => {
794 it("[[Call]] returns the character at the provided position", () => {
795 assertStrictEquals(getCharacter("Ii🎙🆗☺", 4), "🆗");
798 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
799 assertStrictEquals(getCharacter("Ii🎙🆗☺", 5), "\uDD97");
802 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
803 assertStrictEquals(getCharacter("Ii🎙🆗☺", -1), undefined);
804 assertStrictEquals(getCharacter("Ii🎙🆗☺", 7), undefined);
807 it("[[Construct]] throws an error", () => {
808 assertThrows(() => new getCharacter("a", 0));
811 describe(".length", () => {
812 it("[[Get]] returns the correct length", () => {
813 assertStrictEquals(getCharacter
.length
, 2);
817 describe(".name", () => {
818 it("[[Get]] returns the correct name", () => {
819 assertStrictEquals(getCharacter
.name
, "getCharacter");
824 describe("getCodeUnit", () => {
825 it("[[Call]] returns the code unit at the provided position", () => {
826 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 4), 0xD83C);
829 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
830 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 5), 0xDD97);
833 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
834 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", -1), undefined);
835 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 7), undefined);
838 it("[[Construct]] throws an error", () => {
839 assertThrows(() => new getCodeUnit("a", 0));
842 describe(".length", () => {
843 it("[[Get]] returns the correct length", () => {
844 assertStrictEquals(getCodeUnit
.length
, 2);
848 describe(".name", () => {
849 it("[[Get]] returns the correct name", () => {
850 assertStrictEquals(getCodeUnit
.name
, "getCodeUnit");
855 describe("getCodepoint", () => {
856 it("[[Call]] returns the character at the provided position", () => {
857 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 4), 0x1F197);
860 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
861 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 5), 0xDD97);
864 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
865 assertStrictEquals(getCodepoint("Ii🎙🆗☺", -1), undefined);
866 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 7), undefined);
869 it("[[Construct]] throws an error", () => {
870 assertThrows(() => new getCodepoint("a", 0));
873 describe(".length", () => {
874 it("[[Get]] returns the correct length", () => {
875 assertStrictEquals(getCodepoint
.length
, 2);
879 describe(".name", () => {
880 it("[[Get]] returns the correct name", () => {
881 assertStrictEquals(getCodepoint
.name
, "getCodepoint");
886 describe("getFirstSubstringIndex", () => {
887 it("[[Call]] returns the index of the first match", () => {
888 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 4);
891 it("[[Call]] returns −1 if no match is found", () => {
892 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗🆖"), -1);
895 it("[[Call]] returns 0 when provided with an empty string", () => {
896 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", ""), 0);
899 it("[[Construct]] throws an error", () => {
900 assertThrows(() => new getFirstSubstringIndex("", ""));
903 describe(".length", () => {
904 it("[[Get]] returns the correct length", () => {
905 assertStrictEquals(getFirstSubstringIndex
.length
, 2);
909 describe(".name", () => {
910 it("[[Get]] returns the correct name", () => {
912 getFirstSubstringIndex
.name
,
913 "getFirstSubstringIndex",
919 describe("getLastSubstringIndex", () => {
920 it("[[Call]] returns the index of the first match", () => {
921 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 7);
924 it("[[Call]] returns −1 if no match is found", () => {
925 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆖🆗"), -1);
928 it("[[Call]] returns the length when provided with an empty string", () => {
930 getLastSubstringIndex("Ii🎙🆗☺🆗", ""),
935 it("[[Construct]] throws an error", () => {
936 assertThrows(() => new getLastSubstringIndex("", ""));
939 describe(".length", () => {
940 it("[[Get]] returns the correct length", () => {
941 assertStrictEquals(getLastSubstringIndex
.length
, 2);
945 describe(".name", () => {
946 it("[[Get]] returns the correct name", () => {
948 getLastSubstringIndex
.name
,
949 "getLastSubstringIndex",
955 describe("join", () => {
956 it("[[Call]] joins the provided iterator with the provided separartor", () => {
957 assertStrictEquals(join([1, 2, 3, 4].values(), "☂"), "1☂2☂3☂4");
960 it('[[Call]] uses "," if no separator is provided', () => {
961 assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
964 it("[[Call]] uses the empty sting for nullish values", () => {
966 join([null, , null, undefined].values(), "☂"),
971 it("[[Construct]] throws an error", () => {
972 assertThrows(() => new join([]));
975 describe(".length", () => {
976 it("[[Get]] returns the correct length", () => {
977 assertStrictEquals(join
.length
, 2);
981 describe(".name", () => {
982 it("[[Get]] returns the correct name", () => {
983 assertStrictEquals(join
.name
, "join");
988 describe("rawString", () => {
989 it("[[Call]] acts like String.raw", () => {
990 assertStrictEquals(rawString
`\nraw${" string"}`, "\\nraw string");
993 it("[[Construct]] throws an error", () => {
994 assertThrows(() => new rawString(["string"]));
997 describe(".length", () => {
998 it("[[Get]] returns the correct length", () => {
999 assertStrictEquals(rawString
.length
, 1);
1003 describe(".name", () => {
1004 it("[[Get]] returns the correct name", () => {
1005 assertStrictEquals(rawString
.name
, "rawString");
1010 describe("scalarValues", () => {
1011 it("[[Call]] returns an iterable", () => {
1013 typeof scalarValues("")[Symbol
.iterator
],
1018 it("[[Call]] returns an iterator", () => {
1019 assertStrictEquals(typeof scalarValues("").next
, "function");
1022 it("[[Call]] returns a string scalar value iterator", () => {
1024 scalarValues("")[Symbol
.toStringTag
],
1025 "String Scalar Value Iterator",
1029 it("[[Call]] iterates over the scalar values", () => {
1031 ...scalarValues("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
1045 it("[[Construct]] throws an error", () => {
1046 assertThrows(() => new scalarValues(""));
1049 describe(".length", () => {
1050 it("[[Get]] returns the correct length", () => {
1051 assertStrictEquals(scalarValues
.length
, 1);
1055 describe(".name", () => {
1056 it("[[Get]] returns the correct name", () => {
1057 assertStrictEquals(scalarValues
.name
, "scalarValues");
1062 describe("splitOnAsciiWhitespace", () => {
1063 it("[[Call]] splits on sequences of spaces", () => {
1065 splitOnAsciiWhitespace("🅰️ 🅱️ 🆎 🅾️"),
1066 ["🅰️", "🅱️", "🆎", "🅾️"],
1070 it("[[Call]] splits on sequences of tabs", () => {
1072 splitOnAsciiWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
1073 ["🅰️", "🅱️", "🆎", "🅾️"],
1077 it("[[Call]] splits on sequences of carriage returns", () => {
1079 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1080 ["🅰️", "🅱️", "🆎", "🅾️"],
1084 it("[[Call]] splits on sequences of newlines", () => {
1086 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1087 ["🅰️", "🅱️", "🆎", "🅾️"],
1091 it("[[Call]] splits on sequences of form feeds", () => {
1093 splitOnAsciiWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
1094 ["🅰️", "🅱️", "🆎", "🅾️"],
1098 it("[[Call]] splits on mixed whitespace", () => {
1100 splitOnAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
1101 ["🅰️", "🅱️", "🆎", "🅾️"],
1105 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1106 assertEquals(splitOnAsciiWhitespace(""), [""]);
1109 it("[[Call]] returns a single token if there are no spaces", () => {
1110 assertEquals(splitOnAsciiWhitespace("abcd"), ["abcd"]);
1113 it("[[Call]] does not split on other kinds of whitespace", () => {
1115 splitOnAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
1116 ["a\u202F\u205F\xa0\v\0\bb"],
1120 it("[[Call]] trims leading and trailing whitespace", () => {
1122 splitOnAsciiWhitespace(
1123 "\f\r\n\r\n \n\t🅰️\f \t\n🅱️\r🆎\n\f🅾️\n\f",
1125 ["🅰️", "🅱️", "🆎", "🅾️"],
1129 it("[[Construct]] throws an error", () => {
1130 assertThrows(() => new splitOnAsciiWhitespace(""));
1133 describe(".length", () => {
1134 it("[[Get]] returns the correct length", () => {
1135 assertStrictEquals(splitOnAsciiWhitespace
.length
, 1);
1139 describe(".name", () => {
1140 it("[[Get]] returns the correct name", () => {
1142 splitOnAsciiWhitespace
.name
,
1143 "splitOnAsciiWhitespace",
1149 describe("splitOnCommas", () => {
1150 it("[[Call]] splits on commas", () => {
1152 splitOnCommas("🅰️,🅱️,🆎,🅾️"),
1153 ["🅰️", "🅱️", "🆎", "🅾️"],
1157 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1158 assertEquals(splitOnCommas(""), [""]);
1161 it("[[Call]] returns a single token if there are no commas", () => {
1162 assertEquals(splitOnCommas("abcd"), ["abcd"]);
1165 it("[[Call]] splits into empty strings if there are only commas", () => {
1166 assertEquals(splitOnCommas(",,,"), ["", "", "", ""]);
1169 it("[[Call]] trims leading and trailing whitespace", () => {
1171 splitOnCommas("\f\r\n\r\n \n\t🅰️,🅱️,🆎,🅾️\n\f"),
1172 ["🅰️", "🅱️", "🆎", "🅾️"],
1175 splitOnCommas("\f\r\n\r\n \n\t,,,\n\f"),
1180 it("[[Call]] removes whitespace from the split tokens", () => {
1183 "\f\r\n\r\n \n\t🅰️\f , \t\n🅱️,\r\n\r🆎\n\f,🅾️\n\f",
1185 ["🅰️", "🅱️", "🆎", "🅾️"],
1188 splitOnCommas("\f\r\n\r\n \n\t\f , \t\n,\r\n\r\n\f,\n\f"),
1193 it("[[Construct]] throws an error", () => {
1194 assertThrows(() => new splitOnCommas(""));
1197 describe(".length", () => {
1198 it("[[Get]] returns the correct length", () => {
1199 assertStrictEquals(splitOnCommas
.length
, 1);
1203 describe(".name", () => {
1204 it("[[Get]] returns the correct name", () => {
1205 assertStrictEquals(splitOnCommas
.name
, "splitOnCommas");
1210 describe("stringCatenate", () => {
1211 it("[[Call]] catenates the values", () => {
1212 assertStrictEquals(stringCatenate("the", " values"), "the values");
1215 it("[[Call]] returns an empty string when called with no values", () => {
1216 assertStrictEquals(stringCatenate(), "");
1219 it('[[Call]] uses "undefined" when explicitly provided undefined', () => {
1221 stringCatenate(undefined, undefined),
1222 "undefinedundefined",
1226 it('[[Call]] uses "null" when provided null', () => {
1227 assertStrictEquals(stringCatenate(null, null), "nullnull");
1230 it("[[Construct]] throws an error", () => {
1231 assertThrows(() => new stringCatenate());
1234 describe(".length", () => {
1235 it("[[Get]] returns the correct length", () => {
1236 assertStrictEquals(stringCatenate
.length
, 2);
1240 describe(".name", () => {
1241 it("[[Get]] returns the correct name", () => {
1242 assertStrictEquals(stringCatenate
.name
, "stringCatenate");
1247 describe("stringEndsWith", () => {
1248 it("[[Call]] returns whether the string ends with the thing", () => {
1250 stringEndsWith("very success", " success"),
1253 assertStrictEquals(stringEndsWith("very fail", " success"), false);
1256 it("[[Call]] accepts an offset", () => {
1258 stringEndsWith("very successful", " success", 12),
1263 it("[[Call]] returns true for an empty string test", () => {
1264 assertStrictEquals(stringEndsWith("", ""), true);
1267 it("[[Construct]] throws an error", () => {
1268 assertThrows(() => new stringEndsWith("", ""));
1271 describe(".length", () => {
1272 it("[[Get]] returns the correct length", () => {
1273 assertStrictEquals(stringEndsWith
.length
, 2);
1277 describe(".name", () => {
1278 it("[[Get]] returns the correct name", () => {
1279 assertStrictEquals(stringEndsWith
.name
, "stringEndsWith");
1284 describe("stringFromCodeUnits", () => {
1285 it("[[Call]] makes the string", () => {
1287 stringFromCodeUnits(0xD83C, 0xDD97),
1292 it("[[Call]] throws with non‐integral arguments", () => {
1293 assertThrows(() => stringFromCodeUnits(NaN
));
1294 assertThrows(() => stringFromCodeUnits(Infinity
));
1295 assertThrows(() => stringFromCodeUnits(0.1));
1298 it("[[Call]] throws with arguments out of range", () => {
1299 assertThrows(() => stringFromCodeUnits(-1));
1300 assertThrows(() => stringFromCodeUnits(0x10000));
1303 it("[[Construct]] throws an error", () => {
1304 assertThrows(() => new stringFromCodeUnits([]));
1307 describe(".length", () => {
1308 it("[[Get]] returns the correct length", () => {
1309 assertStrictEquals(stringFromCodeUnits
.length
, 1);
1313 describe(".name", () => {
1314 it("[[Get]] returns the correct name", () => {
1316 stringFromCodeUnits
.name
,
1317 "stringFromCodeUnits",
1323 describe("stringFromCodepoints", () => {
1324 it("[[Call]] makes the string", () => {
1325 assertStrictEquals(stringFromCodepoints(0x1F197), "🆗");
1328 it("[[Call]] throws with non‐integral arguments", () => {
1329 assertThrows(() => stringFromCodepoints(NaN
));
1330 assertThrows(() => stringFromCodepoints(Infinity
));
1331 assertThrows(() => stringFromCodepoints(0.1));
1334 it("[[Call]] throws with arguments out of range", () => {
1335 assertThrows(() => stringFromCodepoints(-1));
1336 assertThrows(() => stringFromCodepoints(0x110000));
1339 it("[[Construct]] throws an error", () => {
1340 assertThrows(() => new stringFromCodepoints([]));
1343 describe(".length", () => {
1344 it("[[Get]] returns the correct length", () => {
1345 assertStrictEquals(stringFromCodepoints
.length
, 1);
1349 describe(".name", () => {
1350 it("[[Get]] returns the correct name", () => {
1352 stringFromCodepoints
.name
,
1353 "stringFromCodepoints",
1359 describe("stringIncludes", () => {
1360 it("[[Call]] returns whether the string includes the thing", () => {
1362 stringIncludes("very success full", " success "),
1366 stringIncludes("very fail full", " success "),
1371 it("[[Call]] accepts an offset", () => {
1373 stringIncludes("maybe success full", " success ", 4),
1377 stringIncludes("maybe success full", " success ", 5),
1381 stringIncludes("maybe success full", " success ", 6),
1386 it("[[Call]] returns true for an empty string test", () => {
1387 assertStrictEquals(stringIncludes("", ""), true);
1390 it("[[Construct]] throws an error", () => {
1391 assertThrows(() => new stringIncludes("", ""));
1394 describe(".length", () => {
1395 it("[[Get]] returns the correct length", () => {
1396 assertStrictEquals(stringIncludes
.length
, 2);
1400 describe(".name", () => {
1401 it("[[Get]] returns the correct name", () => {
1402 assertStrictEquals(stringIncludes
.name
, "stringIncludes");
1407 describe("stringMatch", () => {
1408 it("[[Call]] does the match akin to String::match", () => {
1410 [...stringMatch("very success full", /([sc]+[ue]?)+/)],
1414 [...stringMatch("very success full", /([sc]+)[ue]?/g)],
1415 ["su", "cce", "ss"],
1419 it("[[Construct]] throws an error", () => {
1420 assertThrows(() => new stringMatch("", /(?:)/));
1423 describe(".length", () => {
1424 it("[[Get]] returns the correct length", () => {
1425 assertStrictEquals(stringMatch
.length
, 2);
1429 describe(".name", () => {
1430 it("[[Get]] returns the correct name", () => {
1431 assertStrictEquals(stringMatch
.name
, "stringMatch");
1436 describe("stringMatchAll", () => {
1437 it("[[Call]] does the match akin to String::matchAll", () => {
1439 [...stringMatchAll("very success full", /([sc]+)[ue]?/g)].map((
1442 [["su", "s"], ["cce", "cc"], ["ss", "ss"]],
1446 it("[[Construct]] throws an error", () => {
1447 assertThrows(() => new stringMatchAll("", /(?:)/g));
1450 describe(".length", () => {
1451 it("[[Get]] returns the correct length", () => {
1452 assertStrictEquals(stringMatchAll
.length
, 2);
1456 describe(".name", () => {
1457 it("[[Get]] returns the correct name", () => {
1458 assertStrictEquals(stringMatchAll
.name
, "stringMatchAll");
1463 describe("stringNormalize", () => {
1464 it("[[Call]] normalizes the string properly", () => {
1465 assertStrictEquals(stringNormalize("ẛ", "NFC"), "\u1E9B");
1466 assertStrictEquals(stringNormalize("ẛ", "NFD"), "\u017F\u0307");
1467 assertStrictEquals(stringNormalize("ẛ", "NFKC"), "\u1E61");
1468 assertStrictEquals(stringNormalize("ẛ", "NFKD"), "\u0073\u0307");
1471 it("[[Call]] assumes NFC", () => {
1472 assertStrictEquals(stringNormalize("\u017F\u0307"), "\u1E9B");
1475 it("[[Call]] throws with an invalid form", () => {
1476 assertThrows(() => stringNormalize("", "NFB"));
1479 it("[[Construct]] throws an error", () => {
1480 assertThrows(() => new stringNormalize("", "NFC"));
1483 describe(".length", () => {
1484 it("[[Get]] returns the correct length", () => {
1485 assertStrictEquals(stringNormalize
.length
, 1);
1489 describe(".name", () => {
1490 it("[[Get]] returns the correct name", () => {
1491 assertStrictEquals(stringNormalize
.name
, "stringNormalize");
1496 describe("stringPadEnd", () => {
1497 it("[[Call]] pads the end of the string", () => {
1498 assertStrictEquals(stringPadEnd("xx", 3), "xx ");
1499 assertStrictEquals(stringPadEnd("xx", 3, "o"), "xxo");
1500 assertStrictEquals(stringPadEnd("", 3, "xo"), "xox");
1501 assertStrictEquals(stringPadEnd("xx", 3, ""), "xx");
1504 it("[[Construct]] throws an error", () => {
1505 assertThrows(() => new stringPadEnd("", 1));
1508 describe(".length", () => {
1509 it("[[Get]] returns the correct length", () => {
1510 assertStrictEquals(stringPadEnd
.length
, 2);
1514 describe(".name", () => {
1515 it("[[Get]] returns the correct name", () => {
1516 assertStrictEquals(stringPadEnd
.name
, "stringPadEnd");
1521 describe("stringPadStart", () => {
1522 it("[[Call]] pads the start of the string", () => {
1523 assertStrictEquals(stringPadStart("xx", 3), " xx");
1524 assertStrictEquals(stringPadStart("xx", 3, "o"), "oxx");
1525 assertStrictEquals(stringPadStart("", 3, "xo"), "xox");
1526 assertStrictEquals(stringPadStart("xx", 3, ""), "xx");
1529 it("[[Construct]] throws an error", () => {
1530 assertThrows(() => new stringPadStart("", 1));
1533 describe(".length", () => {
1534 it("[[Get]] returns the correct length", () => {
1535 assertStrictEquals(stringPadStart
.length
, 2);
1539 describe(".name", () => {
1540 it("[[Get]] returns the correct name", () => {
1541 assertStrictEquals(stringPadStart
.name
, "stringPadStart");
1546 describe("stringRepeat", () => {
1547 it("[[Call]] repeats the string", () => {
1548 assertStrictEquals(stringRepeat("xx", 3), "xxxxxx");
1549 assertStrictEquals(stringRepeat("", 3), "");
1550 assertStrictEquals(stringRepeat("xx", 0), "");
1553 it("[[Call]] throws for negative repititions", () => {
1554 assertThrows(() => stringRepeat("", -1));
1557 it("[[Call]] throws for infinite repititions", () => {
1558 assertThrows(() => stringRepeat("", Infinity
));
1561 it("[[Construct]] throws an error", () => {
1562 assertThrows(() => new stringRepeat("", 1));
1565 describe(".length", () => {
1566 it("[[Get]] returns the correct length", () => {
1567 assertStrictEquals(stringRepeat
.length
, 2);
1571 describe(".name", () => {
1572 it("[[Get]] returns the correct name", () => {
1573 assertStrictEquals(stringRepeat
.name
, "stringRepeat");
1578 describe("stringReplace", () => {
1579 it("[[Call]] does the replacement akin to String::replace", () => {
1581 stringReplace("it’s a failure", "failure", "success"),
1586 "very success full",
1594 "very success full",
1597 `${$s[0].length}`.repeat($s
[1].length
)
1598 + $s
[0].substring($s
[1].length
),
1600 "very 2u33e22 full",
1604 it("[[Construct]] throws an error", () => {
1605 assertThrows(() => new stringReplace("", /(?:)/, ""));
1608 describe(".length", () => {
1609 it("[[Get]] returns the correct length", () => {
1610 assertStrictEquals(stringReplace
.length
, 3);
1614 describe(".name", () => {
1615 it("[[Get]] returns the correct name", () => {
1616 assertStrictEquals(stringReplace
.name
, "stringReplace");
1621 describe("stringReplaceAll", () => {
1622 it("[[Call]] does the match akin to String::replaceAll", () => {
1624 stringReplaceAll("it’s a failure failure", "failure", "success"),
1625 "it’s a success success",
1629 "very success full",
1632 `${$s[0].length}`.repeat($s
[1].length
)
1633 + $s
[0].substring($s
[1].length
),
1635 "very 2u33e22 full",
1639 it("[[Construct]] throws an error", () => {
1640 assertThrows(() => new stringReplaceAll("", /(?:)/g));
1643 describe(".length", () => {
1644 it("[[Get]] returns the correct length", () => {
1645 assertStrictEquals(stringReplaceAll
.length
, 3);
1649 describe(".name", () => {
1650 it("[[Get]] returns the correct name", () => {
1651 assertStrictEquals(stringReplaceAll
.name
, "stringReplaceAll");
1656 describe("stringSearch", () => {
1657 it("[[Call]] does the search akin to String::search", () => {
1659 stringSearch("very success full", /([sc]+)[ue]?/),
1663 stringSearch("very fail full", /([sc]+)[ue]?/),
1668 it("[[Construct]] throws an error", () => {
1669 assertThrows(() => new stringSearch("", /(?:)/));
1672 describe(".length", () => {
1673 it("[[Get]] returns the correct length", () => {
1674 assertStrictEquals(stringSearch
.length
, 2);
1678 describe(".name", () => {
1679 it("[[Get]] returns the correct name", () => {
1680 assertStrictEquals(stringSearch
.name
, "stringSearch");
1685 describe("stringSlice", () => {
1686 it("[[Call]] slices the string akin to String::search", () => {
1688 stringSlice("very success full", 5, 12),
1692 stringSlice("very success full", -12, -5),
1697 it("[[Construct]] throws an error", () => {
1698 assertThrows(() => new stringSlice("", 0, 0));
1701 describe(".length", () => {
1702 it("[[Get]] returns the correct length", () => {
1703 assertStrictEquals(stringSlice
.length
, 3);
1707 describe(".name", () => {
1708 it("[[Get]] returns the correct name", () => {
1709 assertStrictEquals(stringSlice
.name
, "stringSlice");
1714 describe("stringSplit", () => {
1715 it("[[Call]] splits the string akin to String::split", () => {
1716 assertEquals(stringSplit("success", ""), [
1725 assertEquals(stringSplit("success", /(?<=[aeiou])(?=[^aeiou])/), [
1730 assertEquals(stringSplit("success", "failure"), ["success"]);
1733 it("[[Call]] recognizes a limit", () => {
1734 assertEquals(stringSplit("success", "", 4), ["s", "u", "c", "c"]);
1737 it("[[Construct]] throws an error", () => {
1738 assertThrows(() => new stringSplit("", ""));
1741 describe(".length", () => {
1742 it("[[Get]] returns the correct length", () => {
1743 assertStrictEquals(stringSplit
.length
, 3);
1747 describe(".name", () => {
1748 it("[[Get]] returns the correct name", () => {
1749 assertStrictEquals(stringSplit
.name
, "stringSplit");
1754 describe("stringStartsWith", () => {
1755 it("[[Call]] returns whether the string starts with the thing", () => {
1757 stringStartsWith("success is had", "success "),
1761 stringStartsWith("no success is had", "success "),
1766 it("[[Call]] accepts an offset", () => {
1768 stringStartsWith("much success is had", "success ", 5),
1773 it("[[Call]] returns true for an empty string test", () => {
1774 assertStrictEquals(stringEndsWith("", ""), true);
1777 it("[[Construct]] throws an error", () => {
1778 assertThrows(() => new stringStartsWith("", ""));
1781 describe(".length", () => {
1782 it("[[Get]] returns the correct length", () => {
1783 assertStrictEquals(stringStartsWith
.length
, 2);
1787 describe(".name", () => {
1788 it("[[Get]] returns the correct name", () => {
1789 assertStrictEquals(stringStartsWith
.name
, "stringStartsWith");
1794 describe("stringStartsWith", () => {
1795 it("[[Call]] returns the string value of a string literal", () => {
1796 assertStrictEquals(stringValue("success"), "success");
1799 it("[[Call]] returns the string value of a string object", () => {
1800 const string
= new String("success");
1801 Object
.defineProperties(string
, {
1802 toString: { value: () => "failure" },
1803 valueOf: { value: () => "failure" },
1805 assertStrictEquals(stringValue(string
), "success");
1808 it("[[Call]] throws for non‐strings", () => {
1809 assertThrows(() => stringValue(Object
.create(String
.prototype)));
1812 it("[[Construct]] throws an error", () => {
1813 assertThrows(() => new stringValue(""));
1816 describe(".length", () => {
1817 it("[[Get]] returns the correct length", () => {
1818 assertStrictEquals(stringValue
.length
, 1);
1822 describe(".name", () => {
1823 it("[[Get]] returns the correct name", () => {
1824 assertStrictEquals(stringValue
.name
, "stringValue");
1829 describe("stripAndCollapseAsciiWhitespace", () => {
1830 it("[[Call]] collapses mixed inner whitespace", () => {
1832 stripAndCollapseAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
1837 it("[[Call]] trims leading and trailing whitespace", () => {
1839 stripAndCollapseAsciiWhitespace(
1840 "\f\r\n\r\n \n\t\f 🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️\n\f",
1846 it("[[Call]] returns the empty string for strings of whitespace", () => {
1848 stripAndCollapseAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
1853 it("[[Call]] does not collapse other kinds of whitespace", () => {
1855 stripAndCollapseAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
1856 "a\u202F\u205F\xa0\v\0\bb",
1860 it("[[Construct]] throws an error", () => {
1861 assertThrows(() => new stripAndCollapseAsciiWhitespace(""));
1864 describe(".length", () => {
1865 it("[[Get]] returns the correct length", () => {
1866 assertStrictEquals(stripAndCollapseAsciiWhitespace
.length
, 1);
1870 describe(".name", () => {
1871 it("[[Get]] returns the correct name", () => {
1873 stripAndCollapseAsciiWhitespace
.name
,
1874 "stripAndCollapseAsciiWhitespace",
1880 describe("stripLeadingAndTrailingAsciiWhitespace", () => {
1881 it("[[Call]] trims leading and trailing whitespace", () => {
1883 stripLeadingAndTrailingAsciiWhitespace(
1884 "\f\r\n\r\n \n\t\f 🅰️🅱️🆎🅾️\n\f",
1890 it("[[Call]] returns the empty string for strings of whitespace", () => {
1892 stripLeadingAndTrailingAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
1897 it("[[Call]] does not trim other kinds of whitespace", () => {
1899 stripLeadingAndTrailingAsciiWhitespace(
1900 "\v\u202F\u205Fx\0\b\xa0",
1902 "\v\u202F\u205Fx\0\b\xa0",
1906 it("[[Call]] does not adjust inner whitespace", () => {
1908 stripLeadingAndTrailingAsciiWhitespace("a b"),
1913 it("[[Construct]] throws an error", () => {
1914 assertThrows(() => new stripLeadingAndTrailingAsciiWhitespace(""));
1917 describe(".length", () => {
1918 it("[[Get]] returns the correct length", () => {
1920 stripLeadingAndTrailingAsciiWhitespace
.length
,
1926 describe(".name", () => {
1927 it("[[Get]] returns the correct name", () => {
1929 stripLeadingAndTrailingAsciiWhitespace
.name
,
1930 "stripLeadingAndTrailingAsciiWhitespace",
1936 describe("substring", () => {
1937 it("[[Call]] returns the substring", () => {
1939 substring("success", 0),
1943 substring("very success full", 5, 12),
1948 it("[[Construct]] throws an error", () => {
1949 assertThrows(() => new substring("", 0));
1952 describe(".length", () => {
1953 it("[[Get]] returns the correct length", () => {
1954 assertStrictEquals(substring
.length
, 3);
1958 describe(".name", () => {
1959 it("[[Get]] returns the correct name", () => {
1960 assertStrictEquals(substring
.name
, "substring");
1965 describe("toScalarValueString", () => {
1966 it("[[Call]] replaces invalid values", () => {
1968 toScalarValueString("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
1969 "Ii🎙\uFFFD\uFFFD\uFFFD\uFFFD🆗☺",
1973 it("[[Construct]] throws an error", () => {
1974 assertThrows(() => new toScalarValueString(""));
1977 describe(".length", () => {
1978 it("[[Get]] returns the correct length", () => {
1979 assertStrictEquals(toScalarValueString
.length
, 1);
1983 describe(".name", () => {
1984 it("[[Get]] returns the correct name", () => {
1986 toScalarValueString
.name
,
1987 "toScalarValueString",
1993 describe("toString", () => {
1994 it("[[Call]] converts to a string", () => {
2005 it("[[Call]] throws when provided a symbol", () => {
2006 assertThrows(() => toString(Symbol()));
2009 it("[[Construct]] throws an error", () => {
2010 assertThrows(() => new toString(""));
2013 describe(".length", () => {
2014 it("[[Get]] returns the correct length", () => {
2015 assertStrictEquals(toString
.length
, 1);
2019 describe(".name", () => {
2020 it("[[Get]] returns the correct name", () => {
2021 assertStrictEquals(toString
.name
, "toString");