Skip to content

Commit 7a4f933

Browse files
committed
chore: add RegExp pattern tests
1 parent a4b91bb commit 7a4f933

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

test/index.js

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ function run(route, url, loose) {
55
let i=0, out={}, result=fn(route, !!loose);
66
let matches = result.pattern.exec(url);
77
if (matches === null) return false;
8+
if (matches.groups) return matches.groups;
89
while (i < result.keys.length) {
910
out[ result.keys[i] ] = matches[++i] || null;
1011
}
@@ -568,3 +569,229 @@ test('(extra) exec :: loose', t => {
568569

569570
t.end();
570571
});
572+
573+
// ---
574+
575+
test('(RegExp) static', t => {
576+
let rgx = /^\/?books/;
577+
let { keys, pattern } = fn(rgx);
578+
t.same(keys, false, '~> keys = false');
579+
t.same(rgx, pattern, '~> pattern = input');
580+
t.true(pattern.test('/books'), '~> matches route');
581+
t.true(pattern.test('/books/'), '~> matches trailing slash');
582+
t.true(pattern.test('/books/'), '~> matches without leading slash');
583+
t.end();
584+
});
585+
586+
test('(RegExp) param', t => {
587+
let rgx = /^\/(?<year>[0-9]{4})/i;
588+
let { keys, pattern } = fn(rgx);
589+
t.same(keys, false, '~> keys = false');
590+
t.same(rgx, pattern, '~> pattern = input');
591+
592+
// RegExp testing (not regexparam related)
593+
t.false(pattern.test('/123'), '~> does not match 3-digit string');
594+
t.false(pattern.test('/asdf'), '~> does not match 4 alpha characters');
595+
t.true(pattern.test('/2019'), '~> matches definition');
596+
t.true(pattern.test('/2019/'), '~> matches definition w/ trailing slash');
597+
t.false(pattern.test('2019'), '~> does not match without lead slash');
598+
t.true(pattern.test('/2019/narnia/hello'), '~> allows extra bits');
599+
600+
// exec results, array access
601+
let [url, value] = pattern.exec('/2019/books');
602+
t.is(url, '/2019', '~> executing pattern on correct trimming');
603+
t.is(value, '2019', '~> executing pattern gives correct value');
604+
605+
// exec results, named object
606+
t.toExec(rgx, '/2019/books', { year: '2019' });
607+
t.toExec(rgx, '/2019/books/narnia', { year: '2019' });
608+
609+
t.end();
610+
});
611+
612+
test('(RegExp) param :: w/ static', t => {
613+
let rgx = /^\/books\/(?<title>[a-z]+)/i;
614+
let { keys, pattern } = fn(rgx);
615+
t.same(keys, false, '~> keys = false');
616+
t.same(rgx, pattern, '~> pattern = input');
617+
618+
// RegExp testing (not regexparam related)
619+
t.false(pattern.test('/books'), '~> does not match naked base');
620+
t.false(pattern.test('/books/'), '~> does not match naked base w/ trailing slash');
621+
t.true(pattern.test('/books/narnia'), '~> matches definition');
622+
t.true(pattern.test('/books/narnia/'), '~> matches definition w/ trailing slash');
623+
t.true(pattern.test('/books/narnia/hello'), '~> allows extra bits');
624+
t.false(pattern.test('books/narnia'), '~> does not match path without lead slash');
625+
626+
// exec results, array access
627+
let [url, value] = pattern.exec('/books/narnia');
628+
t.is(url, '/books/narnia', '~> executing pattern on correct trimming');
629+
t.is(value, 'narnia', '~> executing pattern gives correct value');
630+
631+
// exec results, named object
632+
t.toExec(rgx, '/books/narnia', { title: 'narnia' });
633+
t.toExec(rgx, '/books/narnia/hello', { title: 'narnia' });
634+
635+
t.end();
636+
});
637+
638+
test('(RegExp) param :: multiple', t => {
639+
let rgx = /^\/(?<year>[0-9]{4})-(?<month>[0-9]{2})\/(?<day>[0-9]{2})/i;
640+
let { keys, pattern } = fn(rgx);
641+
t.same(keys, false, '~> keys = false');
642+
t.same(rgx, pattern, '~> pattern = input');
643+
644+
// RegExp testing (not regexparam related)
645+
t.false(pattern.test('/123-1'));
646+
t.false(pattern.test('/123-10'));
647+
t.false(pattern.test('/1234-10'));
648+
t.false(pattern.test('/1234-10/1'));
649+
t.false(pattern.test('/1234-10/as'));
650+
t.true(pattern.test('/1234-10/01/'));
651+
t.true(pattern.test('/2019-10/30'));
652+
653+
// exec results, array access
654+
let [url, year, month, day] = pattern.exec('/2019-05/30/');
655+
t.is(url, '/2019-05/30', '~> executing pattern on correct trimming');
656+
t.is(year, '2019', '~> executing pattern gives correct "year" value');
657+
t.is(month, '05', '~> executing pattern gives correct "month" value');
658+
t.is(day, '30', '~> executing pattern gives correct "day" value');
659+
660+
// exec results, named object
661+
t.toExec(rgx, '/2019-10/02', { year:'2019', month:'10', day:'02' });
662+
t.toExec(rgx, '/2019-10/02/narnia', { year:'2019', month:'10', day:'02' });
663+
664+
t.end();
665+
});
666+
667+
test('(RegExp) param :: suffix', t => {
668+
let rgx = /^\/movies[/](?<title>\w+)\.mp4/i;
669+
let { keys, pattern } = fn(rgx);
670+
t.same(keys, false, '~> keys = false');
671+
t.same(rgx, pattern, '~> pattern = input');
672+
673+
// RegExp testing (not regexparam related)
674+
t.false(pattern.test('/movies'));
675+
t.false(pattern.test('/movies/'));
676+
t.false(pattern.test('/movies/foo'));
677+
t.false(pattern.test('/movies/foo.mp3'));
678+
t.true(pattern.test('/movies/foo.mp4'));
679+
t.true(pattern.test('/movies/foo.mp4/'));
680+
681+
// exec results, array access
682+
let [url, title] = pattern.exec('/movies/narnia.mp4');
683+
t.is(url, '/movies/narnia.mp4', '~> executing pattern on correct trimming');
684+
t.is(title, 'narnia', '~> executing pattern gives correct "title" value');
685+
686+
// exec results, named object
687+
t.toExec(rgx, '/movies/narnia.mp4', { title: 'narnia' });
688+
t.toExec(rgx, '/movies/narnia.mp4/', { title: 'narnia' });
689+
690+
t.end();
691+
});
692+
693+
test('(RegExp) param :: suffices', t => {
694+
let rgx = /^\/movies[/](?<title>\w+)\.(mp4|mov)/i;
695+
let { keys, pattern } = fn(rgx);
696+
t.same(keys, false, '~> keys = false');
697+
t.same(rgx, pattern, '~> pattern = input');
698+
699+
// RegExp testing (not regexparam related)
700+
t.false(pattern.test('/movies'));
701+
t.false(pattern.test('/movies/'));
702+
t.false(pattern.test('/movies/foo'));
703+
t.false(pattern.test('/movies/foo.mp3'));
704+
t.true(pattern.test('/movies/foo.mp4'));
705+
t.true(pattern.test('/movies/foo.mp4/'));
706+
t.true(pattern.test('/movies/foo.mov/'));
707+
708+
// exec results, array access
709+
let [url, title] = pattern.exec('/movies/narnia.mov');
710+
t.is(url, '/movies/narnia.mov', '~> executing pattern on correct trimming');
711+
t.is(title, 'narnia', '~> executing pattern gives correct "title" value');
712+
713+
// exec results, named object
714+
t.toExec(rgx, '/movies/narnia.mov', { title: 'narnia' });
715+
t.toExec(rgx, '/movies/narnia.mov/', { title: 'narnia' });
716+
717+
t.end();
718+
});
719+
720+
test('(RegExp) param :: optional', t => {
721+
let rgx = /^\/books[/](?<author>[^/]+)[/]?(?<title>[^/]+)?[/]?$/
722+
let { keys, pattern } = fn(rgx);
723+
t.same(keys, false, '~> keys = false');
724+
t.same(rgx, pattern, '~> pattern = input');
725+
726+
// RegExp testing (not regexparam related)
727+
t.false(pattern.test('/books'));
728+
t.false(pattern.test('/books/'));
729+
t.true(pattern.test('/books/smith'));
730+
t.true(pattern.test('/books/smith/'));
731+
t.true(pattern.test('/books/smith/narnia'));
732+
t.true(pattern.test('/books/smith/narnia/'));
733+
t.false(pattern.test('/books/smith/narnia/reviews'));
734+
t.false(pattern.test('books/smith/narnia'));
735+
736+
// exec results, array access
737+
let [url, author, title] = pattern.exec('/books/smith/narnia/');
738+
t.is(url, '/books/smith/narnia/', '~> executing pattern on correct trimming');
739+
t.is(author, 'smith', '~> executing pattern gives correct value');
740+
t.is(title, 'narnia', '~> executing pattern gives correct value');
741+
742+
// exec results, named object
743+
t.toExec(rgx, '/books/smith/narnia', { author: 'smith', title: 'narnia' });
744+
t.toExec(rgx, '/books/smith/narnia/', { author: 'smith', title: 'narnia' });
745+
t.toExec(rgx, '/books/smith/', { author: 'smith', title: undefined });
746+
747+
t.end();
748+
});
749+
750+
test('param :: optional', t => {
751+
let { keys, pattern } = fn('/books/:author/:title?');
752+
t.same(keys, ['author', 'title'], '~> keys has "author" & "title" values');
753+
t.false(pattern.test('/books'), '~> does not match naked base');
754+
t.false(pattern.test('/books/'), '~> does not match naked base w/ trailing slash');
755+
t.true(pattern.test('/books/smith'), '~> matches when optional parameter is missing counts');
756+
t.true(pattern.test('/books/smith/'), '~> matches when optional paramter is missing w/ trailing slash');
757+
t.true(pattern.test('/books/smith/narnia'), '~> matches when fully populated');
758+
t.true(pattern.test('/books/smith/narnia/'), '~> matches when fully populated w/ trailing slash');
759+
t.false(pattern.test('/books/smith/narnia/reviews'), '~> does not match extra bits');
760+
t.false(pattern.test('books/smith/narnia'), '~> does not match path without lead slash');
761+
let [_, author, title] = pattern.exec('/books/smith/narnia');
762+
t.is(author, 'smith', '~> executing pattern gives correct value');
763+
t.is(title, 'narnia', '~> executing pattern gives correct value');
764+
t.end();
765+
});
766+
767+
test('(RegExp) nameless', t => {
768+
// For whatever reason~
769+
// ~> regexparam CANNOT give `keys` list cuz unknown
770+
let rgx = /^\/books[/]([^/]\w+)[/]?(\w+)?(?=\/|$)/i;
771+
let { keys, pattern } = fn(rgx);
772+
t.same(keys, false, '~> keys = false');
773+
t.same(rgx, pattern, '~> pattern = input');
774+
775+
// RegExp testing (not regexparam related)
776+
t.false(pattern.test('/books'));
777+
t.false(pattern.test('/books/'));
778+
t.true(pattern.test('/books/smith'));
779+
t.true(pattern.test('/books/smith/'));
780+
t.true(pattern.test('/books/smith/narnia'));
781+
t.true(pattern.test('/books/smith/narnia/'));
782+
t.false(pattern.test('books/smith/narnia'));
783+
784+
// exec results, array access
785+
let [url, author, title] = pattern.exec('/books/smith/narnia/');
786+
t.is(url, '/books/smith/narnia', '~> executing pattern on correct trimming');
787+
t.is(author, 'smith', '~> executing pattern gives correct value');
788+
t.is(title, 'narnia', '~> executing pattern gives correct value');
789+
790+
// exec results, named object
791+
// Note: UNKNOWN & UNNAMED KEYS
792+
t.toExec(rgx, '/books/smith/narnia', {});
793+
t.toExec(rgx, '/books/smith/narnia/', {});
794+
t.toExec(rgx, '/books/smith/', {});
795+
796+
t.end();
797+
});

0 commit comments

Comments
 (0)