UNPKG

68 kBJavaScriptView Raw
1var __assign = (this && this.__assign) || function () {
2 __assign = Object.assign || function(t) {
3 for (var s, i = 1, n = arguments.length; i < n; i++) {
4 s = arguments[i];
5 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6 t[p] = s[p];
7 }
8 return t;
9 };
10 return __assign.apply(this, arguments);
11};
12import * as util from "util";
13import * as pathToRegexp from "./index";
14/**
15 * An array of test cases with expected inputs and outputs.
16 */
17var TESTS = [
18 /**
19 * Simple paths.
20 */
21 [
22 "/",
23 undefined,
24 ["/"],
25 [
26 ["/", ["/"], { path: "/", index: 0, params: {} }],
27 ["/route", null, false]
28 ],
29 [
30 [null, "/"],
31 [{}, "/"],
32 [{ id: 123 }, "/"]
33 ]
34 ],
35 [
36 "/test",
37 undefined,
38 ["/test"],
39 [
40 ["/test", ["/test"], { path: "/test", index: 0, params: {} }],
41 ["/route", null, false],
42 ["/test/route", null, false],
43 ["/test/", ["/test/"], { path: "/test/", index: 0, params: {} }]
44 ],
45 [
46 [null, "/test"],
47 [{}, "/test"]
48 ]
49 ],
50 [
51 "/test/",
52 undefined,
53 ["/test/"],
54 [
55 ["/test", null],
56 ["/test/", ["/test/"]],
57 ["/test//", ["/test//"]]
58 ],
59 [[null, "/test/"]]
60 ],
61 /**
62 * Case-sensitive paths.
63 */
64 [
65 "/test",
66 {
67 sensitive: true
68 },
69 ["/test"],
70 [
71 ["/test", ["/test"]],
72 ["/TEST", null]
73 ],
74 [[null, "/test"]]
75 ],
76 [
77 "/TEST",
78 {
79 sensitive: true
80 },
81 ["/TEST"],
82 [
83 ["/test", null],
84 ["/TEST", ["/TEST"]]
85 ],
86 [[null, "/TEST"]]
87 ],
88 /**
89 * Strict mode.
90 */
91 [
92 "/test",
93 {
94 strict: true
95 },
96 ["/test"],
97 [
98 ["/test", ["/test"]],
99 ["/test/", null],
100 ["/TEST", ["/TEST"]]
101 ],
102 [[null, "/test"]]
103 ],
104 [
105 "/test/",
106 {
107 strict: true
108 },
109 ["/test/"],
110 [
111 ["/test", null],
112 ["/test/", ["/test/"]],
113 ["/test//", null]
114 ],
115 [[null, "/test/"]]
116 ],
117 /**
118 * Non-ending mode.
119 */
120 [
121 "/test",
122 {
123 end: false
124 },
125 ["/test"],
126 [
127 ["/test", ["/test"]],
128 ["/test/", ["/test/"]],
129 ["/test/route", ["/test"]],
130 ["/route", null]
131 ],
132 [[null, "/test"]]
133 ],
134 [
135 "/test/",
136 {
137 end: false
138 },
139 ["/test/"],
140 [
141 ["/test", null],
142 ["/test/route", ["/test/"]],
143 ["/test//", ["/test//"]],
144 ["/test//route", ["/test/"]]
145 ],
146 [[null, "/test/"]]
147 ],
148 [
149 "/:test",
150 {
151 end: false
152 },
153 [
154 {
155 name: "test",
156 prefix: "/",
157 suffix: "",
158 modifier: "",
159 pattern: "[^\\/#\\?]+?"
160 }
161 ],
162 [
163 [
164 "/route",
165 ["/route", "route"],
166 { path: "/route", index: 0, params: { test: "route" } }
167 ],
168 [
169 "/caf%C3%A9",
170 ["/caf%C3%A9", "caf%C3%A9"],
171 { path: "/caf%C3%A9", index: 0, params: { test: "caf%C3%A9" } }
172 ],
173 [
174 "/caf%C3%A9",
175 ["/caf%C3%A9", "caf%C3%A9"],
176 { path: "/caf%C3%A9", index: 0, params: { test: "café" } },
177 { decode: decodeURIComponent }
178 ]
179 ],
180 [
181 [{}, null],
182 [{ test: "abc" }, "/abc"],
183 [{ test: "a+b" }, "/a+b"],
184 [{ test: "a+b" }, "/test", { encode: function (_, token) { return String(token.name); } }],
185 [{ test: "a+b" }, "/a%2Bb", { encode: encodeURIComponent }]
186 ]
187 ],
188 [
189 "/:test/",
190 {
191 end: false
192 },
193 [
194 {
195 name: "test",
196 prefix: "/",
197 suffix: "",
198 modifier: "",
199 pattern: "[^\\/#\\?]+?"
200 },
201 "/"
202 ],
203 [
204 ["/route", null],
205 ["/route/", ["/route/", "route"]]
206 ],
207 [[{ test: "abc" }, "/abc/"]]
208 ],
209 [
210 "",
211 {
212 end: false
213 },
214 [],
215 [
216 ["", [""]],
217 ["/", ["/"]],
218 ["route", [""]],
219 ["/route", [""]],
220 ["/route/", [""]]
221 ],
222 [[null, ""]]
223 ],
224 /**
225 * Non-starting mode.
226 */
227 [
228 "/test",
229 {
230 start: false
231 },
232 ["/test"],
233 [
234 ["/test", ["/test"]],
235 ["/test/", ["/test/"]],
236 ["/route/test", ["/test"]],
237 ["/test/route", null],
238 ["/route/test/deep", null],
239 ["/route", null]
240 ],
241 [[null, "/test"]]
242 ],
243 [
244 "/test/",
245 {
246 start: false
247 },
248 ["/test/"],
249 [
250 ["/test", null],
251 ["/test/route", null],
252 ["/test//route", null],
253 ["/test//", ["/test//"]],
254 ["/route/test/", ["/test/"]]
255 ],
256 [[null, "/test/"]]
257 ],
258 [
259 "/:test",
260 {
261 start: false
262 },
263 [
264 {
265 name: "test",
266 prefix: "/",
267 suffix: "",
268 modifier: "",
269 pattern: "[^\\/#\\?]+?"
270 }
271 ],
272 [["/route", ["/route", "route"]]],
273 [
274 [{}, null],
275 [{ test: "abc" }, "/abc"],
276 [{ test: "a+b" }, "/a+b"],
277 [{ test: "a+b" }, "/test", { encode: function (_, token) { return String(token.name); } }],
278 [{ test: "a+b" }, "/a%2Bb", { encode: encodeURIComponent }]
279 ]
280 ],
281 [
282 "/:test/",
283 {
284 start: false
285 },
286 [
287 {
288 name: "test",
289 prefix: "/",
290 suffix: "",
291 modifier: "",
292 pattern: "[^\\/#\\?]+?"
293 },
294 "/"
295 ],
296 [
297 ["/route", null],
298 ["/route/", ["/route/", "route"]]
299 ],
300 [[{ test: "abc" }, "/abc/"]]
301 ],
302 [
303 "",
304 {
305 start: false
306 },
307 [],
308 [
309 ["", [""]],
310 ["/", ["/"]],
311 ["route", [""]],
312 ["/route", [""]],
313 ["/route/", ["/"]]
314 ],
315 [[null, ""]]
316 ],
317 /**
318 * Combine modes.
319 */
320 [
321 "/test",
322 {
323 end: false,
324 strict: true
325 },
326 ["/test"],
327 [
328 ["/test", ["/test"]],
329 ["/test/", ["/test"]],
330 ["/test/route", ["/test"]]
331 ],
332 [[null, "/test"]]
333 ],
334 [
335 "/test/",
336 {
337 end: false,
338 strict: true
339 },
340 ["/test/"],
341 [
342 ["/test", null],
343 ["/test/", ["/test/"]],
344 ["/test//", ["/test/"]],
345 ["/test/route", ["/test/"]]
346 ],
347 [[null, "/test/"]]
348 ],
349 [
350 "/test.json",
351 {
352 end: false,
353 strict: true
354 },
355 ["/test.json"],
356 [
357 ["/test.json", ["/test.json"]],
358 ["/test.json.hbs", null],
359 ["/test.json/route", ["/test.json"]]
360 ],
361 [[null, "/test.json"]]
362 ],
363 [
364 "/:test",
365 {
366 end: false,
367 strict: true
368 },
369 [
370 {
371 name: "test",
372 prefix: "/",
373 suffix: "",
374 modifier: "",
375 pattern: "[^\\/#\\?]+?"
376 }
377 ],
378 [
379 ["/route", ["/route", "route"]],
380 ["/route/", ["/route", "route"]]
381 ],
382 [
383 [{}, null],
384 [{ test: "abc" }, "/abc"]
385 ]
386 ],
387 [
388 "/:test/",
389 {
390 end: false,
391 strict: true
392 },
393 [
394 {
395 name: "test",
396 prefix: "/",
397 suffix: "",
398 modifier: "",
399 pattern: "[^\\/#\\?]+?"
400 },
401 "/"
402 ],
403 [
404 ["/route", null],
405 ["/route/", ["/route/", "route"]]
406 ],
407 [[{ test: "foobar" }, "/foobar/"]]
408 ],
409 [
410 "/test",
411 {
412 start: false,
413 end: false
414 },
415 ["/test"],
416 [
417 ["/test", ["/test"]],
418 ["/test/", ["/test/"]],
419 ["/test/route", ["/test"]],
420 ["/route/test/deep", ["/test"]]
421 ],
422 [[null, "/test"]]
423 ],
424 [
425 "/test/",
426 {
427 start: false,
428 end: false
429 },
430 ["/test/"],
431 [
432 ["/test", null],
433 ["/test/", ["/test/"]],
434 ["/test//", ["/test//"]],
435 ["/test/route", ["/test/"]],
436 ["/route/test/deep", ["/test/"]]
437 ],
438 [[null, "/test/"]]
439 ],
440 [
441 "/test.json",
442 {
443 start: false,
444 end: false
445 },
446 ["/test.json"],
447 [
448 ["/test.json", ["/test.json"]],
449 ["/test.json.hbs", null],
450 ["/test.json/route", ["/test.json"]],
451 ["/route/test.json/deep", ["/test.json"]]
452 ],
453 [[null, "/test.json"]]
454 ],
455 [
456 "/:test",
457 {
458 start: false,
459 end: false
460 },
461 [
462 {
463 name: "test",
464 prefix: "/",
465 suffix: "",
466 modifier: "",
467 pattern: "[^\\/#\\?]+?"
468 }
469 ],
470 [
471 ["/route", ["/route", "route"]],
472 ["/route/", ["/route/", "route"]]
473 ],
474 [
475 [{}, null],
476 [{ test: "abc" }, "/abc"]
477 ]
478 ],
479 [
480 "/:test/",
481 {
482 end: false,
483 strict: true
484 },
485 [
486 {
487 name: "test",
488 prefix: "/",
489 suffix: "",
490 modifier: "",
491 pattern: "[^\\/#\\?]+?"
492 },
493 "/"
494 ],
495 [
496 ["/route", null],
497 ["/route/", ["/route/", "route"]]
498 ],
499 [[{ test: "foobar" }, "/foobar/"]]
500 ],
501 /**
502 * Arrays of simple paths.
503 */
504 [
505 ["/one", "/two"],
506 undefined,
507 [],
508 [
509 ["/one", ["/one"]],
510 ["/two", ["/two"]],
511 ["/three", null],
512 ["/one/two", null]
513 ],
514 []
515 ],
516 /**
517 * Non-ending simple path.
518 */
519 [
520 "/test",
521 {
522 end: false
523 },
524 ["/test"],
525 [["/test/route", ["/test"]]],
526 [[null, "/test"]]
527 ],
528 /**
529 * Single named parameter.
530 */
531 [
532 "/:test",
533 undefined,
534 [
535 {
536 name: "test",
537 prefix: "/",
538 suffix: "",
539 modifier: "",
540 pattern: "[^\\/#\\?]+?"
541 }
542 ],
543 [
544 ["/route", ["/route", "route"]],
545 ["/another", ["/another", "another"]],
546 ["/something/else", null],
547 ["/route.json", ["/route.json", "route.json"]],
548 ["/something%2Felse", ["/something%2Felse", "something%2Felse"]],
549 [
550 "/something%2Felse%2Fmore",
551 ["/something%2Felse%2Fmore", "something%2Felse%2Fmore"]
552 ],
553 ["/;,:@&=+$-_.!~*()", ["/;,:@&=+$-_.!~*()", ";,:@&=+$-_.!~*()"]]
554 ],
555 [
556 [{ test: "route" }, "/route"],
557 [
558 { test: "something/else" },
559 "/something%2Felse",
560 { encode: encodeURIComponent }
561 ],
562 [
563 { test: "something/else/more" },
564 "/something%2Felse%2Fmore",
565 { encode: encodeURIComponent }
566 ]
567 ]
568 ],
569 [
570 "/:test",
571 {
572 strict: true
573 },
574 [
575 {
576 name: "test",
577 prefix: "/",
578 suffix: "",
579 modifier: "",
580 pattern: "[^\\/#\\?]+?"
581 }
582 ],
583 [
584 ["/route", ["/route", "route"]],
585 ["/route/", null]
586 ],
587 [[{ test: "route" }, "/route"]]
588 ],
589 [
590 "/:test/",
591 {
592 strict: true
593 },
594 [
595 {
596 name: "test",
597 prefix: "/",
598 suffix: "",
599 modifier: "",
600 pattern: "[^\\/#\\?]+?"
601 },
602 "/"
603 ],
604 [
605 ["/route/", ["/route/", "route"]],
606 ["/route//", null]
607 ],
608 [[{ test: "route" }, "/route/"]]
609 ],
610 [
611 "/:test",
612 {
613 end: false
614 },
615 [
616 {
617 name: "test",
618 prefix: "/",
619 suffix: "",
620 modifier: "",
621 pattern: "[^\\/#\\?]+?"
622 }
623 ],
624 [
625 ["/route.json", ["/route.json", "route.json"]],
626 ["/route//", ["/route", "route"]]
627 ],
628 [[{ test: "route" }, "/route"]]
629 ],
630 /**
631 * Optional named parameter.
632 */
633 [
634 "/:test?",
635 undefined,
636 [
637 {
638 name: "test",
639 prefix: "/",
640 suffix: "",
641 modifier: "?",
642 pattern: "[^\\/#\\?]+?"
643 }
644 ],
645 [
646 [
647 "/route",
648 ["/route", "route"],
649 { path: "/route", index: 0, params: { test: "route" } }
650 ],
651 ["/route/nested", null, false],
652 ["/", ["/", undefined], { path: "/", index: 0, params: {} }],
653 ["//", null]
654 ],
655 [
656 [null, ""],
657 [{ test: "foobar" }, "/foobar"]
658 ]
659 ],
660 [
661 "/:test?",
662 {
663 strict: true
664 },
665 [
666 {
667 name: "test",
668 prefix: "/",
669 suffix: "",
670 modifier: "?",
671 pattern: "[^\\/#\\?]+?"
672 }
673 ],
674 [
675 ["/route", ["/route", "route"]],
676 ["/", null],
677 ["//", null]
678 ],
679 [
680 [null, ""],
681 [{ test: "foobar" }, "/foobar"]
682 ]
683 ],
684 [
685 "/:test?/",
686 {
687 strict: true
688 },
689 [
690 {
691 name: "test",
692 prefix: "/",
693 suffix: "",
694 modifier: "?",
695 pattern: "[^\\/#\\?]+?"
696 },
697 "/"
698 ],
699 [
700 ["/route", null],
701 ["/route/", ["/route/", "route"]],
702 ["/", ["/", undefined]],
703 ["//", null]
704 ],
705 [
706 [null, "/"],
707 [{ test: "foobar" }, "/foobar/"]
708 ]
709 ],
710 [
711 "/:test?/bar",
712 undefined,
713 [
714 {
715 name: "test",
716 prefix: "/",
717 suffix: "",
718 modifier: "?",
719 pattern: "[^\\/#\\?]+?"
720 },
721 "/bar"
722 ],
723 [
724 ["/bar", ["/bar", undefined]],
725 ["/foo/bar", ["/foo/bar", "foo"]]
726 ],
727 [
728 [null, "/bar"],
729 [{ test: "foo" }, "/foo/bar"]
730 ]
731 ],
732 [
733 "/:test?-bar",
734 undefined,
735 [
736 {
737 name: "test",
738 prefix: "/",
739 suffix: "",
740 modifier: "?",
741 pattern: "[^\\/#\\?]+?"
742 },
743 "-bar"
744 ],
745 [
746 ["-bar", ["-bar", undefined]],
747 ["/-bar", null],
748 ["/foo-bar", ["/foo-bar", "foo"]]
749 ],
750 [
751 [undefined, "-bar"],
752 [{ test: "foo" }, "/foo-bar"]
753 ]
754 ],
755 [
756 "/:test*-bar",
757 undefined,
758 [
759 {
760 name: "test",
761 prefix: "/",
762 suffix: "",
763 modifier: "*",
764 pattern: "[^\\/#\\?]+?"
765 },
766 "-bar"
767 ],
768 [
769 ["-bar", ["-bar", undefined]],
770 ["/-bar", null],
771 ["/foo-bar", ["/foo-bar", "foo"]],
772 ["/foo/baz-bar", ["/foo/baz-bar", "foo/baz"]]
773 ],
774 [[{ test: "foo" }, "/foo-bar"]]
775 ],
776 /**
777 * Repeated one or more times parameters.
778 */
779 [
780 "/:test+",
781 undefined,
782 [
783 {
784 name: "test",
785 prefix: "/",
786 suffix: "",
787 modifier: "+",
788 pattern: "[^\\/#\\?]+?"
789 }
790 ],
791 [
792 ["/", null, false],
793 [
794 "/route",
795 ["/route", "route"],
796 { path: "/route", index: 0, params: { test: ["route"] } }
797 ],
798 [
799 "/some/basic/route",
800 ["/some/basic/route", "some/basic/route"],
801 {
802 path: "/some/basic/route",
803 index: 0,
804 params: { test: ["some", "basic", "route"] }
805 }
806 ],
807 ["//", null, false]
808 ],
809 [
810 [{}, null],
811 [{ test: "foobar" }, "/foobar"],
812 [{ test: ["a", "b", "c"] }, "/a/b/c"]
813 ]
814 ],
815 [
816 "/:test(\\d+)+",
817 undefined,
818 [
819 {
820 name: "test",
821 prefix: "/",
822 suffix: "",
823 modifier: "+",
824 pattern: "\\d+"
825 }
826 ],
827 [
828 ["/abc/456/789", null],
829 ["/123/456/789", ["/123/456/789", "123/456/789"]]
830 ],
831 [
832 [{ test: "abc" }, null],
833 [{ test: 123 }, "/123"],
834 [{ test: [1, 2, 3] }, "/1/2/3"]
835 ]
836 ],
837 [
838 "/route.:ext(json|xml)+",
839 undefined,
840 [
841 "/route",
842 {
843 name: "ext",
844 prefix: ".",
845 suffix: "",
846 modifier: "+",
847 pattern: "json|xml"
848 }
849 ],
850 [
851 ["/route", null],
852 ["/route.json", ["/route.json", "json"]],
853 ["/route.xml.json", ["/route.xml.json", "xml.json"]],
854 ["/route.html", null]
855 ],
856 [
857 [{ ext: "foobar" }, null],
858 [{ ext: "xml" }, "/route.xml"],
859 [{ ext: ["xml", "json"] }, "/route.xml.json"]
860 ]
861 ],
862 [
863 "/route.:ext(\\w+)/test",
864 undefined,
865 [
866 "/route",
867 {
868 name: "ext",
869 prefix: ".",
870 suffix: "",
871 modifier: "",
872 pattern: "\\w+"
873 },
874 "/test"
875 ],
876 [
877 ["/route", null],
878 ["/route.json", null],
879 ["/route.xml/test", ["/route.xml/test", "xml"]],
880 ["/route.json.gz/test", null]
881 ],
882 [[{ ext: "xml" }, "/route.xml/test"]]
883 ],
884 /**
885 * Repeated zero or more times parameters.
886 */
887 [
888 "/:test*",
889 undefined,
890 [
891 {
892 name: "test",
893 prefix: "/",
894 suffix: "",
895 modifier: "*",
896 pattern: "[^\\/#\\?]+?"
897 }
898 ],
899 [
900 ["/", ["/", undefined], { path: "/", index: 0, params: {} }],
901 ["//", null, false],
902 [
903 "/route",
904 ["/route", "route"],
905 { path: "/route", index: 0, params: { test: ["route"] } }
906 ],
907 [
908 "/some/basic/route",
909 ["/some/basic/route", "some/basic/route"],
910 {
911 path: "/some/basic/route",
912 index: 0,
913 params: { test: ["some", "basic", "route"] }
914 }
915 ]
916 ],
917 [
918 [{}, ""],
919 [{ test: [] }, ""],
920 [{ test: "foobar" }, "/foobar"],
921 [{ test: ["foo", "bar"] }, "/foo/bar"]
922 ]
923 ],
924 [
925 "/route.:ext([a-z]+)*",
926 undefined,
927 [
928 "/route",
929 {
930 name: "ext",
931 prefix: ".",
932 suffix: "",
933 modifier: "*",
934 pattern: "[a-z]+"
935 }
936 ],
937 [
938 ["/route", ["/route", undefined]],
939 ["/route.json", ["/route.json", "json"]],
940 ["/route.json.xml", ["/route.json.xml", "json.xml"]],
941 ["/route.123", null]
942 ],
943 [
944 [{}, "/route"],
945 [{ ext: [] }, "/route"],
946 [{ ext: "123" }, null],
947 [{ ext: "foobar" }, "/route.foobar"],
948 [{ ext: ["foo", "bar"] }, "/route.foo.bar"]
949 ]
950 ],
951 /**
952 * Custom named parameters.
953 */
954 [
955 "/:test(\\d+)",
956 undefined,
957 [
958 {
959 name: "test",
960 prefix: "/",
961 suffix: "",
962 modifier: "",
963 pattern: "\\d+"
964 }
965 ],
966 [
967 ["/123", ["/123", "123"]],
968 ["/abc", null],
969 ["/123/abc", null]
970 ],
971 [
972 [{ test: "abc" }, null],
973 [{ test: "abc" }, "/abc", { validate: false }],
974 [{ test: "123" }, "/123"]
975 ]
976 ],
977 [
978 "/:test(\\d+)",
979 {
980 end: false
981 },
982 [
983 {
984 name: "test",
985 prefix: "/",
986 suffix: "",
987 modifier: "",
988 pattern: "\\d+"
989 }
990 ],
991 [
992 ["/123", ["/123", "123"]],
993 ["/abc", null],
994 ["/123/abc", ["/123", "123"]]
995 ],
996 [[{ test: "123" }, "/123"]]
997 ],
998 [
999 "/:test(.*)",
1000 undefined,
1001 [
1002 {
1003 name: "test",
1004 prefix: "/",
1005 suffix: "",
1006 modifier: "",
1007 pattern: ".*"
1008 }
1009 ],
1010 [
1011 ["/anything/goes/here", ["/anything/goes/here", "anything/goes/here"]],
1012 ["/;,:@&=/+$-_.!/~*()", ["/;,:@&=/+$-_.!/~*()", ";,:@&=/+$-_.!/~*()"]]
1013 ],
1014 [
1015 [{ test: "" }, "/"],
1016 [{ test: "abc" }, "/abc"],
1017 [{ test: "abc/123" }, "/abc%2F123", { encode: encodeURIComponent }],
1018 [
1019 { test: "abc/123/456" },
1020 "/abc%2F123%2F456",
1021 { encode: encodeURIComponent }
1022 ]
1023 ]
1024 ],
1025 [
1026 "/:route([a-z]+)",
1027 undefined,
1028 [
1029 {
1030 name: "route",
1031 prefix: "/",
1032 suffix: "",
1033 modifier: "",
1034 pattern: "[a-z]+"
1035 }
1036 ],
1037 [
1038 ["/abcde", ["/abcde", "abcde"]],
1039 ["/12345", null]
1040 ],
1041 [
1042 [{ route: "" }, null],
1043 [{ route: "" }, "/", { validate: false }],
1044 [{ route: "123" }, null],
1045 [{ route: "123" }, "/123", { validate: false }],
1046 [{ route: "abc" }, "/abc"]
1047 ]
1048 ],
1049 [
1050 "/:route(this|that)",
1051 undefined,
1052 [
1053 {
1054 name: "route",
1055 prefix: "/",
1056 suffix: "",
1057 modifier: "",
1058 pattern: "this|that"
1059 }
1060 ],
1061 [
1062 ["/this", ["/this", "this"]],
1063 ["/that", ["/that", "that"]],
1064 ["/foo", null]
1065 ],
1066 [
1067 [{ route: "this" }, "/this"],
1068 [{ route: "foo" }, null],
1069 [{ route: "foo" }, "/foo", { validate: false }],
1070 [{ route: "that" }, "/that"]
1071 ]
1072 ],
1073 [
1074 "/:path(abc|xyz)*",
1075 undefined,
1076 [
1077 {
1078 name: "path",
1079 prefix: "/",
1080 suffix: "",
1081 modifier: "*",
1082 pattern: "abc|xyz"
1083 }
1084 ],
1085 [
1086 ["/abc", ["/abc", "abc"]],
1087 ["/abc/abc", ["/abc/abc", "abc/abc"]],
1088 ["/xyz/xyz", ["/xyz/xyz", "xyz/xyz"]],
1089 ["/abc/xyz", ["/abc/xyz", "abc/xyz"]],
1090 ["/abc/xyz/abc/xyz", ["/abc/xyz/abc/xyz", "abc/xyz/abc/xyz"]],
1091 ["/xyzxyz", null]
1092 ],
1093 [
1094 [{ path: "abc" }, "/abc"],
1095 [{ path: ["abc", "xyz"] }, "/abc/xyz"],
1096 [{ path: ["xyz", "abc", "xyz"] }, "/xyz/abc/xyz"],
1097 [{ path: "abc123" }, null],
1098 [{ path: "abc123" }, "/abc123", { validate: false }],
1099 [{ path: "abcxyz" }, null],
1100 [{ path: "abcxyz" }, "/abcxyz", { validate: false }]
1101 ]
1102 ],
1103 /**
1104 * Prefixed slashes could be omitted.
1105 */
1106 [
1107 "test",
1108 undefined,
1109 ["test"],
1110 [
1111 ["test", ["test"]],
1112 ["/test", null]
1113 ],
1114 [[null, "test"]]
1115 ],
1116 [
1117 ":test",
1118 undefined,
1119 [
1120 {
1121 name: "test",
1122 prefix: "",
1123 suffix: "",
1124 modifier: "",
1125 pattern: "[^\\/#\\?]+?"
1126 }
1127 ],
1128 [
1129 ["route", ["route", "route"]],
1130 ["/route", null],
1131 ["route/", ["route/", "route"]]
1132 ],
1133 [
1134 [{ test: "" }, null],
1135 [{}, null],
1136 [{ test: null }, null],
1137 [{ test: "route" }, "route"]
1138 ]
1139 ],
1140 [
1141 ":test",
1142 {
1143 strict: true
1144 },
1145 [
1146 {
1147 name: "test",
1148 prefix: "",
1149 suffix: "",
1150 modifier: "",
1151 pattern: "[^\\/#\\?]+?"
1152 }
1153 ],
1154 [
1155 ["route", ["route", "route"]],
1156 ["/route", null],
1157 ["route/", null]
1158 ],
1159 [[{ test: "route" }, "route"]]
1160 ],
1161 [
1162 ":test",
1163 {
1164 end: false
1165 },
1166 [
1167 {
1168 name: "test",
1169 prefix: "",
1170 suffix: "",
1171 modifier: "",
1172 pattern: "[^\\/#\\?]+?"
1173 }
1174 ],
1175 [
1176 ["route", ["route", "route"]],
1177 ["/route", null],
1178 ["route/", ["route/", "route"]],
1179 ["route/foobar", ["route", "route"]]
1180 ],
1181 [[{ test: "route" }, "route"]]
1182 ],
1183 [
1184 ":test?",
1185 undefined,
1186 [
1187 {
1188 name: "test",
1189 prefix: "",
1190 suffix: "",
1191 modifier: "?",
1192 pattern: "[^\\/#\\?]+?"
1193 }
1194 ],
1195 [
1196 ["route", ["route", "route"]],
1197 ["/route", null],
1198 ["", ["", undefined]],
1199 ["route/foobar", null]
1200 ],
1201 [
1202 [{}, ""],
1203 [{ test: "" }, null],
1204 [{ test: "route" }, "route"]
1205 ]
1206 ],
1207 [
1208 "{:test/}+",
1209 undefined,
1210 [
1211 {
1212 name: "test",
1213 prefix: "",
1214 suffix: "/",
1215 modifier: "+",
1216 pattern: "[^\\/#\\?]+?"
1217 }
1218 ],
1219 [
1220 ["route/", ["route/", "route"]],
1221 ["/route", null],
1222 ["", null],
1223 ["foo/bar/", ["foo/bar/", "foo/bar"]]
1224 ],
1225 [
1226 [{}, null],
1227 [{ test: "" }, null],
1228 [{ test: ["route"] }, "route/"],
1229 [{ test: ["foo", "bar"] }, "foo/bar/"]
1230 ]
1231 ],
1232 /**
1233 * Formats.
1234 */
1235 [
1236 "/test.json",
1237 undefined,
1238 ["/test.json"],
1239 [
1240 ["/test.json", ["/test.json"]],
1241 ["/route.json", null]
1242 ],
1243 [[{}, "/test.json"]]
1244 ],
1245 [
1246 "/:test.json",
1247 undefined,
1248 [
1249 {
1250 name: "test",
1251 prefix: "/",
1252 suffix: "",
1253 modifier: "",
1254 pattern: "[^\\/#\\?]+?"
1255 },
1256 ".json"
1257 ],
1258 [
1259 ["/.json", null],
1260 ["/test.json", ["/test.json", "test"]],
1261 ["/route.json", ["/route.json", "route"]],
1262 ["/route.json.json", ["/route.json.json", "route.json"]]
1263 ],
1264 [
1265 [{ test: "" }, null],
1266 [{ test: "foo" }, "/foo.json"]
1267 ]
1268 ],
1269 /**
1270 * Format params.
1271 */
1272 [
1273 "/test.:format(\\w+)",
1274 undefined,
1275 [
1276 "/test",
1277 {
1278 name: "format",
1279 prefix: ".",
1280 suffix: "",
1281 modifier: "",
1282 pattern: "\\w+"
1283 }
1284 ],
1285 [
1286 ["/test.html", ["/test.html", "html"]],
1287 ["/test.hbs.html", null]
1288 ],
1289 [
1290 [{}, null],
1291 [{ format: "" }, null],
1292 [{ format: "foo" }, "/test.foo"]
1293 ]
1294 ],
1295 [
1296 "/test.:format(\\w+).:format(\\w+)",
1297 undefined,
1298 [
1299 "/test",
1300 {
1301 name: "format",
1302 prefix: ".",
1303 suffix: "",
1304 modifier: "",
1305 pattern: "\\w+"
1306 },
1307 {
1308 name: "format",
1309 prefix: ".",
1310 suffix: "",
1311 modifier: "",
1312 pattern: "\\w+"
1313 }
1314 ],
1315 [
1316 ["/test.html", null],
1317 ["/test.hbs.html", ["/test.hbs.html", "hbs", "html"]]
1318 ],
1319 [
1320 [{ format: "foo.bar" }, null],
1321 [{ format: "foo" }, "/test.foo.foo"]
1322 ]
1323 ],
1324 [
1325 "/test{.:format}+",
1326 undefined,
1327 [
1328 "/test",
1329 {
1330 name: "format",
1331 prefix: ".",
1332 suffix: "",
1333 modifier: "+",
1334 pattern: "[^\\/#\\?]+?"
1335 }
1336 ],
1337 [
1338 ["/test.html", ["/test.html", "html"]],
1339 ["/test.hbs.html", ["/test.hbs.html", "hbs.html"]]
1340 ],
1341 [
1342 [{ format: [] }, null],
1343 [{ format: "foo" }, "/test.foo"],
1344 [{ format: ["foo", "bar"] }, "/test.foo.bar"]
1345 ]
1346 ],
1347 [
1348 "/test.:format(\\w+)",
1349 {
1350 end: false
1351 },
1352 [
1353 "/test",
1354 {
1355 name: "format",
1356 prefix: ".",
1357 suffix: "",
1358 modifier: "",
1359 pattern: "\\w+"
1360 }
1361 ],
1362 [
1363 ["/test.html", ["/test.html", "html"]],
1364 ["/test.hbs.html", null]
1365 ],
1366 [[{ format: "foo" }, "/test.foo"]]
1367 ],
1368 [
1369 "/test.:format.",
1370 undefined,
1371 [
1372 "/test",
1373 {
1374 name: "format",
1375 prefix: ".",
1376 suffix: "",
1377 modifier: "",
1378 pattern: "[^\\/#\\?]+?"
1379 },
1380 "."
1381 ],
1382 [
1383 ["/test.html.", ["/test.html.", "html"]],
1384 ["/test.hbs.html", null]
1385 ],
1386 [
1387 [{ format: "" }, null],
1388 [{ format: "foo" }, "/test.foo."]
1389 ]
1390 ],
1391 /**
1392 * Format and path params.
1393 */
1394 [
1395 "/:test.:format",
1396 undefined,
1397 [
1398 {
1399 name: "test",
1400 prefix: "/",
1401 suffix: "",
1402 modifier: "",
1403 pattern: "[^\\/#\\?]+?"
1404 },
1405 {
1406 name: "format",
1407 prefix: ".",
1408 suffix: "",
1409 modifier: "",
1410 pattern: "[^\\/#\\?]+?"
1411 }
1412 ],
1413 [
1414 ["/route.html", ["/route.html", "route", "html"]],
1415 ["/route", null],
1416 ["/route.html.json", ["/route.html.json", "route", "html.json"]]
1417 ],
1418 [
1419 [{}, null],
1420 [{ test: "route", format: "foo" }, "/route.foo"]
1421 ]
1422 ],
1423 [
1424 "/:test{.:format}?",
1425 undefined,
1426 [
1427 {
1428 name: "test",
1429 prefix: "/",
1430 suffix: "",
1431 modifier: "",
1432 pattern: "[^\\/#\\?]+?"
1433 },
1434 {
1435 name: "format",
1436 prefix: ".",
1437 suffix: "",
1438 modifier: "?",
1439 pattern: "[^\\/#\\?]+?"
1440 }
1441 ],
1442 [
1443 ["/route", ["/route", "route", undefined]],
1444 ["/route.json", ["/route.json", "route", "json"]],
1445 ["/route.json.html", ["/route.json.html", "route", "json.html"]]
1446 ],
1447 [
1448 [{ test: "route" }, "/route"],
1449 [{ test: "route", format: "" }, null],
1450 [{ test: "route", format: "foo" }, "/route.foo"]
1451 ]
1452 ],
1453 [
1454 "/:test.:format?",
1455 {
1456 end: false
1457 },
1458 [
1459 {
1460 name: "test",
1461 prefix: "/",
1462 suffix: "",
1463 modifier: "",
1464 pattern: "[^\\/#\\?]+?"
1465 },
1466 {
1467 name: "format",
1468 prefix: ".",
1469 suffix: "",
1470 modifier: "?",
1471 pattern: "[^\\/#\\?]+?"
1472 }
1473 ],
1474 [
1475 ["/route", ["/route", "route", undefined]],
1476 ["/route.json", ["/route.json", "route", "json"]],
1477 ["/route.json.html", ["/route.json.html", "route", "json.html"]]
1478 ],
1479 [
1480 [{ test: "route" }, "/route"],
1481 [{ test: "route", format: undefined }, "/route"],
1482 [{ test: "route", format: "" }, null],
1483 [{ test: "route", format: "foo" }, "/route.foo"]
1484 ]
1485 ],
1486 [
1487 "/test.:format(.*)z",
1488 {
1489 end: false
1490 },
1491 [
1492 "/test",
1493 {
1494 name: "format",
1495 prefix: ".",
1496 suffix: "",
1497 modifier: "",
1498 pattern: ".*"
1499 },
1500 "z"
1501 ],
1502 [
1503 ["/test.abc", null],
1504 ["/test.z", ["/test.z", ""]],
1505 ["/test.abcz", ["/test.abcz", "abc"]]
1506 ],
1507 [
1508 [{}, null],
1509 [{ format: "" }, "/test.z"],
1510 [{ format: "foo" }, "/test.fooz"]
1511 ]
1512 ],
1513 /**
1514 * Unnamed params.
1515 */
1516 [
1517 "/(\\d+)",
1518 undefined,
1519 [
1520 {
1521 name: 0,
1522 prefix: "/",
1523 suffix: "",
1524 modifier: "",
1525 pattern: "\\d+"
1526 }
1527 ],
1528 [
1529 ["/123", ["/123", "123"]],
1530 ["/abc", null],
1531 ["/123/abc", null]
1532 ],
1533 [
1534 [{}, null],
1535 [{ "0": "123" }, "/123"]
1536 ]
1537 ],
1538 [
1539 "/(\\d+)",
1540 {
1541 end: false
1542 },
1543 [
1544 {
1545 name: 0,
1546 prefix: "/",
1547 suffix: "",
1548 modifier: "",
1549 pattern: "\\d+"
1550 }
1551 ],
1552 [
1553 ["/123", ["/123", "123"]],
1554 ["/abc", null],
1555 ["/123/abc", ["/123", "123"]],
1556 ["/123/", ["/123/", "123"]]
1557 ],
1558 [[{ "0": "123" }, "/123"]]
1559 ],
1560 [
1561 "/(\\d+)?",
1562 undefined,
1563 [
1564 {
1565 name: 0,
1566 prefix: "/",
1567 suffix: "",
1568 modifier: "?",
1569 pattern: "\\d+"
1570 }
1571 ],
1572 [
1573 ["/", ["/", undefined]],
1574 ["/123", ["/123", "123"]]
1575 ],
1576 [
1577 [{}, ""],
1578 [{ "0": "123" }, "/123"]
1579 ]
1580 ],
1581 [
1582 "/(.*)",
1583 undefined,
1584 [
1585 {
1586 name: 0,
1587 prefix: "/",
1588 suffix: "",
1589 modifier: "",
1590 pattern: ".*"
1591 }
1592 ],
1593 [
1594 ["/", ["/", ""]],
1595 ["/route", ["/route", "route"]],
1596 ["/route/nested", ["/route/nested", "route/nested"]]
1597 ],
1598 [
1599 [{ "0": "" }, "/"],
1600 [{ "0": "123" }, "/123"]
1601 ]
1602 ],
1603 [
1604 "/route\\(\\\\(\\d+\\\\)\\)",
1605 undefined,
1606 [
1607 "/route(\\",
1608 {
1609 name: 0,
1610 prefix: "",
1611 suffix: "",
1612 modifier: "",
1613 pattern: "\\d+\\\\"
1614 },
1615 ")"
1616 ],
1617 [["/route(\\123\\)", ["/route(\\123\\)", "123\\"]]],
1618 []
1619 ],
1620 [
1621 "{/login}?",
1622 undefined,
1623 [
1624 {
1625 name: "",
1626 prefix: "/login",
1627 suffix: "",
1628 modifier: "?",
1629 pattern: ""
1630 }
1631 ],
1632 [
1633 ["/", ["/"]],
1634 ["/login", ["/login"]]
1635 ],
1636 [
1637 [null, ""],
1638 [{ "": "" }, "/login"]
1639 ]
1640 ],
1641 [
1642 "{/login}",
1643 undefined,
1644 [
1645 {
1646 name: "",
1647 prefix: "/login",
1648 suffix: "",
1649 modifier: "",
1650 pattern: ""
1651 }
1652 ],
1653 [
1654 ["/", null],
1655 ["/login", ["/login"]]
1656 ],
1657 [[{ "": "" }, "/login"]]
1658 ],
1659 [
1660 "{/(.*)}",
1661 undefined,
1662 [
1663 {
1664 name: 0,
1665 prefix: "/",
1666 suffix: "",
1667 modifier: "",
1668 pattern: ".*"
1669 }
1670 ],
1671 [
1672 ["/", ["/", ""]],
1673 ["/login", ["/login", "login"]]
1674 ],
1675 [[{ 0: "test" }, "/test"]]
1676 ],
1677 /**
1678 * Regexps.
1679 */
1680 [/.*/, undefined, [], [["/match/anything", ["/match/anything"]]], []],
1681 [
1682 /(.*)/,
1683 undefined,
1684 [
1685 {
1686 name: 0,
1687 prefix: "",
1688 suffix: "",
1689 modifier: "",
1690 pattern: ""
1691 }
1692 ],
1693 [["/match/anything", ["/match/anything", "/match/anything"]]],
1694 []
1695 ],
1696 [
1697 /\/(\d+)/,
1698 undefined,
1699 [
1700 {
1701 name: 0,
1702 prefix: "",
1703 suffix: "",
1704 modifier: "",
1705 pattern: ""
1706 }
1707 ],
1708 [
1709 ["/abc", null],
1710 ["/123", ["/123", "123"]]
1711 ],
1712 []
1713 ],
1714 /**
1715 * Mixed arrays.
1716 */
1717 [
1718 ["/test", /\/(\d+)/],
1719 undefined,
1720 [
1721 {
1722 name: 0,
1723 prefix: "",
1724 suffix: "",
1725 modifier: "",
1726 pattern: ""
1727 }
1728 ],
1729 [["/test", ["/test", undefined]]],
1730 []
1731 ],
1732 [
1733 ["/:test(\\d+)", /(.*)/],
1734 undefined,
1735 [
1736 {
1737 name: "test",
1738 prefix: "/",
1739 suffix: "",
1740 modifier: "",
1741 pattern: "\\d+"
1742 },
1743 {
1744 name: 0,
1745 prefix: "",
1746 suffix: "",
1747 modifier: "",
1748 pattern: ""
1749 }
1750 ],
1751 [
1752 ["/123", ["/123", "123", undefined]],
1753 ["/abc", ["/abc", undefined, "/abc"]]
1754 ],
1755 []
1756 ],
1757 /**
1758 * Correct names and indexes.
1759 */
1760 [
1761 ["/:test", "/route/:test"],
1762 undefined,
1763 [
1764 {
1765 name: "test",
1766 prefix: "/",
1767 suffix: "",
1768 modifier: "",
1769 pattern: "[^\\/#\\?]+?"
1770 },
1771 {
1772 name: "test",
1773 prefix: "/",
1774 suffix: "",
1775 modifier: "",
1776 pattern: "[^\\/#\\?]+?"
1777 }
1778 ],
1779 [
1780 ["/test", ["/test", "test", undefined]],
1781 ["/route/test", ["/route/test", undefined, "test"]]
1782 ],
1783 []
1784 ],
1785 [
1786 [/^\/([^\/]+)$/, /^\/route\/([^\/]+)$/],
1787 undefined,
1788 [
1789 {
1790 name: 0,
1791 prefix: "",
1792 suffix: "",
1793 modifier: "",
1794 pattern: ""
1795 },
1796 {
1797 name: 0,
1798 prefix: "",
1799 suffix: "",
1800 modifier: "",
1801 pattern: ""
1802 }
1803 ],
1804 [
1805 ["/test", ["/test", "test", undefined]],
1806 ["/route/test", ["/route/test", undefined, "test"]]
1807 ],
1808 []
1809 ],
1810 /**
1811 * Ignore non-matching groups in regexps.
1812 */
1813 [
1814 /(?:.*)/,
1815 undefined,
1816 [],
1817 [["/anything/you/want", ["/anything/you/want"]]],
1818 []
1819 ],
1820 /**
1821 * Respect escaped characters.
1822 */
1823 [
1824 "/\\(testing\\)",
1825 undefined,
1826 ["/(testing)"],
1827 [
1828 ["/testing", null],
1829 ["/(testing)", ["/(testing)"]]
1830 ],
1831 [[null, "/(testing)"]]
1832 ],
1833 [
1834 "/.\\+\\*\\?\\{\\}=^!\\:$[]|",
1835 undefined,
1836 ["/.+*?{}=^!:$[]|"],
1837 [["/.+*?{}=^!:$[]|", ["/.+*?{}=^!:$[]|"]]],
1838 [[null, "/.+*?{}=^!:$[]|"]]
1839 ],
1840 [
1841 "/test\\/:uid(u\\d+)?:cid(c\\d+)?",
1842 undefined,
1843 [
1844 "/test/",
1845 {
1846 name: "uid",
1847 prefix: "",
1848 suffix: "",
1849 modifier: "?",
1850 pattern: "u\\d+"
1851 },
1852 {
1853 name: "cid",
1854 prefix: "",
1855 suffix: "",
1856 modifier: "?",
1857 pattern: "c\\d+"
1858 }
1859 ],
1860 [
1861 ["/test", null],
1862 ["/test/", ["/test/", undefined, undefined]],
1863 ["/test/u123", ["/test/u123", "u123", undefined]],
1864 ["/test/c123", ["/test/c123", undefined, "c123"]]
1865 ],
1866 [
1867 [{ uid: "u123" }, "/test/u123"],
1868 [{ cid: "c123" }, "/test/c123"],
1869 [{ cid: "u123" }, null]
1870 ]
1871 ],
1872 /**
1873 * Unnamed group prefix.
1874 */
1875 [
1876 "/{apple-}?icon-:res(\\d+).png",
1877 undefined,
1878 [
1879 "/",
1880 {
1881 name: "",
1882 prefix: "apple-",
1883 suffix: "",
1884 modifier: "?",
1885 pattern: ""
1886 },
1887 "icon-",
1888 {
1889 name: "res",
1890 prefix: "",
1891 suffix: "",
1892 modifier: "",
1893 pattern: "\\d+"
1894 },
1895 ".png"
1896 ],
1897 [
1898 ["/icon-240.png", ["/icon-240.png", "240"]],
1899 ["/apple-icon-240.png", ["/apple-icon-240.png", "240"]]
1900 ],
1901 []
1902 ],
1903 /**
1904 * Random examples.
1905 */
1906 [
1907 "/:foo/:bar",
1908 undefined,
1909 [
1910 {
1911 name: "foo",
1912 prefix: "/",
1913 suffix: "",
1914 modifier: "",
1915 pattern: "[^\\/#\\?]+?"
1916 },
1917 {
1918 name: "bar",
1919 prefix: "/",
1920 suffix: "",
1921 modifier: "",
1922 pattern: "[^\\/#\\?]+?"
1923 }
1924 ],
1925 [["/match/route", ["/match/route", "match", "route"]]],
1926 [[{ foo: "a", bar: "b" }, "/a/b"]]
1927 ],
1928 [
1929 "/:foo\\(test\\)/bar",
1930 undefined,
1931 [
1932 {
1933 name: "foo",
1934 prefix: "/",
1935 suffix: "",
1936 modifier: "",
1937 pattern: "[^\\/#\\?]+?"
1938 },
1939 "(test)/bar"
1940 ],
1941 [],
1942 []
1943 ],
1944 [
1945 "/:remote([\\w-.]+)/:user([\\w-]+)",
1946 undefined,
1947 [
1948 {
1949 name: "remote",
1950 prefix: "/",
1951 suffix: "",
1952 modifier: "",
1953 pattern: "[\\w-.]+"
1954 },
1955 {
1956 name: "user",
1957 prefix: "/",
1958 suffix: "",
1959 modifier: "",
1960 pattern: "[\\w-]+"
1961 }
1962 ],
1963 [
1964 ["/endpoint/user", ["/endpoint/user", "endpoint", "user"]],
1965 ["/endpoint/user-name", ["/endpoint/user-name", "endpoint", "user-name"]],
1966 ["/foo.bar/user-name", ["/foo.bar/user-name", "foo.bar", "user-name"]]
1967 ],
1968 [
1969 [{ remote: "foo", user: "bar" }, "/foo/bar"],
1970 [{ remote: "foo.bar", user: "uno" }, "/foo.bar/uno"]
1971 ]
1972 ],
1973 [
1974 "/:foo\\?",
1975 undefined,
1976 [
1977 {
1978 name: "foo",
1979 prefix: "/",
1980 suffix: "",
1981 modifier: "",
1982 pattern: "[^\\/#\\?]+?"
1983 },
1984 "?"
1985 ],
1986 [["/route?", ["/route?", "route"]]],
1987 [[{ foo: "bar" }, "/bar?"]]
1988 ],
1989 [
1990 "/:foo+baz",
1991 undefined,
1992 [
1993 {
1994 name: "foo",
1995 prefix: "/",
1996 suffix: "",
1997 modifier: "+",
1998 pattern: "[^\\/#\\?]+?"
1999 },
2000 "baz"
2001 ],
2002 [
2003 ["/foobaz", ["/foobaz", "foo"]],
2004 ["/foo/barbaz", ["/foo/barbaz", "foo/bar"]],
2005 ["/baz", null]
2006 ],
2007 [
2008 [{ foo: "foo" }, "/foobaz"],
2009 [{ foo: "foo/bar" }, "/foo%2Fbarbaz", { encode: encodeURIComponent }],
2010 [{ foo: ["foo", "bar"] }, "/foo/barbaz"]
2011 ]
2012 ],
2013 [
2014 "\\/:pre?baz",
2015 undefined,
2016 [
2017 "/",
2018 {
2019 name: "pre",
2020 prefix: "",
2021 suffix: "",
2022 modifier: "?",
2023 pattern: "[^\\/#\\?]+?"
2024 },
2025 "baz"
2026 ],
2027 [
2028 ["/foobaz", ["/foobaz", "foo"]],
2029 ["/baz", ["/baz", undefined]]
2030 ],
2031 [
2032 [{}, "/baz"],
2033 [{ pre: "foo" }, "/foobaz"]
2034 ]
2035 ],
2036 [
2037 "/:foo\\(:bar?\\)",
2038 undefined,
2039 [
2040 {
2041 name: "foo",
2042 prefix: "/",
2043 suffix: "",
2044 modifier: "",
2045 pattern: "[^\\/#\\?]+?"
2046 },
2047 "(",
2048 {
2049 name: "bar",
2050 prefix: "",
2051 suffix: "",
2052 modifier: "?",
2053 pattern: "[^\\/#\\?]+?"
2054 },
2055 ")"
2056 ],
2057 [
2058 ["/hello(world)", ["/hello(world)", "hello", "world"]],
2059 ["/hello()", ["/hello()", "hello", undefined]]
2060 ],
2061 [
2062 [{ foo: "hello", bar: "world" }, "/hello(world)"],
2063 [{ foo: "hello" }, "/hello()"]
2064 ]
2065 ],
2066 [
2067 "/:postType(video|audio|text)(\\+.+)?",
2068 undefined,
2069 [
2070 {
2071 name: "postType",
2072 prefix: "/",
2073 suffix: "",
2074 modifier: "",
2075 pattern: "video|audio|text"
2076 },
2077 {
2078 name: 0,
2079 prefix: "",
2080 suffix: "",
2081 modifier: "?",
2082 pattern: "\\+.+"
2083 }
2084 ],
2085 [
2086 ["/video", ["/video", "video", undefined]],
2087 ["/video+test", ["/video+test", "video", "+test"]],
2088 ["/video+", null]
2089 ],
2090 [
2091 [{ postType: "video" }, "/video"],
2092 [{ postType: "random" }, null]
2093 ]
2094 ],
2095 [
2096 "/:foo?/:bar?-ext",
2097 undefined,
2098 [
2099 {
2100 name: "foo",
2101 prefix: "/",
2102 suffix: "",
2103 modifier: "?",
2104 pattern: "[^\\/#\\?]+?"
2105 },
2106 {
2107 name: "bar",
2108 prefix: "/",
2109 suffix: "",
2110 modifier: "?",
2111 pattern: "[^\\/#\\?]+?"
2112 },
2113 "-ext"
2114 ],
2115 [
2116 ["/-ext", null],
2117 ["-ext", ["-ext", undefined, undefined]],
2118 ["/foo-ext", ["/foo-ext", "foo", undefined]],
2119 ["/foo/bar-ext", ["/foo/bar-ext", "foo", "bar"]],
2120 ["/foo/-ext", null]
2121 ],
2122 [
2123 [{}, "-ext"],
2124 [{ foo: "foo" }, "/foo-ext"],
2125 [{ bar: "bar" }, "/bar-ext"],
2126 [{ foo: "foo", bar: "bar" }, "/foo/bar-ext"]
2127 ]
2128 ],
2129 [
2130 "/:required/:optional?-ext",
2131 undefined,
2132 [
2133 {
2134 name: "required",
2135 prefix: "/",
2136 suffix: "",
2137 modifier: "",
2138 pattern: "[^\\/#\\?]+?"
2139 },
2140 {
2141 name: "optional",
2142 prefix: "/",
2143 suffix: "",
2144 modifier: "?",
2145 pattern: "[^\\/#\\?]+?"
2146 },
2147 "-ext"
2148 ],
2149 [
2150 ["/foo-ext", ["/foo-ext", "foo", undefined]],
2151 ["/foo/bar-ext", ["/foo/bar-ext", "foo", "bar"]],
2152 ["/foo/-ext", null]
2153 ],
2154 [[{ required: "foo" }, "/foo-ext"]]
2155 ],
2156 /**
2157 * Unicode characters.
2158 */
2159 [
2160 "/:foo",
2161 undefined,
2162 [
2163 {
2164 name: "foo",
2165 prefix: "/",
2166 suffix: "",
2167 modifier: "",
2168 pattern: "[^\\/#\\?]+?"
2169 }
2170 ],
2171 [["/café", ["/café", "café"]]],
2172 [
2173 [{ foo: "café" }, "/café"],
2174 [{ foo: "café" }, "/caf%C3%A9", { encode: encodeURIComponent }]
2175 ]
2176 ],
2177 ["/café", undefined, ["/café"], [["/café", ["/café"]]], [[null, "/café"]]],
2178 [
2179 "/café",
2180 { encode: encodeURI },
2181 ["/café"],
2182 [["/caf%C3%A9", ["/caf%C3%A9"]]],
2183 [[null, "/café"]]
2184 ],
2185 [
2186 "packages/",
2187 undefined,
2188 ["packages/"],
2189 [
2190 ["packages", null],
2191 ["packages/", ["packages/"]]
2192 ],
2193 [[null, "packages/"]]
2194 ],
2195 /**
2196 * Hostnames.
2197 */
2198 [
2199 ":domain.com",
2200 {
2201 delimiter: "."
2202 },
2203 [
2204 {
2205 name: "domain",
2206 prefix: "",
2207 suffix: "",
2208 modifier: "",
2209 pattern: "[^\\.]+?"
2210 },
2211 ".com"
2212 ],
2213 [
2214 ["example.com", ["example.com", "example"]],
2215 ["github.com", ["github.com", "github"]]
2216 ],
2217 [
2218 [{ domain: "example" }, "example.com"],
2219 [{ domain: "github" }, "github.com"]
2220 ]
2221 ],
2222 [
2223 "mail.:domain.com",
2224 {
2225 delimiter: "."
2226 },
2227 [
2228 "mail",
2229 {
2230 name: "domain",
2231 prefix: ".",
2232 suffix: "",
2233 modifier: "",
2234 pattern: "[^\\.]+?"
2235 },
2236 ".com"
2237 ],
2238 [
2239 ["mail.example.com", ["mail.example.com", "example"]],
2240 ["mail.github.com", ["mail.github.com", "github"]]
2241 ],
2242 [
2243 [{ domain: "example" }, "mail.example.com"],
2244 [{ domain: "github" }, "mail.github.com"]
2245 ]
2246 ],
2247 [
2248 "example.:ext",
2249 {},
2250 [
2251 "example",
2252 {
2253 name: "ext",
2254 prefix: ".",
2255 suffix: "",
2256 modifier: "",
2257 pattern: "[^\\/#\\?]+?"
2258 }
2259 ],
2260 [
2261 ["example.com", ["example.com", "com"]],
2262 ["example.org", ["example.org", "org"]]
2263 ],
2264 [
2265 [{ ext: "com" }, "example.com"],
2266 [{ ext: "org" }, "example.org"]
2267 ]
2268 ],
2269 [
2270 "this is",
2271 {
2272 delimiter: " ",
2273 end: false
2274 },
2275 ["this is"],
2276 [
2277 ["this is a test", ["this is"]],
2278 ["this isn't", null]
2279 ],
2280 [[null, "this is"]]
2281 ],
2282 /**
2283 * Ends with.
2284 */
2285 [
2286 "/test",
2287 {
2288 endsWith: "?"
2289 },
2290 ["/test"],
2291 [
2292 ["/test", ["/test"]],
2293 ["/test?query=string", ["/test"]],
2294 ["/test/?query=string", ["/test/"]],
2295 ["/testx", null]
2296 ],
2297 [[null, "/test"]]
2298 ],
2299 [
2300 "/test",
2301 {
2302 endsWith: "?",
2303 strict: true
2304 },
2305 ["/test"],
2306 [
2307 ["/test?query=string", ["/test"]],
2308 ["/test/?query=string", null]
2309 ],
2310 [[null, "/test"]]
2311 ],
2312 /**
2313 * Custom prefixes.
2314 */
2315 [
2316 "{$:foo}{$:bar}?",
2317 {},
2318 [
2319 {
2320 name: "foo",
2321 pattern: "[^\\/#\\?]+?",
2322 prefix: "$",
2323 suffix: "",
2324 modifier: ""
2325 },
2326 {
2327 name: "bar",
2328 pattern: "[^\\/#\\?]+?",
2329 prefix: "$",
2330 suffix: "",
2331 modifier: "?"
2332 }
2333 ],
2334 [
2335 ["$x", ["$x", "x", undefined]],
2336 ["$x$y", ["$x$y", "x", "y"]]
2337 ],
2338 [
2339 [{ foo: "foo" }, "$foo"],
2340 [{ foo: "foo", bar: "bar" }, "$foo$bar"]
2341 ]
2342 ],
2343 [
2344 "name/:attr1?{-:attr2}?{-:attr3}?",
2345 {},
2346 [
2347 "name",
2348 {
2349 name: "attr1",
2350 pattern: "[^\\/#\\?]+?",
2351 prefix: "/",
2352 suffix: "",
2353 modifier: "?"
2354 },
2355 {
2356 name: "attr2",
2357 pattern: "[^\\/#\\?]+?",
2358 prefix: "-",
2359 suffix: "",
2360 modifier: "?"
2361 },
2362 {
2363 name: "attr3",
2364 pattern: "[^\\/#\\?]+?",
2365 prefix: "-",
2366 suffix: "",
2367 modifier: "?"
2368 }
2369 ],
2370 [
2371 ["name/test", ["name/test", "test", undefined, undefined]],
2372 ["name/1", ["name/1", "1", undefined, undefined]],
2373 ["name/1-2", ["name/1-2", "1", "2", undefined]],
2374 ["name/1-2-3", ["name/1-2-3", "1", "2", "3"]],
2375 ["name/foo-bar/route", null],
2376 ["name/test/route", null]
2377 ],
2378 [
2379 [{}, "name"],
2380 [{ attr1: "test" }, "name/test"],
2381 [{ attr2: "attr" }, "name-attr"]
2382 ]
2383 ],
2384 /**
2385 * Case-sensitive compile tokensToFunction params.
2386 */
2387 [
2388 "/:test(abc)",
2389 {
2390 sensitive: true
2391 },
2392 [
2393 {
2394 name: "test",
2395 prefix: "/",
2396 suffix: "",
2397 modifier: "",
2398 pattern: "abc"
2399 }
2400 ],
2401 [
2402 ["/abc", ["/abc", "abc"]],
2403 ["/ABC", null]
2404 ],
2405 [
2406 [{ test: "abc" }, "/abc"],
2407 [{ test: "ABC" }, null]
2408 ]
2409 ],
2410 [
2411 "/:test(abc)",
2412 {},
2413 [
2414 {
2415 name: "test",
2416 prefix: "/",
2417 suffix: "",
2418 modifier: "",
2419 pattern: "abc"
2420 }
2421 ],
2422 [
2423 ["/abc", ["/abc", "abc"]],
2424 ["/ABC", ["/ABC", "ABC"]]
2425 ],
2426 [
2427 [{ test: "abc" }, "/abc"],
2428 [{ test: "ABC" }, "/ABC"]
2429 ]
2430 ],
2431 /**
2432 * Nested parentheses.
2433 */
2434 [
2435 "/:test(\\d+(?:\\.\\d+)?)",
2436 undefined,
2437 [
2438 {
2439 name: "test",
2440 prefix: "/",
2441 suffix: "",
2442 modifier: "",
2443 pattern: "\\d+(?:\\.\\d+)?"
2444 }
2445 ],
2446 [
2447 ["/123", ["/123", "123"]],
2448 ["/abc", null],
2449 ["/123/abc", null],
2450 ["/123.123", ["/123.123", "123.123"]],
2451 ["/123.abc", null]
2452 ],
2453 [
2454 [{ test: 123 }, "/123"],
2455 [{ test: 123.123 }, "/123.123"],
2456 [{ test: "abc" }, null],
2457 [{ test: "123" }, "/123"],
2458 [{ test: "123.123" }, "/123.123"],
2459 [{ test: "123.abc" }, null]
2460 ]
2461 ],
2462 [
2463 "/:test((?!login)[^/]+)",
2464 undefined,
2465 [
2466 {
2467 name: "test",
2468 prefix: "/",
2469 suffix: "",
2470 modifier: "",
2471 pattern: "(?!login)[^/]+"
2472 }
2473 ],
2474 [
2475 ["/route", ["/route", "route"]],
2476 ["/login", null]
2477 ],
2478 [
2479 [{ test: "route" }, "/route"],
2480 [{ test: "login" }, null]
2481 ]
2482 ],
2483 /**
2484 * https://github.com/pillarjs/path-to-regexp/issues/206
2485 */
2486 [
2487 "/user(s)?/:user",
2488 undefined,
2489 [
2490 "/user",
2491 {
2492 name: 0,
2493 prefix: "",
2494 suffix: "",
2495 modifier: "?",
2496 pattern: "s"
2497 },
2498 {
2499 name: "user",
2500 prefix: "/",
2501 suffix: "",
2502 modifier: "",
2503 pattern: "[^\\/#\\?]+?"
2504 }
2505 ],
2506 [
2507 ["/user/123", ["/user/123", undefined, "123"]],
2508 ["/users/123", ["/users/123", "s", "123"]]
2509 ],
2510 [[{ user: "123" }, "/user/123"]]
2511 ],
2512 /**
2513 * https://github.com/pillarjs/path-to-regexp/issues/209
2514 */
2515 [
2516 "/whatever/:foo\\?query=str",
2517 undefined,
2518 [
2519 "/whatever",
2520 {
2521 name: "foo",
2522 prefix: "/",
2523 suffix: "",
2524 modifier: "",
2525 pattern: "[^\\/#\\?]+?"
2526 },
2527 "?query=str"
2528 ],
2529 [["/whatever/123?query=str", ["/whatever/123?query=str", "123"]]],
2530 [[{ foo: "123" }, "/whatever/123?query=str"]]
2531 ],
2532 [
2533 "/whatever/:foo",
2534 {
2535 end: false
2536 },
2537 [
2538 "/whatever",
2539 {
2540 name: "foo",
2541 prefix: "/",
2542 suffix: "",
2543 modifier: "",
2544 pattern: "[^\\/#\\?]+?"
2545 }
2546 ],
2547 [
2548 ["/whatever/123", ["/whatever/123", "123"]],
2549 ["/whatever/123/path", ["/whatever/123", "123"]],
2550 ["/whatever/123#fragment", ["/whatever/123", "123"]],
2551 ["/whatever/123?query=str", ["/whatever/123", "123"]]
2552 ],
2553 [
2554 [{ foo: "123" }, "/whatever/123"],
2555 [{ foo: "#" }, null]
2556 ]
2557 ]
2558];
2559/**
2560 * Dynamically generate the entire test suite.
2561 */
2562describe("path-to-regexp", function () {
2563 var TEST_PATH = "/user/:id";
2564 var TEST_PARAM = {
2565 name: "id",
2566 prefix: "/",
2567 suffix: "",
2568 modifier: "",
2569 pattern: "[^\\/#\\?]+?"
2570 };
2571 describe("arguments", function () {
2572 it("should work without different call combinations", function () {
2573 pathToRegexp.pathToRegexp("/test");
2574 pathToRegexp.pathToRegexp("/test", []);
2575 pathToRegexp.pathToRegexp("/test", undefined, {});
2576 pathToRegexp.pathToRegexp(/^\/test/);
2577 pathToRegexp.pathToRegexp(/^\/test/, []);
2578 pathToRegexp.pathToRegexp(/^\/test/, undefined, {});
2579 pathToRegexp.pathToRegexp(["/a", "/b"]);
2580 pathToRegexp.pathToRegexp(["/a", "/b"], []);
2581 pathToRegexp.pathToRegexp(["/a", "/b"], undefined, {});
2582 });
2583 it("should accept an array of keys as the second argument", function () {
2584 var keys = [];
2585 var re = pathToRegexp.pathToRegexp(TEST_PATH, keys, { end: false });
2586 expect(keys).toEqual([TEST_PARAM]);
2587 expect(exec(re, "/user/123/show")).toEqual(["/user/123", "123"]);
2588 });
2589 it("should throw on non-capturing pattern", function () {
2590 expect(function () {
2591 pathToRegexp.pathToRegexp("/:foo(?:\\d+(\\.\\d+)?)");
2592 }).toThrow(new TypeError('Pattern cannot start with "?" at 6'));
2593 });
2594 it("should throw on nested capturing group", function () {
2595 expect(function () {
2596 pathToRegexp.pathToRegexp("/:foo(\\d+(\\.\\d+)?)");
2597 }).toThrow(new TypeError("Capturing groups are not allowed at 9"));
2598 });
2599 it("should throw on unbalanced pattern", function () {
2600 expect(function () {
2601 pathToRegexp.pathToRegexp("/:foo(abc");
2602 }).toThrow(new TypeError("Unbalanced pattern at 5"));
2603 });
2604 it("should throw on missing pattern", function () {
2605 expect(function () {
2606 pathToRegexp.pathToRegexp("/:foo()");
2607 }).toThrow(new TypeError("Missing pattern at 5"));
2608 });
2609 it("should throw on missing name", function () {
2610 expect(function () {
2611 pathToRegexp.pathToRegexp("/:(test)");
2612 }).toThrow(new TypeError("Missing parameter name at 1"));
2613 });
2614 it("should throw on nested groups", function () {
2615 expect(function () {
2616 pathToRegexp.pathToRegexp("/{a{b:foo}}");
2617 }).toThrow(new TypeError("Unexpected OPEN at 3, expected CLOSE"));
2618 });
2619 it("should throw on misplaced modifier", function () {
2620 expect(function () {
2621 pathToRegexp.pathToRegexp("/foo?");
2622 }).toThrow(new TypeError("Unexpected MODIFIER at 4, expected END"));
2623 });
2624 });
2625 describe("tokens", function () {
2626 var tokens = pathToRegexp.parse(TEST_PATH);
2627 it("should expose method to compile tokens to regexp", function () {
2628 var re = pathToRegexp.tokensToRegexp(tokens);
2629 expect(exec(re, "/user/123")).toEqual(["/user/123", "123"]);
2630 });
2631 it("should expose method to compile tokens to a path function", function () {
2632 var fn = pathToRegexp.tokensToFunction(tokens);
2633 expect(fn({ id: 123 })).toEqual("/user/123");
2634 });
2635 });
2636 describe("rules", function () {
2637 TESTS.forEach(function (test) {
2638 var path = test[0], opts = test[1], tokens = test[2], matchCases = test[3], compileCases = test[4];
2639 describe(util.inspect(path), function () {
2640 var keys = [];
2641 var re = pathToRegexp.pathToRegexp(path, keys, opts);
2642 // Parsing and compiling is only supported with string input.
2643 if (typeof path === "string") {
2644 it("should parse", function () {
2645 expect(pathToRegexp.parse(path, opts)).toEqual(tokens);
2646 });
2647 describe("compile", function () {
2648 compileCases.forEach(function (io) {
2649 var params = io[0], result = io[1], options = io[2];
2650 var toPath = pathToRegexp.compile(path, __assign(__assign({}, opts), options));
2651 if (result !== null) {
2652 it("should compile using " + util.inspect(params), function () {
2653 expect(toPath(params)).toEqual(result);
2654 });
2655 }
2656 else {
2657 it("should not compile using " + util.inspect(params), function () {
2658 expect(function () {
2659 toPath(params);
2660 }).toThrow(TypeError);
2661 });
2662 }
2663 });
2664 });
2665 }
2666 else {
2667 it("should parse keys", function () {
2668 expect(keys).toEqual(tokens.filter(function (token) {
2669 return typeof token !== "string";
2670 }));
2671 });
2672 }
2673 describe("match" + (opts ? " using " + util.inspect(opts) : ""), function () {
2674 matchCases.forEach(function (io) {
2675 var pathname = io[0], matches = io[1], params = io[2], options = io[3];
2676 var message = "should " + (matches ? "" : "not ") + "match " + util.inspect(pathname);
2677 it(message, function () {
2678 expect(exec(re, pathname)).toEqual(matches);
2679 });
2680 if (typeof path === "string" && params !== undefined) {
2681 var match_1 = pathToRegexp.match(path, options);
2682 it(message + " params", function () {
2683 expect(match_1(pathname)).toEqual(params);
2684 });
2685 }
2686 });
2687 });
2688 });
2689 });
2690 });
2691 describe("compile errors", function () {
2692 it("should throw when a required param is undefined", function () {
2693 var toPath = pathToRegexp.compile("/a/:b/c");
2694 expect(function () {
2695 toPath();
2696 }).toThrow(new TypeError('Expected "b" to be a string'));
2697 });
2698 it("should throw when it does not match the pattern", function () {
2699 var toPath = pathToRegexp.compile("/:foo(\\d+)");
2700 expect(function () {
2701 toPath({ foo: "abc" });
2702 }).toThrow(new TypeError('Expected "foo" to match "\\d+", but got "abc"'));
2703 });
2704 it("should throw when expecting a repeated value", function () {
2705 var toPath = pathToRegexp.compile("/:foo+");
2706 expect(function () {
2707 toPath({ foo: [] });
2708 }).toThrow(new TypeError('Expected "foo" to not be empty'));
2709 });
2710 it("should throw when not expecting a repeated value", function () {
2711 var toPath = pathToRegexp.compile("/:foo");
2712 expect(function () {
2713 toPath({ foo: [] });
2714 }).toThrow(new TypeError('Expected "foo" to not repeat, but got an array'));
2715 });
2716 it("should throw when repeated value does not match", function () {
2717 var toPath = pathToRegexp.compile("/:foo(\\d+)+");
2718 expect(function () {
2719 toPath({ foo: [1, 2, 3, "a"] });
2720 }).toThrow(new TypeError('Expected all "foo" to match "\\d+", but got "a"'));
2721 });
2722 });
2723});
2724/**
2725 * Execute a regular expression and return a flat array for comparison.
2726 *
2727 * @param {RegExp} re
2728 * @param {String} str
2729 * @return {Array}
2730 */
2731function exec(re, str) {
2732 var match = re.exec(str);
2733 return match && Array.prototype.slice.call(match);
2734}
2735//# sourceMappingURL=index.spec.js.map
\No newline at end of file