]> Lady’s Gitweb - Pisces/blob - string.test.js
Move string functions from value.js to string.js
[Pisces] / string.test.js
1 // ♓🌟 Piscēs ∷ string.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022–2023 Lady [@ Lady’s Computer].
5 //
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
9
10 import {
11 assert,
12 assertEquals,
13 assertSpyCalls,
14 assertStrictEquals,
15 assertThrows,
16 describe,
17 it,
18 spy,
19 } from "./dev-deps.js";
20 import {
21 asciiLowercase,
22 asciiUppercase,
23 canonicalNumericIndexString,
24 characters,
25 codepoints,
26 codeUnits,
27 getCharacter,
28 getCodepoint,
29 getCodeUnit,
30 getFirstSubstringIndex,
31 getLastSubstringIndex,
32 isIntegerIndexString,
33 join,
34 Matcher,
35 rawString,
36 scalarValues,
37 splitOnAsciiWhitespace,
38 splitOnCommas,
39 stringCatenate,
40 stringEndsWith,
41 stringFromCodepoints,
42 stringFromCodeUnits,
43 stringIncludes,
44 stringMatch,
45 stringMatchAll,
46 stringNormalize,
47 stringPadEnd,
48 stringPadStart,
49 stringRepeat,
50 stringReplace,
51 stringReplaceAll,
52 stringSearch,
53 stringSlice,
54 stringSplit,
55 stringStartsWith,
56 stringValue,
57 stripAndCollapseAsciiWhitespace,
58 stripLeadingAndTrailingAsciiWhitespace,
59 substring,
60 toScalarValueString,
61 toString,
62 } from "./string.js";
63
64 describe("Matcher", () => {
65 it("[[Call]] throws an error", () => {
66 assertThrows(() => Matcher(""));
67 });
68
69 it("[[Construct]] accepts a string first argument", () => {
70 assert(new Matcher(""));
71 });
72
73 it("[[Construct]] accepts a unicode regular expression first argument", () => {
74 assert(new Matcher(/(?:)/u));
75 });
76
77 it("[[Construct]] throws with a non·unicode regular expression first argument", () => {
78 assertThrows(() => new Matcher(/(?:)/));
79 });
80
81 it("[[Construct]] creates a callable object", () => {
82 assertStrictEquals(typeof new Matcher(""), "function");
83 });
84
85 it("[[Construct]] creates a new Matcher", () => {
86 assertStrictEquals(
87 Object.getPrototypeOf(new Matcher("")),
88 Matcher.prototype,
89 );
90 });
91
92 it("[[Construct]] creates an object which inherits from RegExp", () => {
93 assert(new Matcher("") instanceof RegExp);
94 });
95
96 it("[[Construct]] throws when provided with a noncallable, non·null third argument", () => {
97 assertThrows(() => new Matcher("", undefined, "failure"));
98 });
99
100 describe(".length", () => {
101 it("[[Get]] returns the correct length", () => {
102 assertStrictEquals(Matcher.length, 1);
103 });
104 });
105
106 describe(".name", () => {
107 it("[[Get]] returns the correct name", () => {
108 assertStrictEquals(Matcher.name, "Matcher");
109 });
110 });
111
112 describe("::dotAll", () => {
113 it("[[Get]] returns true when the dotAll flag is present", () => {
114 assertStrictEquals(new Matcher(/(?:)/su).dotAll, true);
115 });
116
117 it("[[Get]] returns false when the dotAll flag is not present", () => {
118 assertStrictEquals(new Matcher(/(?:)/u).dotAll, false);
119 });
120
121 describe(".length", () => {
122 it("[[Get]] returns the correct length", () => {
123 assertStrictEquals(
124 Object.getOwnPropertyDescriptor(
125 Matcher.prototype,
126 "dotAll",
127 ).get.length,
128 0,
129 );
130 });
131 });
132
133 describe(".name", () => {
134 it("[[Get]] returns the correct name", () => {
135 assertStrictEquals(
136 Object.getOwnPropertyDescriptor(
137 Matcher.prototype,
138 "dotAll",
139 ).get.name,
140 "get dotAll",
141 );
142 });
143 });
144 });
145
146 describe("::exec", () => {
147 it("[[Call]] returns the match object given a complete match", () => {
148 assertEquals(
149 [...new Matcher(/.(?<wow>(?:.(?=.))*)(.)?/u).exec("success")],
150 ["success", "ucces", "s"],
151 );
152 assertEquals(
153 [...new Matcher(
154 /.(?<wow>(?:.(?=.))*)(.)?/u,
155 undefined,
156 ($) => $ === "success",
157 ).exec("success")],
158 ["success", "ucces", "s"],
159 );
160 });
161
162 it("[[Call]] calls the constraint if the match succeeds", () => {
163 const constraint = spy((_) => true);
164 const matcher = new Matcher("(.).*", undefined, constraint);
165 const result = matcher.exec({
166 toString() {
167 return "etaoin";
168 },
169 });
170 assertEquals([...result], ["etaoin", "e"]);
171 assertSpyCalls(constraint, 1);
172 assertStrictEquals(constraint.calls[0].args[0], "etaoin");
173 assertEquals([...constraint.calls[0].args[1]], ["etaoin", "e"]);
174 assertStrictEquals(constraint.calls[0].args[2], matcher);
175 assertStrictEquals(constraint.calls[0].self, undefined);
176 });
177
178 it("[[Call]] does not call the constraint if the match fails", () => {
179 const constraint = spy((_) => true);
180 const matcher = new Matcher("", undefined, constraint);
181 matcher.exec("failure");
182 assertSpyCalls(constraint, 0);
183 });
184
185 it("[[Call]] returns null given a partial match", () => {
186 assertStrictEquals(new Matcher("").exec("failure"), null);
187 });
188
189 it("[[Call]] returns null if the constraint fails", () => {
190 assertStrictEquals(
191 new Matcher(".*", undefined, () => false).exec(""),
192 null,
193 );
194 });
195
196 describe(".length", () => {
197 it("[[Get]] returns the correct length", () => {
198 assertStrictEquals(Matcher.prototype.exec.length, 1);
199 });
200 });
201
202 describe(".name", () => {
203 it("[[Get]] returns the correct name", () => {
204 assertStrictEquals(Matcher.prototype.exec.name, "exec");
205 });
206 });
207 });
208
209 describe("::global", () => {
210 it("[[Get]] returns true when the global flag is present", () => {
211 assertStrictEquals(new Matcher(/(?:)/gu).global, true);
212 });
213
214 it("[[Get]] returns false when the global flag is not present", () => {
215 assertStrictEquals(new Matcher(/(?:)/u).global, false);
216 });
217
218 describe(".length", () => {
219 it("[[Get]] returns the correct length", () => {
220 assertStrictEquals(
221 Object.getOwnPropertyDescriptor(
222 Matcher.prototype,
223 "global",
224 ).get.length,
225 0,
226 );
227 });
228 });
229
230 describe(".name", () => {
231 it("[[Get]] returns the correct name", () => {
232 assertStrictEquals(
233 Object.getOwnPropertyDescriptor(
234 Matcher.prototype,
235 "global",
236 ).get.name,
237 "get global",
238 );
239 });
240 });
241 });
242
243 describe("::hasIndices", () => {
244 it("[[Get]] returns true when the hasIndices flag is present", () => {
245 assertStrictEquals(new Matcher(/(?:)/du).hasIndices, true);
246 });
247
248 it("[[Get]] returns false when the hasIndices flag is not present", () => {
249 assertStrictEquals(new Matcher(/(?:)/u).hasIndices, false);
250 });
251
252 describe(".length", () => {
253 it("[[Get]] returns the correct length", () => {
254 assertStrictEquals(
255 Object.getOwnPropertyDescriptor(
256 Matcher.prototype,
257 "hasIndices",
258 ).get.length,
259 0,
260 );
261 });
262 });
263
264 describe(".name", () => {
265 it("[[Get]] returns the correct name", () => {
266 assertStrictEquals(
267 Object.getOwnPropertyDescriptor(
268 Matcher.prototype,
269 "hasIndices",
270 ).get.name,
271 "get hasIndices",
272 );
273 });
274 });
275 });
276
277 describe("::ignoreCase", () => {
278 it("[[Get]] returns true when the ignoreCase flag is present", () => {
279 assertStrictEquals(new Matcher(/(?:)/iu).ignoreCase, true);
280 });
281
282 it("[[Get]] returns false when the ignoreCase flag is not present", () => {
283 assertStrictEquals(new Matcher(/(?:)/u).ignoreCase, false);
284 });
285
286 describe(".length", () => {
287 it("[[Get]] returns the correct length", () => {
288 assertStrictEquals(
289 Object.getOwnPropertyDescriptor(
290 Matcher.prototype,
291 "ignoreCase",
292 ).get.length,
293 0,
294 );
295 });
296 });
297
298 describe(".name", () => {
299 it("[[Get]] returns the correct name", () => {
300 assertStrictEquals(
301 Object.getOwnPropertyDescriptor(
302 Matcher.prototype,
303 "ignoreCase",
304 ).get.name,
305 "get ignoreCase",
306 );
307 });
308 });
309 });
310
311 describe("::multiline", () => {
312 it("[[Get]] returns true when the multiline flag is present", () => {
313 assertStrictEquals(new Matcher(/(?:)/mu).multiline, true);
314 });
315
316 it("[[Get]] returns false when the multiline flag is not present", () => {
317 assertStrictEquals(new Matcher(/(?:)/u).multiline, false);
318 });
319
320 describe(".length", () => {
321 it("[[Get]] returns the correct length", () => {
322 assertStrictEquals(
323 Object.getOwnPropertyDescriptor(
324 Matcher.prototype,
325 "multiline",
326 ).get.length,
327 0,
328 );
329 });
330 });
331
332 describe(".name", () => {
333 it("[[Get]] returns the correct name", () => {
334 assertStrictEquals(
335 Object.getOwnPropertyDescriptor(
336 Matcher.prototype,
337 "multiline",
338 ).get.name,
339 "get multiline",
340 );
341 });
342 });
343 });
344
345 describe("::source", () => {
346 it("[[Get]] returns the RegExp source", () => {
347 assertStrictEquals(new Matcher("").source, "(?:)");
348 assertStrictEquals(new Matcher(/.*/su).source, ".*");
349 });
350
351 describe(".length", () => {
352 it("[[Get]] returns the correct length", () => {
353 assertStrictEquals(
354 Object.getOwnPropertyDescriptor(
355 Matcher.prototype,
356 "source",
357 ).get.length,
358 0,
359 );
360 });
361 });
362
363 describe(".name", () => {
364 it("[[Get]] returns the correct name", () => {
365 assertStrictEquals(
366 Object.getOwnPropertyDescriptor(
367 Matcher.prototype,
368 "source",
369 ).get.name,
370 "get source",
371 );
372 });
373 });
374 });
375
376 describe("::sticky", () => {
377 it("[[Get]] returns true when the sticky flag is present", () => {
378 assertStrictEquals(new Matcher(/(?:)/uy).sticky, true);
379 });
380
381 it("[[Get]] returns false when the sticky flag is not present", () => {
382 assertStrictEquals(new Matcher(/(?:)/u).sticky, false);
383 });
384
385 describe(".length", () => {
386 it("[[Get]] returns the correct length", () => {
387 assertStrictEquals(
388 Object.getOwnPropertyDescriptor(
389 Matcher.prototype,
390 "sticky",
391 ).get.length,
392 0,
393 );
394 });
395 });
396
397 describe(".name", () => {
398 it("[[Get]] returns the correct name", () => {
399 assertStrictEquals(
400 Object.getOwnPropertyDescriptor(
401 Matcher.prototype,
402 "sticky",
403 ).get.name,
404 "get sticky",
405 );
406 });
407 });
408 });
409
410 describe("::toString", () => {
411 it("[[Call]] returns the string source", () => {
412 assertStrictEquals(new Matcher(/(?:)/u).toString(), "/(?:)/u");
413 });
414 });
415
416 describe("::unicode", () => {
417 it("[[Get]] returns true when the unicode flag is present", () => {
418 assertStrictEquals(new Matcher(/(?:)/u).unicode, true);
419 });
420
421 describe(".length", () => {
422 it("[[Get]] returns the correct length", () => {
423 assertStrictEquals(
424 Object.getOwnPropertyDescriptor(
425 Matcher.prototype,
426 "unicode",
427 ).get.length,
428 0,
429 );
430 });
431 });
432
433 describe(".name", () => {
434 it("[[Get]] returns the correct name", () => {
435 assertStrictEquals(
436 Object.getOwnPropertyDescriptor(
437 Matcher.prototype,
438 "unicode",
439 ).get.name,
440 "get unicode",
441 );
442 });
443 });
444 });
445
446 describe("~", () => {
447 it("[[Call]] returns true for a complete match", () => {
448 assertStrictEquals(new Matcher("")(""), true);
449 assertStrictEquals(new Matcher(/.*/su)("success\nyay"), true);
450 assertStrictEquals(
451 new Matcher(/.*/su, undefined, ($) => $ === "success")(
452 "success",
453 ),
454 true,
455 );
456 });
457
458 it("[[Call]] calls the constraint if the match succeeds", () => {
459 const constraint = spy((_) => true);
460 const matcher = new Matcher("(.).*", undefined, constraint);
461 matcher("etaoin");
462 assertSpyCalls(constraint, 1);
463 assertStrictEquals(constraint.calls[0].args[0], "etaoin");
464 assertEquals([...constraint.calls[0].args[1]], ["etaoin", "e"]);
465 assertStrictEquals(constraint.calls[0].args[2], matcher);
466 assertStrictEquals(constraint.calls[0].self, undefined);
467 });
468
469 it("[[Call]] does not call the constraint if the match fails", () => {
470 const constraint = spy((_) => true);
471 const matcher = new Matcher("", undefined, constraint);
472 matcher("failure");
473 assertSpyCalls(constraint, 0);
474 });
475
476 it("[[Call]] returns false for a partial match", () => {
477 assertStrictEquals(new Matcher("")("failure"), false);
478 assertStrictEquals(new Matcher(/.*/u)("failure\nno"), false);
479 });
480
481 it("[[Call]] returns false if the constraint fails", () => {
482 assertStrictEquals(
483 new Matcher(".*", undefined, () => false)(""),
484 false,
485 );
486 });
487 });
488
489 describe("~lastIndex", () => {
490 it("[[Get]] returns zero", () => {
491 assertStrictEquals(new Matcher("").lastIndex, 0);
492 });
493
494 it("[[Set]] fails", () => {
495 assertThrows(() => (new Matcher("").lastIndex = 1));
496 });
497 });
498
499 describe("~length", () => {
500 it("[[Get]] returns one", () => {
501 assertStrictEquals(new Matcher("").length, 1);
502 });
503 });
504
505 describe("~name", () => {
506 it("[[Get]] wraps the stringified regular expression if no name was provided", () => {
507 assertStrictEquals(new Matcher("").name, "Matcher(/(?:)/u)");
508 assertStrictEquals(
509 new Matcher(/.*/gsu).name,
510 "Matcher(/.*/gsu)",
511 );
512 });
513
514 it("[[Get]] uses the provided name if one was provided", () => {
515 assertStrictEquals(new Matcher("", "success").name, "success");
516 });
517 });
518 });
519
520 describe("asciiLowercase", () => {
521 it("[[Call]] lowercases (just) A·S·C·I·I letters", () => {
522 assertStrictEquals(asciiLowercase("aBſÆss FtɁɂß"), "abſÆss ftɁɂß");
523 });
524
525 it("[[Construct]] throws an error", () => {
526 assertThrows(() => new asciiLowercase(""));
527 });
528
529 describe(".length", () => {
530 it("[[Get]] returns the correct length", () => {
531 assertStrictEquals(asciiLowercase.length, 1);
532 });
533 });
534
535 describe(".name", () => {
536 it("[[Get]] returns the correct name", () => {
537 assertStrictEquals(asciiLowercase.name, "asciiLowercase");
538 });
539 });
540 });
541
542 describe("asciiUppercase", () => {
543 it("[[Call]] uppercases (just) A·S·C·I·I letters", () => {
544 assertStrictEquals(asciiUppercase("aBſÆss FtɁɂß"), "ABſÆSS FTɁɂß");
545 });
546
547 it("[[Construct]] throws an error", () => {
548 assertThrows(() => new asciiUppercase(""));
549 });
550
551 describe(".length", () => {
552 it("[[Get]] returns the correct length", () => {
553 assertStrictEquals(asciiUppercase.length, 1);
554 });
555 });
556
557 describe(".name", () => {
558 it("[[Get]] returns the correct name", () => {
559 assertStrictEquals(asciiUppercase.name, "asciiUppercase");
560 });
561 });
562 });
563
564 describe("canonicalNumericIndexString", () => {
565 it("[[Call]] returns undefined for nonstrings", () => {
566 assertStrictEquals(canonicalNumericIndexString(1), void {});
567 });
568
569 it("[[Call]] returns undefined for noncanonical strings", () => {
570 assertStrictEquals(canonicalNumericIndexString(""), void {});
571 assertStrictEquals(canonicalNumericIndexString("01"), void {});
572 assertStrictEquals(
573 canonicalNumericIndexString("9007199254740993"),
574 void {},
575 );
576 });
577
578 it('[[Call]] returns -0 for "-0"', () => {
579 assertStrictEquals(canonicalNumericIndexString("-0"), -0);
580 });
581
582 it("[[Call]] returns the corresponding number for canonical strings", () => {
583 assertStrictEquals(canonicalNumericIndexString("0"), 0);
584 assertStrictEquals(canonicalNumericIndexString("-0.25"), -0.25);
585 assertStrictEquals(
586 canonicalNumericIndexString("9007199254740992"),
587 9007199254740992,
588 );
589 assertStrictEquals(canonicalNumericIndexString("NaN"), 0 / 0);
590 assertStrictEquals(canonicalNumericIndexString("Infinity"), 1 / 0);
591 assertStrictEquals(
592 canonicalNumericIndexString("-Infinity"),
593 -1 / 0,
594 );
595 });
596
597 it("[[Construct]] throws an error", () => {
598 assertThrows(() => new canonicalNumericIndexString(""));
599 });
600
601 describe(".length", () => {
602 it("[[Get]] returns the correct length", () => {
603 assertStrictEquals(canonicalNumericIndexString.length, 1);
604 });
605 });
606
607 describe(".name", () => {
608 it("[[Get]] returns the correct name", () => {
609 assertStrictEquals(
610 canonicalNumericIndexString.name,
611 "canonicalNumericIndexString",
612 );
613 });
614 });
615 });
616
617 describe("characters", () => {
618 it("[[Call]] returns an iterable", () => {
619 assertStrictEquals(
620 typeof characters("")[Symbol.iterator],
621 "function",
622 );
623 });
624
625 it("[[Call]] returns an iterator", () => {
626 assertStrictEquals(typeof characters("").next, "function");
627 });
628
629 it("[[Call]] returns a string character iterator", () => {
630 assertStrictEquals(
631 characters("")[Symbol.toStringTag],
632 "String Character Iterator",
633 );
634 });
635
636 it("[[Call]] iterates over the characters", () => {
637 assertEquals([
638 ...characters("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
639 ], [
640 "I",
641 "i",
642 "🎙",
643 "\uDFFF",
644 "\uDD96",
645 "\uD83C",
646 "\uD800",
647 "🆗",
648 "☺",
649 ]);
650 });
651
652 it("[[Construct]] throws an error", () => {
653 assertThrows(() => new characters(""));
654 });
655
656 describe(".length", () => {
657 it("[[Get]] returns the correct length", () => {
658 assertStrictEquals(characters.length, 1);
659 });
660 });
661
662 describe(".name", () => {
663 it("[[Get]] returns the correct name", () => {
664 assertStrictEquals(characters.name, "characters");
665 });
666 });
667 });
668
669 describe("codeUnits", () => {
670 it("[[Call]] returns an iterable", () => {
671 assertStrictEquals(
672 typeof codeUnits("")[Symbol.iterator],
673 "function",
674 );
675 });
676
677 it("[[Call]] returns an iterator", () => {
678 assertStrictEquals(typeof codeUnits("").next, "function");
679 });
680
681 it("[[Call]] returns a string code unit iterator", () => {
682 assertStrictEquals(
683 codeUnits("")[Symbol.toStringTag],
684 "String Code Unit Iterator",
685 );
686 });
687
688 it("[[Call]] iterates over the code units", () => {
689 assertEquals([
690 ...codeUnits("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
691 ], [
692 0x49,
693 0x69,
694 0xD83C,
695 0xDF99,
696 0xDFFF,
697 0xDD96,
698 0xD83C,
699 0xD800,
700 0xD83C,
701 0xDD97,
702 0x263A,
703 ]);
704 });
705
706 it("[[Construct]] throws an error", () => {
707 assertThrows(() => new codeUnits(""));
708 });
709
710 describe(".length", () => {
711 it("[[Get]] returns the correct length", () => {
712 assertStrictEquals(codeUnits.length, 1);
713 });
714 });
715
716 describe(".name", () => {
717 it("[[Get]] returns the correct name", () => {
718 assertStrictEquals(codeUnits.name, "codeUnits");
719 });
720 });
721 });
722
723 describe("codepoints", () => {
724 it("[[Call]] returns an iterable", () => {
725 assertStrictEquals(
726 typeof codepoints("")[Symbol.iterator],
727 "function",
728 );
729 });
730
731 it("[[Call]] returns an iterator", () => {
732 assertStrictEquals(typeof codepoints("").next, "function");
733 });
734
735 it("[[Call]] returns a string codepoint iterator", () => {
736 assertStrictEquals(
737 codepoints("")[Symbol.toStringTag],
738 "String Codepoint Iterator",
739 );
740 });
741
742 it("[[Call]] iterates over the codepoints", () => {
743 assertEquals([
744 ...codepoints("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
745 ], [
746 0x49,
747 0x69,
748 0x1F399,
749 0xDFFF,
750 0xDD96,
751 0xD83C,
752 0xD800,
753 0x1F197,
754 0x263A,
755 ]);
756 });
757
758 it("[[Construct]] throws an error", () => {
759 assertThrows(() => new codepoints(""));
760 });
761
762 describe(".length", () => {
763 it("[[Get]] returns the correct length", () => {
764 assertStrictEquals(codepoints.length, 1);
765 });
766 });
767
768 describe(".name", () => {
769 it("[[Get]] returns the correct name", () => {
770 assertStrictEquals(codepoints.name, "codepoints");
771 });
772 });
773 });
774
775 describe("getCharacter", () => {
776 it("[[Call]] returns the character at the provided position", () => {
777 assertStrictEquals(getCharacter("Ii🎙🆗☺", 4), "🆗");
778 });
779
780 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
781 assertStrictEquals(getCharacter("Ii🎙🆗☺", 5), "\uDD97");
782 });
783
784 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
785 assertStrictEquals(getCharacter("Ii🎙🆗☺", -1), undefined);
786 assertStrictEquals(getCharacter("Ii🎙🆗☺", 7), undefined);
787 });
788
789 it("[[Construct]] throws an error", () => {
790 assertThrows(() => new getCharacter("a", 0));
791 });
792
793 describe(".length", () => {
794 it("[[Get]] returns the correct length", () => {
795 assertStrictEquals(getCharacter.length, 2);
796 });
797 });
798
799 describe(".name", () => {
800 it("[[Get]] returns the correct name", () => {
801 assertStrictEquals(getCharacter.name, "getCharacter");
802 });
803 });
804 });
805
806 describe("getCodeUnit", () => {
807 it("[[Call]] returns the code unit at the provided position", () => {
808 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 4), 0xD83C);
809 });
810
811 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
812 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 5), 0xDD97);
813 });
814
815 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
816 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", -1), undefined);
817 assertStrictEquals(getCodeUnit("Ii🎙🆗☺", 7), undefined);
818 });
819
820 it("[[Construct]] throws an error", () => {
821 assertThrows(() => new getCodeUnit("a", 0));
822 });
823
824 describe(".length", () => {
825 it("[[Get]] returns the correct length", () => {
826 assertStrictEquals(getCodeUnit.length, 2);
827 });
828 });
829
830 describe(".name", () => {
831 it("[[Get]] returns the correct name", () => {
832 assertStrictEquals(getCodeUnit.name, "getCodeUnit");
833 });
834 });
835 });
836
837 describe("getCodepoint", () => {
838 it("[[Call]] returns the character at the provided position", () => {
839 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 4), 0x1F197);
840 });
841
842 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
843 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 5), 0xDD97);
844 });
845
846 it("[[Call]] returns undefined for an out‐of‐bounds index", () => {
847 assertStrictEquals(getCodepoint("Ii🎙🆗☺", -1), undefined);
848 assertStrictEquals(getCodepoint("Ii🎙🆗☺", 7), undefined);
849 });
850
851 it("[[Construct]] throws an error", () => {
852 assertThrows(() => new getCodepoint("a", 0));
853 });
854
855 describe(".length", () => {
856 it("[[Get]] returns the correct length", () => {
857 assertStrictEquals(getCodepoint.length, 2);
858 });
859 });
860
861 describe(".name", () => {
862 it("[[Get]] returns the correct name", () => {
863 assertStrictEquals(getCodepoint.name, "getCodepoint");
864 });
865 });
866 });
867
868 describe("getFirstSubstringIndex", () => {
869 it("[[Call]] returns the index of the first match", () => {
870 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 4);
871 });
872
873 it("[[Call]] returns −1 if no match is found", () => {
874 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", "🆗🆖"), -1);
875 });
876
877 it("[[Call]] returns 0 when provided with an empty string", () => {
878 assertStrictEquals(getFirstSubstringIndex("Ii🎙🆗☺🆗", ""), 0);
879 });
880
881 it("[[Construct]] throws an error", () => {
882 assertThrows(() => new getFirstSubstringIndex("", ""));
883 });
884
885 describe(".length", () => {
886 it("[[Get]] returns the correct length", () => {
887 assertStrictEquals(getFirstSubstringIndex.length, 2);
888 });
889 });
890
891 describe(".name", () => {
892 it("[[Get]] returns the correct name", () => {
893 assertStrictEquals(
894 getFirstSubstringIndex.name,
895 "getFirstSubstringIndex",
896 );
897 });
898 });
899 });
900
901 describe("getLastSubstringIndex", () => {
902 it("[[Call]] returns the index of the first match", () => {
903 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆗"), 7);
904 });
905
906 it("[[Call]] returns −1 if no match is found", () => {
907 assertStrictEquals(getLastSubstringIndex("Ii🎙🆗☺🆗", "🆖🆗"), -1);
908 });
909
910 it("[[Call]] returns the length when provided with an empty string", () => {
911 assertStrictEquals(
912 getLastSubstringIndex("Ii🎙🆗☺🆗", ""),
913 "Ii🎙🆗☺🆗".length,
914 );
915 });
916
917 it("[[Construct]] throws an error", () => {
918 assertThrows(() => new getLastSubstringIndex("", ""));
919 });
920
921 describe(".length", () => {
922 it("[[Get]] returns the correct length", () => {
923 assertStrictEquals(getLastSubstringIndex.length, 2);
924 });
925 });
926
927 describe(".name", () => {
928 it("[[Get]] returns the correct name", () => {
929 assertStrictEquals(
930 getLastSubstringIndex.name,
931 "getLastSubstringIndex",
932 );
933 });
934 });
935 });
936
937 describe("isIntegerIndexString", () => {
938 it("[[Call]] returns false for nonstrings", () => {
939 assertStrictEquals(isIntegerIndexString(1), false);
940 });
941
942 it("[[Call]] returns false for noncanonical strings", () => {
943 assertStrictEquals(isIntegerIndexString(""), false);
944 assertStrictEquals(isIntegerIndexString("01"), false);
945 assertStrictEquals(
946 isIntegerIndexString("9007199254740993"),
947 false,
948 );
949 });
950
951 it("[[Call]] returns false for nonfinite numbers", () => {
952 assertStrictEquals(isIntegerIndexString("NaN"), false);
953 assertStrictEquals(isIntegerIndexString("Infinity"), false);
954 assertStrictEquals(isIntegerIndexString("-Infinity"), false);
955 });
956
957 it("[[Call]] returns false for negative numbers", () => {
958 assertStrictEquals(isIntegerIndexString("-0"), false);
959 assertStrictEquals(isIntegerIndexString("-1"), false);
960 });
961
962 it("[[Call]] returns false for nonintegers", () => {
963 assertStrictEquals(isIntegerIndexString("0.25"), false);
964 assertStrictEquals(isIntegerIndexString("1.1"), false);
965 });
966
967 it("[[Call]] returns false for numbers greater than or equal to 2 ** 53", () => {
968 assertStrictEquals(
969 isIntegerIndexString("9007199254740992"),
970 false,
971 );
972 });
973
974 it("[[Call]] returns true for safe canonical integer strings", () => {
975 assertStrictEquals(isIntegerIndexString("0"), true);
976 assertStrictEquals(isIntegerIndexString("9007199254740991"), true);
977 });
978 });
979
980 describe("join", () => {
981 it("[[Call]] joins the provided iterator with the provided separartor", () => {
982 assertStrictEquals(join([1, 2, 3, 4].values(), "☂"), "1☂2☂3☂4");
983 });
984
985 it('[[Call]] uses "," if no separator is provided', () => {
986 assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
987 });
988
989 it("[[Call]] uses the empty sting for nullish values", () => {
990 assertStrictEquals(
991 join([null, , null, undefined].values(), "☂"),
992 "☂☂☂",
993 );
994 });
995
996 it("[[Construct]] throws an error", () => {
997 assertThrows(() => new join([]));
998 });
999
1000 describe(".length", () => {
1001 it("[[Get]] returns the correct length", () => {
1002 assertStrictEquals(join.length, 2);
1003 });
1004 });
1005
1006 describe(".name", () => {
1007 it("[[Get]] returns the correct name", () => {
1008 assertStrictEquals(join.name, "join");
1009 });
1010 });
1011 });
1012
1013 describe("rawString", () => {
1014 it("[[Call]] acts like String.raw", () => {
1015 assertStrictEquals(rawString`\nraw${" string"}`, "\\nraw string");
1016 });
1017
1018 it("[[Construct]] throws an error", () => {
1019 assertThrows(() => new rawString(["string"]));
1020 });
1021
1022 describe(".length", () => {
1023 it("[[Get]] returns the correct length", () => {
1024 assertStrictEquals(rawString.length, 1);
1025 });
1026 });
1027
1028 describe(".name", () => {
1029 it("[[Get]] returns the correct name", () => {
1030 assertStrictEquals(rawString.name, "rawString");
1031 });
1032 });
1033 });
1034
1035 describe("scalarValues", () => {
1036 it("[[Call]] returns an iterable", () => {
1037 assertStrictEquals(
1038 typeof scalarValues("")[Symbol.iterator],
1039 "function",
1040 );
1041 });
1042
1043 it("[[Call]] returns an iterator", () => {
1044 assertStrictEquals(typeof scalarValues("").next, "function");
1045 });
1046
1047 it("[[Call]] returns a string scalar value iterator", () => {
1048 assertStrictEquals(
1049 scalarValues("")[Symbol.toStringTag],
1050 "String Scalar Value Iterator",
1051 );
1052 });
1053
1054 it("[[Call]] iterates over the scalar values", () => {
1055 assertEquals([
1056 ...scalarValues("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
1057 ], [
1058 0x49,
1059 0x69,
1060 0x1F399,
1061 0xFFFD,
1062 0xFFFD,
1063 0xFFFD,
1064 0xFFFD,
1065 0x1F197,
1066 0x263A,
1067 ]);
1068 });
1069
1070 it("[[Construct]] throws an error", () => {
1071 assertThrows(() => new scalarValues(""));
1072 });
1073
1074 describe(".length", () => {
1075 it("[[Get]] returns the correct length", () => {
1076 assertStrictEquals(scalarValues.length, 1);
1077 });
1078 });
1079
1080 describe(".name", () => {
1081 it("[[Get]] returns the correct name", () => {
1082 assertStrictEquals(scalarValues.name, "scalarValues");
1083 });
1084 });
1085 });
1086
1087 describe("splitOnAsciiWhitespace", () => {
1088 it("[[Call]] splits on sequences of spaces", () => {
1089 assertEquals(
1090 splitOnAsciiWhitespace("🅰️ 🅱️ 🆎 🅾️"),
1091 ["🅰️", "🅱️", "🆎", "🅾️"],
1092 );
1093 });
1094
1095 it("[[Call]] splits on sequences of tabs", () => {
1096 assertEquals(
1097 splitOnAsciiWhitespace("🅰️\t\t\t🅱️\t🆎\t\t🅾️"),
1098 ["🅰️", "🅱️", "🆎", "🅾️"],
1099 );
1100 });
1101
1102 it("[[Call]] splits on sequences of carriage returns", () => {
1103 assertEquals(
1104 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1105 ["🅰️", "🅱️", "🆎", "🅾️"],
1106 );
1107 });
1108
1109 it("[[Call]] splits on sequences of newlines", () => {
1110 assertEquals(
1111 splitOnAsciiWhitespace("🅰️\r\r\r🅱️\r🆎\r\r🅾️"),
1112 ["🅰️", "🅱️", "🆎", "🅾️"],
1113 );
1114 });
1115
1116 it("[[Call]] splits on sequences of form feeds", () => {
1117 assertEquals(
1118 splitOnAsciiWhitespace("🅰️\f\f\f🅱️\f🆎\f\f🅾️"),
1119 ["🅰️", "🅱️", "🆎", "🅾️"],
1120 );
1121 });
1122
1123 it("[[Call]] splits on mixed whitespace", () => {
1124 assertEquals(
1125 splitOnAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
1126 ["🅰️", "🅱️", "🆎", "🅾️"],
1127 );
1128 });
1129
1130 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1131 assertEquals(splitOnAsciiWhitespace(""), [""]);
1132 });
1133
1134 it("[[Call]] returns a single token if there are no spaces", () => {
1135 assertEquals(splitOnAsciiWhitespace("abcd"), ["abcd"]);
1136 });
1137
1138 it("[[Call]] does not split on other kinds of whitespace", () => {
1139 assertEquals(
1140 splitOnAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
1141 ["a\u202F\u205F\xa0\v\0\bb"],
1142 );
1143 });
1144
1145 it("[[Call]] trims leading and trailing whitespace", () => {
1146 assertEquals(
1147 splitOnAsciiWhitespace(
1148 "\f\r\n\r\n \n\t🅰️\f \t\n🅱️\r🆎\n\f🅾️\n\f",
1149 ),
1150 ["🅰️", "🅱️", "🆎", "🅾️"],
1151 );
1152 });
1153
1154 it("[[Construct]] throws an error", () => {
1155 assertThrows(() => new splitOnAsciiWhitespace(""));
1156 });
1157
1158 describe(".length", () => {
1159 it("[[Get]] returns the correct length", () => {
1160 assertStrictEquals(splitOnAsciiWhitespace.length, 1);
1161 });
1162 });
1163
1164 describe(".name", () => {
1165 it("[[Get]] returns the correct name", () => {
1166 assertStrictEquals(
1167 splitOnAsciiWhitespace.name,
1168 "splitOnAsciiWhitespace",
1169 );
1170 });
1171 });
1172 });
1173
1174 describe("splitOnCommas", () => {
1175 it("[[Call]] splits on commas", () => {
1176 assertEquals(
1177 splitOnCommas("🅰️,🅱️,🆎,🅾️"),
1178 ["🅰️", "🅱️", "🆎", "🅾️"],
1179 );
1180 });
1181
1182 it("[[Call]] returns an array of just the empty string for the empty string", () => {
1183 assertEquals(splitOnCommas(""), [""]);
1184 });
1185
1186 it("[[Call]] returns a single token if there are no commas", () => {
1187 assertEquals(splitOnCommas("abcd"), ["abcd"]);
1188 });
1189
1190 it("[[Call]] splits into empty strings if there are only commas", () => {
1191 assertEquals(splitOnCommas(",,,"), ["", "", "", ""]);
1192 });
1193
1194 it("[[Call]] trims leading and trailing whitespace", () => {
1195 assertEquals(
1196 splitOnCommas("\f\r\n\r\n \n\t🅰️,🅱️,🆎,🅾️\n\f"),
1197 ["🅰️", "🅱️", "🆎", "🅾️"],
1198 );
1199 assertEquals(
1200 splitOnCommas("\f\r\n\r\n \n\t,,,\n\f"),
1201 ["", "", "", ""],
1202 );
1203 });
1204
1205 it("[[Call]] removes whitespace from the split tokens", () => {
1206 assertEquals(
1207 splitOnCommas(
1208 "\f\r\n\r\n \n\t🅰️\f , \t\n🅱️,\r\n\r🆎\n\f,🅾️\n\f",
1209 ),
1210 ["🅰️", "🅱️", "🆎", "🅾️"],
1211 );
1212 assertEquals(
1213 splitOnCommas("\f\r\n\r\n \n\t\f , \t\n,\r\n\r\n\f,\n\f"),
1214 ["", "", "", ""],
1215 );
1216 });
1217
1218 it("[[Construct]] throws an error", () => {
1219 assertThrows(() => new splitOnCommas(""));
1220 });
1221
1222 describe(".length", () => {
1223 it("[[Get]] returns the correct length", () => {
1224 assertStrictEquals(splitOnCommas.length, 1);
1225 });
1226 });
1227
1228 describe(".name", () => {
1229 it("[[Get]] returns the correct name", () => {
1230 assertStrictEquals(splitOnCommas.name, "splitOnCommas");
1231 });
1232 });
1233 });
1234
1235 describe("stringCatenate", () => {
1236 it("[[Call]] catenates the values", () => {
1237 assertStrictEquals(stringCatenate("the", " values"), "the values");
1238 });
1239
1240 it("[[Call]] returns an empty string when called with no values", () => {
1241 assertStrictEquals(stringCatenate(), "");
1242 });
1243
1244 it('[[Call]] uses "undefined" when explicitly provided undefined', () => {
1245 assertStrictEquals(
1246 stringCatenate(undefined, undefined),
1247 "undefinedundefined",
1248 );
1249 });
1250
1251 it('[[Call]] uses "null" when provided null', () => {
1252 assertStrictEquals(stringCatenate(null, null), "nullnull");
1253 });
1254
1255 it("[[Construct]] throws an error", () => {
1256 assertThrows(() => new stringCatenate());
1257 });
1258
1259 describe(".length", () => {
1260 it("[[Get]] returns the correct length", () => {
1261 assertStrictEquals(stringCatenate.length, 2);
1262 });
1263 });
1264
1265 describe(".name", () => {
1266 it("[[Get]] returns the correct name", () => {
1267 assertStrictEquals(stringCatenate.name, "stringCatenate");
1268 });
1269 });
1270 });
1271
1272 describe("stringEndsWith", () => {
1273 it("[[Call]] returns whether the string ends with the thing", () => {
1274 assertStrictEquals(
1275 stringEndsWith("very success", " success"),
1276 true,
1277 );
1278 assertStrictEquals(stringEndsWith("very fail", " success"), false);
1279 });
1280
1281 it("[[Call]] accepts an offset", () => {
1282 assertStrictEquals(
1283 stringEndsWith("very successful", " success", 12),
1284 true,
1285 );
1286 });
1287
1288 it("[[Call]] returns true for an empty string test", () => {
1289 assertStrictEquals(stringEndsWith("", ""), true);
1290 });
1291
1292 it("[[Construct]] throws an error", () => {
1293 assertThrows(() => new stringEndsWith("", ""));
1294 });
1295
1296 describe(".length", () => {
1297 it("[[Get]] returns the correct length", () => {
1298 assertStrictEquals(stringEndsWith.length, 2);
1299 });
1300 });
1301
1302 describe(".name", () => {
1303 it("[[Get]] returns the correct name", () => {
1304 assertStrictEquals(stringEndsWith.name, "stringEndsWith");
1305 });
1306 });
1307 });
1308
1309 describe("stringFromCodeUnits", () => {
1310 it("[[Call]] makes the string", () => {
1311 assertStrictEquals(
1312 stringFromCodeUnits(0xD83C, 0xDD97),
1313 "🆗",
1314 );
1315 });
1316
1317 it("[[Call]] throws with non‐integral arguments", () => {
1318 assertThrows(() => stringFromCodeUnits(NaN));
1319 assertThrows(() => stringFromCodeUnits(Infinity));
1320 assertThrows(() => stringFromCodeUnits(0.1));
1321 });
1322
1323 it("[[Call]] throws with arguments out of range", () => {
1324 assertThrows(() => stringFromCodeUnits(-1));
1325 assertThrows(() => stringFromCodeUnits(0x10000));
1326 });
1327
1328 it("[[Construct]] throws an error", () => {
1329 assertThrows(() => new stringFromCodeUnits([]));
1330 });
1331
1332 describe(".length", () => {
1333 it("[[Get]] returns the correct length", () => {
1334 assertStrictEquals(stringFromCodeUnits.length, 1);
1335 });
1336 });
1337
1338 describe(".name", () => {
1339 it("[[Get]] returns the correct name", () => {
1340 assertStrictEquals(
1341 stringFromCodeUnits.name,
1342 "stringFromCodeUnits",
1343 );
1344 });
1345 });
1346 });
1347
1348 describe("stringFromCodepoints", () => {
1349 it("[[Call]] makes the string", () => {
1350 assertStrictEquals(stringFromCodepoints(0x1F197), "🆗");
1351 });
1352
1353 it("[[Call]] throws with non‐integral arguments", () => {
1354 assertThrows(() => stringFromCodepoints(NaN));
1355 assertThrows(() => stringFromCodepoints(Infinity));
1356 assertThrows(() => stringFromCodepoints(0.1));
1357 });
1358
1359 it("[[Call]] throws with arguments out of range", () => {
1360 assertThrows(() => stringFromCodepoints(-1));
1361 assertThrows(() => stringFromCodepoints(0x110000));
1362 });
1363
1364 it("[[Construct]] throws an error", () => {
1365 assertThrows(() => new stringFromCodepoints([]));
1366 });
1367
1368 describe(".length", () => {
1369 it("[[Get]] returns the correct length", () => {
1370 assertStrictEquals(stringFromCodepoints.length, 1);
1371 });
1372 });
1373
1374 describe(".name", () => {
1375 it("[[Get]] returns the correct name", () => {
1376 assertStrictEquals(
1377 stringFromCodepoints.name,
1378 "stringFromCodepoints",
1379 );
1380 });
1381 });
1382 });
1383
1384 describe("stringIncludes", () => {
1385 it("[[Call]] returns whether the string includes the thing", () => {
1386 assertStrictEquals(
1387 stringIncludes("very success full", " success "),
1388 true,
1389 );
1390 assertStrictEquals(
1391 stringIncludes("very fail full", " success "),
1392 false,
1393 );
1394 });
1395
1396 it("[[Call]] accepts an offset", () => {
1397 assertStrictEquals(
1398 stringIncludes("maybe success full", " success ", 4),
1399 true,
1400 );
1401 assertStrictEquals(
1402 stringIncludes("maybe success full", " success ", 5),
1403 true,
1404 );
1405 assertStrictEquals(
1406 stringIncludes("maybe success full", " success ", 6),
1407 false,
1408 );
1409 });
1410
1411 it("[[Call]] returns true for an empty string test", () => {
1412 assertStrictEquals(stringIncludes("", ""), true);
1413 });
1414
1415 it("[[Construct]] throws an error", () => {
1416 assertThrows(() => new stringIncludes("", ""));
1417 });
1418
1419 describe(".length", () => {
1420 it("[[Get]] returns the correct length", () => {
1421 assertStrictEquals(stringIncludes.length, 2);
1422 });
1423 });
1424
1425 describe(".name", () => {
1426 it("[[Get]] returns the correct name", () => {
1427 assertStrictEquals(stringIncludes.name, "stringIncludes");
1428 });
1429 });
1430 });
1431
1432 describe("stringMatch", () => {
1433 it("[[Call]] does the match akin to String::match", () => {
1434 assertEquals(
1435 [...stringMatch("very success full", /([sc]+[ue]?)+/)],
1436 ["success", "ss"],
1437 );
1438 assertEquals(
1439 [...stringMatch("very success full", /([sc]+)[ue]?/g)],
1440 ["su", "cce", "ss"],
1441 );
1442 });
1443
1444 it("[[Construct]] throws an error", () => {
1445 assertThrows(() => new stringMatch("", /(?:)/));
1446 });
1447
1448 describe(".length", () => {
1449 it("[[Get]] returns the correct length", () => {
1450 assertStrictEquals(stringMatch.length, 2);
1451 });
1452 });
1453
1454 describe(".name", () => {
1455 it("[[Get]] returns the correct name", () => {
1456 assertStrictEquals(stringMatch.name, "stringMatch");
1457 });
1458 });
1459 });
1460
1461 describe("stringMatchAll", () => {
1462 it("[[Call]] does the match akin to String::matchAll", () => {
1463 assertEquals(
1464 [...stringMatchAll("very success full", /([sc]+)[ue]?/g)].map((
1465 match,
1466 ) => [...match]),
1467 [["su", "s"], ["cce", "cc"], ["ss", "ss"]],
1468 );
1469 });
1470
1471 it("[[Construct]] throws an error", () => {
1472 assertThrows(() => new stringMatchAll("", /(?:)/g));
1473 });
1474
1475 describe(".length", () => {
1476 it("[[Get]] returns the correct length", () => {
1477 assertStrictEquals(stringMatchAll.length, 2);
1478 });
1479 });
1480
1481 describe(".name", () => {
1482 it("[[Get]] returns the correct name", () => {
1483 assertStrictEquals(stringMatchAll.name, "stringMatchAll");
1484 });
1485 });
1486 });
1487
1488 describe("stringNormalize", () => {
1489 it("[[Call]] normalizes the string properly", () => {
1490 assertStrictEquals(stringNormalize("ẛ", "NFC"), "\u1E9B");
1491 assertStrictEquals(stringNormalize("ẛ", "NFD"), "\u017F\u0307");
1492 assertStrictEquals(stringNormalize("ẛ", "NFKC"), "\u1E61");
1493 assertStrictEquals(stringNormalize("ẛ", "NFKD"), "\u0073\u0307");
1494 });
1495
1496 it("[[Call]] assumes NFC", () => {
1497 assertStrictEquals(stringNormalize("\u017F\u0307"), "\u1E9B");
1498 });
1499
1500 it("[[Call]] throws with an invalid form", () => {
1501 assertThrows(() => stringNormalize("", "NFB"));
1502 });
1503
1504 it("[[Construct]] throws an error", () => {
1505 assertThrows(() => new stringNormalize("", "NFC"));
1506 });
1507
1508 describe(".length", () => {
1509 it("[[Get]] returns the correct length", () => {
1510 assertStrictEquals(stringNormalize.length, 1);
1511 });
1512 });
1513
1514 describe(".name", () => {
1515 it("[[Get]] returns the correct name", () => {
1516 assertStrictEquals(stringNormalize.name, "stringNormalize");
1517 });
1518 });
1519 });
1520
1521 describe("stringPadEnd", () => {
1522 it("[[Call]] pads the end of the string", () => {
1523 assertStrictEquals(stringPadEnd("xx", 3), "xx ");
1524 assertStrictEquals(stringPadEnd("xx", 3, "o"), "xxo");
1525 assertStrictEquals(stringPadEnd("", 3, "xo"), "xox");
1526 assertStrictEquals(stringPadEnd("xx", 3, ""), "xx");
1527 });
1528
1529 it("[[Construct]] throws an error", () => {
1530 assertThrows(() => new stringPadEnd("", 1));
1531 });
1532
1533 describe(".length", () => {
1534 it("[[Get]] returns the correct length", () => {
1535 assertStrictEquals(stringPadEnd.length, 2);
1536 });
1537 });
1538
1539 describe(".name", () => {
1540 it("[[Get]] returns the correct name", () => {
1541 assertStrictEquals(stringPadEnd.name, "stringPadEnd");
1542 });
1543 });
1544 });
1545
1546 describe("stringPadStart", () => {
1547 it("[[Call]] pads the start of the string", () => {
1548 assertStrictEquals(stringPadStart("xx", 3), " xx");
1549 assertStrictEquals(stringPadStart("xx", 3, "o"), "oxx");
1550 assertStrictEquals(stringPadStart("", 3, "xo"), "xox");
1551 assertStrictEquals(stringPadStart("xx", 3, ""), "xx");
1552 });
1553
1554 it("[[Construct]] throws an error", () => {
1555 assertThrows(() => new stringPadStart("", 1));
1556 });
1557
1558 describe(".length", () => {
1559 it("[[Get]] returns the correct length", () => {
1560 assertStrictEquals(stringPadStart.length, 2);
1561 });
1562 });
1563
1564 describe(".name", () => {
1565 it("[[Get]] returns the correct name", () => {
1566 assertStrictEquals(stringPadStart.name, "stringPadStart");
1567 });
1568 });
1569 });
1570
1571 describe("stringRepeat", () => {
1572 it("[[Call]] repeats the string", () => {
1573 assertStrictEquals(stringRepeat("xx", 3), "xxxxxx");
1574 assertStrictEquals(stringRepeat("", 3), "");
1575 assertStrictEquals(stringRepeat("xx", 0), "");
1576 });
1577
1578 it("[[Call]] throws for negative repititions", () => {
1579 assertThrows(() => stringRepeat("", -1));
1580 });
1581
1582 it("[[Call]] throws for infinite repititions", () => {
1583 assertThrows(() => stringRepeat("", Infinity));
1584 });
1585
1586 it("[[Construct]] throws an error", () => {
1587 assertThrows(() => new stringRepeat("", 1));
1588 });
1589
1590 describe(".length", () => {
1591 it("[[Get]] returns the correct length", () => {
1592 assertStrictEquals(stringRepeat.length, 2);
1593 });
1594 });
1595
1596 describe(".name", () => {
1597 it("[[Get]] returns the correct name", () => {
1598 assertStrictEquals(stringRepeat.name, "stringRepeat");
1599 });
1600 });
1601 });
1602
1603 describe("stringReplace", () => {
1604 it("[[Call]] does the replacement akin to String::replace", () => {
1605 assertStrictEquals(
1606 stringReplace("it’s a failure", "failure", "success"),
1607 "it’s a success",
1608 );
1609 assertStrictEquals(
1610 stringReplace(
1611 "very success full",
1612 /([sc]+)[ue]?/,
1613 ($) => $.length,
1614 ),
1615 "very 2ccess full",
1616 );
1617 assertStrictEquals(
1618 stringReplace(
1619 "very success full",
1620 /([sc]+)[ue]?/g,
1621 (...$s) =>
1622 `${$s[0].length}`.repeat($s[1].length) +
1623 $s[0].substring($s[1].length),
1624 ),
1625 "very 2u33e22 full",
1626 );
1627 });
1628
1629 it("[[Construct]] throws an error", () => {
1630 assertThrows(() => new stringReplace("", /(?:)/, ""));
1631 });
1632
1633 describe(".length", () => {
1634 it("[[Get]] returns the correct length", () => {
1635 assertStrictEquals(stringReplace.length, 3);
1636 });
1637 });
1638
1639 describe(".name", () => {
1640 it("[[Get]] returns the correct name", () => {
1641 assertStrictEquals(stringReplace.name, "stringReplace");
1642 });
1643 });
1644 });
1645
1646 describe("stringReplaceAll", () => {
1647 it("[[Call]] does the match akin to String::replaceAll", () => {
1648 assertStrictEquals(
1649 stringReplaceAll("it’s a failure failure", "failure", "success"),
1650 "it’s a success success",
1651 );
1652 assertStrictEquals(
1653 stringReplaceAll(
1654 "very success full",
1655 /([sc]+)[ue]?/g,
1656 (...$s) =>
1657 `${$s[0].length}`.repeat($s[1].length) +
1658 $s[0].substring($s[1].length),
1659 ),
1660 "very 2u33e22 full",
1661 );
1662 });
1663
1664 it("[[Construct]] throws an error", () => {
1665 assertThrows(() => new stringReplaceAll("", /(?:)/g));
1666 });
1667
1668 describe(".length", () => {
1669 it("[[Get]] returns the correct length", () => {
1670 assertStrictEquals(stringReplaceAll.length, 3);
1671 });
1672 });
1673
1674 describe(".name", () => {
1675 it("[[Get]] returns the correct name", () => {
1676 assertStrictEquals(stringReplaceAll.name, "stringReplaceAll");
1677 });
1678 });
1679 });
1680
1681 describe("stringSearch", () => {
1682 it("[[Call]] does the search akin to String::search", () => {
1683 assertStrictEquals(
1684 stringSearch("very success full", /([sc]+)[ue]?/),
1685 5,
1686 );
1687 assertStrictEquals(
1688 stringSearch("very fail full", /([sc]+)[ue]?/),
1689 -1,
1690 );
1691 });
1692
1693 it("[[Construct]] throws an error", () => {
1694 assertThrows(() => new stringSearch("", /(?:)/));
1695 });
1696
1697 describe(".length", () => {
1698 it("[[Get]] returns the correct length", () => {
1699 assertStrictEquals(stringSearch.length, 2);
1700 });
1701 });
1702
1703 describe(".name", () => {
1704 it("[[Get]] returns the correct name", () => {
1705 assertStrictEquals(stringSearch.name, "stringSearch");
1706 });
1707 });
1708 });
1709
1710 describe("stringSlice", () => {
1711 it("[[Call]] slices the string akin to String::search", () => {
1712 assertStrictEquals(
1713 stringSlice("very success full", 5, 12),
1714 "success",
1715 );
1716 assertStrictEquals(
1717 stringSlice("very success full", -12, -5),
1718 "success",
1719 );
1720 });
1721
1722 it("[[Construct]] throws an error", () => {
1723 assertThrows(() => new stringSlice("", 0, 0));
1724 });
1725
1726 describe(".length", () => {
1727 it("[[Get]] returns the correct length", () => {
1728 assertStrictEquals(stringSlice.length, 3);
1729 });
1730 });
1731
1732 describe(".name", () => {
1733 it("[[Get]] returns the correct name", () => {
1734 assertStrictEquals(stringSlice.name, "stringSlice");
1735 });
1736 });
1737 });
1738
1739 describe("stringSplit", () => {
1740 it("[[Call]] splits the string akin to String::split", () => {
1741 assertEquals(stringSplit("success", ""), [
1742 "s",
1743 "u",
1744 "c",
1745 "c",
1746 "e",
1747 "s",
1748 "s",
1749 ]);
1750 assertEquals(stringSplit("success", /(?<=[aeiou])(?=[^aeiou])/), [
1751 "su",
1752 "cce",
1753 "ss",
1754 ]);
1755 assertEquals(stringSplit("success", "failure"), ["success"]);
1756 });
1757
1758 it("[[Call]] recognizes a limit", () => {
1759 assertEquals(stringSplit("success", "", 4), ["s", "u", "c", "c"]);
1760 });
1761
1762 it("[[Construct]] throws an error", () => {
1763 assertThrows(() => new stringSplit("", ""));
1764 });
1765
1766 describe(".length", () => {
1767 it("[[Get]] returns the correct length", () => {
1768 assertStrictEquals(stringSplit.length, 3);
1769 });
1770 });
1771
1772 describe(".name", () => {
1773 it("[[Get]] returns the correct name", () => {
1774 assertStrictEquals(stringSplit.name, "stringSplit");
1775 });
1776 });
1777 });
1778
1779 describe("stringStartsWith", () => {
1780 it("[[Call]] returns whether the string starts with the thing", () => {
1781 assertStrictEquals(
1782 stringStartsWith("success is had", "success "),
1783 true,
1784 );
1785 assertStrictEquals(
1786 stringStartsWith("no success is had", "success "),
1787 false,
1788 );
1789 });
1790
1791 it("[[Call]] accepts an offset", () => {
1792 assertStrictEquals(
1793 stringStartsWith("much success is had", "success ", 5),
1794 true,
1795 );
1796 });
1797
1798 it("[[Call]] returns true for an empty string test", () => {
1799 assertStrictEquals(stringEndsWith("", ""), true);
1800 });
1801
1802 it("[[Construct]] throws an error", () => {
1803 assertThrows(() => new stringStartsWith("", ""));
1804 });
1805
1806 describe(".length", () => {
1807 it("[[Get]] returns the correct length", () => {
1808 assertStrictEquals(stringStartsWith.length, 2);
1809 });
1810 });
1811
1812 describe(".name", () => {
1813 it("[[Get]] returns the correct name", () => {
1814 assertStrictEquals(stringStartsWith.name, "stringStartsWith");
1815 });
1816 });
1817 });
1818
1819 describe("stringStartsWith", () => {
1820 it("[[Call]] returns the string value of a string literal", () => {
1821 assertStrictEquals(stringValue("success"), "success");
1822 });
1823
1824 it("[[Call]] returns the string value of a string object", () => {
1825 const string = new String("success");
1826 Object.defineProperties(string, {
1827 toString: { value: () => "failure" },
1828 valueOf: { value: () => "failure" },
1829 });
1830 assertStrictEquals(stringValue(string), "success");
1831 });
1832
1833 it("[[Call]] throws for non‐strings", () => {
1834 assertThrows(() => stringValue(Object.create(String.prototype)));
1835 });
1836
1837 it("[[Construct]] throws an error", () => {
1838 assertThrows(() => new stringValue(""));
1839 });
1840
1841 describe(".length", () => {
1842 it("[[Get]] returns the correct length", () => {
1843 assertStrictEquals(stringValue.length, 1);
1844 });
1845 });
1846
1847 describe(".name", () => {
1848 it("[[Get]] returns the correct name", () => {
1849 assertStrictEquals(stringValue.name, "stringValue");
1850 });
1851 });
1852 });
1853
1854 describe("stripAndCollapseAsciiWhitespace", () => {
1855 it("[[Call]] collapses mixed inner whitespace", () => {
1856 assertEquals(
1857 stripAndCollapseAsciiWhitespace("🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️"),
1858 "🅰️ 🅱️ 🆎 🅾️",
1859 );
1860 });
1861
1862 it("[[Call]] trims leading and trailing whitespace", () => {
1863 assertStrictEquals(
1864 stripAndCollapseAsciiWhitespace(
1865 "\f\r\n\r\n \n\t\f 🅰️\f \t\n🅱️\r\n\r🆎\n\f🅾️\n\f",
1866 ),
1867 "🅰️ 🅱️ 🆎 🅾️",
1868 );
1869 });
1870
1871 it("[[Call]] returns the empty string for strings of whitespace", () => {
1872 assertStrictEquals(
1873 stripAndCollapseAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
1874 "",
1875 );
1876 });
1877
1878 it("[[Call]] does not collapse other kinds of whitespace", () => {
1879 assertEquals(
1880 stripAndCollapseAsciiWhitespace("a\u202F\u205F\xa0\v\0\bb"),
1881 "a\u202F\u205F\xa0\v\0\bb",
1882 );
1883 });
1884
1885 it("[[Construct]] throws an error", () => {
1886 assertThrows(() => new stripAndCollapseAsciiWhitespace(""));
1887 });
1888
1889 describe(".length", () => {
1890 it("[[Get]] returns the correct length", () => {
1891 assertStrictEquals(stripAndCollapseAsciiWhitespace.length, 1);
1892 });
1893 });
1894
1895 describe(".name", () => {
1896 it("[[Get]] returns the correct name", () => {
1897 assertStrictEquals(
1898 stripAndCollapseAsciiWhitespace.name,
1899 "stripAndCollapseAsciiWhitespace",
1900 );
1901 });
1902 });
1903 });
1904
1905 describe("stripLeadingAndTrailingAsciiWhitespace", () => {
1906 it("[[Call]] trims leading and trailing whitespace", () => {
1907 assertStrictEquals(
1908 stripLeadingAndTrailingAsciiWhitespace(
1909 "\f\r\n\r\n \n\t\f 🅰️🅱️🆎🅾️\n\f",
1910 ),
1911 "🅰️🅱️🆎🅾️",
1912 );
1913 });
1914
1915 it("[[Call]] returns the empty string for strings of whitespace", () => {
1916 assertStrictEquals(
1917 stripLeadingAndTrailingAsciiWhitespace("\f\r\n\r\n \n\t\f \n\f"),
1918 "",
1919 );
1920 });
1921
1922 it("[[Call]] does not trim other kinds of whitespace", () => {
1923 assertEquals(
1924 stripLeadingAndTrailingAsciiWhitespace(
1925 "\v\u202F\u205Fx\0\b\xa0",
1926 ),
1927 "\v\u202F\u205Fx\0\b\xa0",
1928 );
1929 });
1930
1931 it("[[Call]] does not adjust inner whitespace", () => {
1932 assertEquals(
1933 stripLeadingAndTrailingAsciiWhitespace("a b"),
1934 "a b",
1935 );
1936 });
1937
1938 it("[[Construct]] throws an error", () => {
1939 assertThrows(() => new stripLeadingAndTrailingAsciiWhitespace(""));
1940 });
1941
1942 describe(".length", () => {
1943 it("[[Get]] returns the correct length", () => {
1944 assertStrictEquals(
1945 stripLeadingAndTrailingAsciiWhitespace.length,
1946 1,
1947 );
1948 });
1949 });
1950
1951 describe(".name", () => {
1952 it("[[Get]] returns the correct name", () => {
1953 assertStrictEquals(
1954 stripLeadingAndTrailingAsciiWhitespace.name,
1955 "stripLeadingAndTrailingAsciiWhitespace",
1956 );
1957 });
1958 });
1959 });
1960
1961 describe("substring", () => {
1962 it("[[Call]] returns the substring", () => {
1963 assertStrictEquals(
1964 substring("success", 0),
1965 "success",
1966 );
1967 assertStrictEquals(
1968 substring("very success full", 5, 12),
1969 "success",
1970 );
1971 });
1972
1973 it("[[Construct]] throws an error", () => {
1974 assertThrows(() => new substring("", 0));
1975 });
1976
1977 describe(".length", () => {
1978 it("[[Get]] returns the correct length", () => {
1979 assertStrictEquals(substring.length, 3);
1980 });
1981 });
1982
1983 describe(".name", () => {
1984 it("[[Get]] returns the correct name", () => {
1985 assertStrictEquals(substring.name, "substring");
1986 });
1987 });
1988 });
1989
1990 describe("toScalarValueString", () => {
1991 it("[[Call]] replaces invalid values", () => {
1992 assertStrictEquals(
1993 toScalarValueString("Ii🎙\uDFFF\uDD96\uD83C\uD800🆗☺"),
1994 "Ii🎙\uFFFD\uFFFD\uFFFD\uFFFD🆗☺",
1995 );
1996 });
1997
1998 it("[[Construct]] throws an error", () => {
1999 assertThrows(() => new toScalarValueString(""));
2000 });
2001
2002 describe(".length", () => {
2003 it("[[Get]] returns the correct length", () => {
2004 assertStrictEquals(toScalarValueString.length, 1);
2005 });
2006 });
2007
2008 describe(".name", () => {
2009 it("[[Get]] returns the correct name", () => {
2010 assertStrictEquals(
2011 toScalarValueString.name,
2012 "toScalarValueString",
2013 );
2014 });
2015 });
2016 });
2017
2018 describe("toString", () => {
2019 it("[[Call]] converts to a string", () => {
2020 assertStrictEquals(
2021 toString({
2022 toString() {
2023 return "success";
2024 },
2025 }),
2026 "success",
2027 );
2028 });
2029
2030 it("[[Call]] throws when provided a symbol", () => {
2031 assertThrows(() => toString(Symbol()));
2032 });
2033
2034 it("[[Construct]] throws an error", () => {
2035 assertThrows(() => new toString(""));
2036 });
2037
2038 describe(".length", () => {
2039 it("[[Get]] returns the correct length", () => {
2040 assertStrictEquals(toString.length, 1);
2041 });
2042 });
2043
2044 describe(".name", () => {
2045 it("[[Get]] returns the correct name", () => {
2046 assertStrictEquals(toString.name, "toString");
2047 });
2048 });
2049 });
This page took 0.359008 seconds and 5 git commands to generate.