Skip to content

Commit d6d4c3b

Browse files
committed
chore: conditional named RegExp testing
1 parent 0573304 commit d6d4c3b

File tree

2 files changed

+168
-180
lines changed

2 files changed

+168
-180
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
language: node_js
22
node_js:
3+
- 10
34
- 6

test/index.js

Lines changed: 167 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const test = require('tape');
22
const fn = require('../dist/regexparam');
33

4+
const hasNamedGroups = 'groups' in /x/.exec('x');
5+
46
function run(route, url, loose) {
57
let i=0, out={}, result=fn(route, !!loose);
68
let matches = result.pattern.exec(url);
@@ -583,186 +585,171 @@ test('(RegExp) static', t => {
583585
t.end();
584586
});
585587

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-
});
588+
if (hasNamedGroups) {
589+
test('(RegExp) param', t => {
590+
let rgx = /^\/(?<year>[0-9]{4})/i;
591+
let { keys, pattern } = fn(rgx);
592+
t.same(keys, false, '~> keys = false');
593+
t.same(rgx, pattern, '~> pattern = input');
594+
595+
// RegExp testing (not regexparam related)
596+
t.false(pattern.test('/123'), '~> does not match 3-digit string');
597+
t.false(pattern.test('/asdf'), '~> does not match 4 alpha characters');
598+
t.true(pattern.test('/2019'), '~> matches definition');
599+
t.true(pattern.test('/2019/'), '~> matches definition w/ trailing slash');
600+
t.false(pattern.test('2019'), '~> does not match without lead slash');
601+
t.true(pattern.test('/2019/narnia/hello'), '~> allows extra bits');
602+
603+
// exec results, array access
604+
let [url, value] = pattern.exec('/2019/books');
605+
t.is(url, '/2019', '~> executing pattern on correct trimming');
606+
t.is(value, '2019', '~> executing pattern gives correct value');
607+
608+
// exec results, named object
609+
t.toExec(rgx, '/2019/books', { year: '2019' });
610+
t.toExec(rgx, '/2019/books/narnia', { year: '2019' });
611+
612+
t.end();
613+
});
614+
615+
test('(RegExp) param :: w/ static', t => {
616+
let rgx = /^\/books\/(?<title>[a-z]+)/i;
617+
let { keys, pattern } = fn(rgx);
618+
t.same(keys, false, '~> keys = false');
619+
t.same(rgx, pattern, '~> pattern = input');
620+
621+
// RegExp testing (not regexparam related)
622+
t.false(pattern.test('/books'), '~> does not match naked base');
623+
t.false(pattern.test('/books/'), '~> does not match naked base w/ trailing slash');
624+
t.true(pattern.test('/books/narnia'), '~> matches definition');
625+
t.true(pattern.test('/books/narnia/'), '~> matches definition w/ trailing slash');
626+
t.true(pattern.test('/books/narnia/hello'), '~> allows extra bits');
627+
t.false(pattern.test('books/narnia'), '~> does not match path without lead slash');
628+
629+
// exec results, array access
630+
let [url, value] = pattern.exec('/books/narnia');
631+
t.is(url, '/books/narnia', '~> executing pattern on correct trimming');
632+
t.is(value, 'narnia', '~> executing pattern gives correct value');
633+
634+
// exec results, named object
635+
t.toExec(rgx, '/books/narnia', { title: 'narnia' });
636+
t.toExec(rgx, '/books/narnia/hello', { title: 'narnia' });
637+
638+
t.end();
639+
});
640+
641+
test('(RegExp) param :: multiple', t => {
642+
let rgx = /^\/(?<year>[0-9]{4})-(?<month>[0-9]{2})\/(?<day>[0-9]{2})/i;
643+
let { keys, pattern } = fn(rgx);
644+
t.same(keys, false, '~> keys = false');
645+
t.same(rgx, pattern, '~> pattern = input');
646+
647+
// RegExp testing (not regexparam related)
648+
t.false(pattern.test('/123-1'));
649+
t.false(pattern.test('/123-10'));
650+
t.false(pattern.test('/1234-10'));
651+
t.false(pattern.test('/1234-10/1'));
652+
t.false(pattern.test('/1234-10/as'));
653+
t.true(pattern.test('/1234-10/01/'));
654+
t.true(pattern.test('/2019-10/30'));
655+
656+
// exec results, array access
657+
let [url, year, month, day] = pattern.exec('/2019-05/30/');
658+
t.is(url, '/2019-05/30', '~> executing pattern on correct trimming');
659+
t.is(year, '2019', '~> executing pattern gives correct "year" value');
660+
t.is(month, '05', '~> executing pattern gives correct "month" value');
661+
t.is(day, '30', '~> executing pattern gives correct "day" value');
662+
663+
// exec results, named object
664+
t.toExec(rgx, '/2019-10/02', { year:'2019', month:'10', day:'02' });
665+
t.toExec(rgx, '/2019-10/02/narnia', { year:'2019', month:'10', day:'02' });
666+
667+
t.end();
668+
});
669+
670+
test('(RegExp) param :: suffix', t => {
671+
let rgx = /^\/movies[/](?<title>\w+)\.mp4/i;
672+
let { keys, pattern } = fn(rgx);
673+
t.same(keys, false, '~> keys = false');
674+
t.same(rgx, pattern, '~> pattern = input');
675+
676+
// RegExp testing (not regexparam related)
677+
t.false(pattern.test('/movies'));
678+
t.false(pattern.test('/movies/'));
679+
t.false(pattern.test('/movies/foo'));
680+
t.false(pattern.test('/movies/foo.mp3'));
681+
t.true(pattern.test('/movies/foo.mp4'));
682+
t.true(pattern.test('/movies/foo.mp4/'));
683+
684+
// exec results, array access
685+
let [url, title] = pattern.exec('/movies/narnia.mp4');
686+
t.is(url, '/movies/narnia.mp4', '~> executing pattern on correct trimming');
687+
t.is(title, 'narnia', '~> executing pattern gives correct "title" value');
688+
689+
// exec results, named object
690+
t.toExec(rgx, '/movies/narnia.mp4', { title: 'narnia' });
691+
t.toExec(rgx, '/movies/narnia.mp4/', { title: 'narnia' });
692+
693+
t.end();
694+
});
695+
696+
test('(RegExp) param :: suffices', t => {
697+
let rgx = /^\/movies[/](?<title>\w+)\.(mp4|mov)/i;
698+
let { keys, pattern } = fn(rgx);
699+
t.same(keys, false, '~> keys = false');
700+
t.same(rgx, pattern, '~> pattern = input');
701+
702+
// RegExp testing (not regexparam related)
703+
t.false(pattern.test('/movies'));
704+
t.false(pattern.test('/movies/'));
705+
t.false(pattern.test('/movies/foo'));
706+
t.false(pattern.test('/movies/foo.mp3'));
707+
t.true(pattern.test('/movies/foo.mp4'));
708+
t.true(pattern.test('/movies/foo.mp4/'));
709+
t.true(pattern.test('/movies/foo.mov/'));
710+
711+
// exec results, array access
712+
let [url, title] = pattern.exec('/movies/narnia.mov');
713+
t.is(url, '/movies/narnia.mov', '~> executing pattern on correct trimming');
714+
t.is(title, 'narnia', '~> executing pattern gives correct "title" value');
715+
716+
// exec results, named object
717+
t.toExec(rgx, '/movies/narnia.mov', { title: 'narnia' });
718+
t.toExec(rgx, '/movies/narnia.mov/', { title: 'narnia' });
719+
720+
t.end();
721+
});
722+
723+
test('(RegExp) param :: optional', t => {
724+
let rgx = /^\/books[/](?<author>[^/]+)[/]?(?<title>[^/]+)?[/]?$/
725+
let { keys, pattern } = fn(rgx);
726+
t.same(keys, false, '~> keys = false');
727+
t.same(rgx, pattern, '~> pattern = input');
728+
729+
// RegExp testing (not regexparam related)
730+
t.false(pattern.test('/books'));
731+
t.false(pattern.test('/books/'));
732+
t.true(pattern.test('/books/smith'));
733+
t.true(pattern.test('/books/smith/'));
734+
t.true(pattern.test('/books/smith/narnia'));
735+
t.true(pattern.test('/books/smith/narnia/'));
736+
t.false(pattern.test('/books/smith/narnia/reviews'));
737+
t.false(pattern.test('books/smith/narnia'));
738+
739+
// exec results, array access
740+
let [url, author, title] = pattern.exec('/books/smith/narnia/');
741+
t.is(url, '/books/smith/narnia/', '~> executing pattern on correct trimming');
742+
t.is(author, 'smith', '~> executing pattern gives correct value');
743+
t.is(title, 'narnia', '~> executing pattern gives correct value');
744+
745+
// exec results, named object
746+
t.toExec(rgx, '/books/smith/narnia', { author: 'smith', title: 'narnia' });
747+
t.toExec(rgx, '/books/smith/narnia/', { author: 'smith', title: 'narnia' });
748+
t.toExec(rgx, '/books/smith/', { author: 'smith', title: undefined });
749+
750+
t.end();
751+
});
752+
}
766753

767754
test('(RegExp) nameless', t => {
768755
// For whatever reason~

0 commit comments

Comments
 (0)