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