Skip to content

Commit 0896539

Browse files
committed
feat: allow suffix matching
1 parent 41e208d commit 0896539

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export default function (str) {
2-
var c, o, tmp, keys=[], pattern='', arr=str.split('/');
2+
var c, o, tmp, ext, keys=[], pattern='', arr=str.split('/');
33
arr[0] || arr.shift();
44

55
while (tmp = arr.shift()) {
@@ -8,9 +8,11 @@ export default function (str) {
88
keys.push('wild');
99
pattern += '/(.*)';
1010
} else if (c === ':') {
11-
o = tmp[tmp.length - 1] === '?'; // optional?
12-
keys.push( tmp.substring(1, o ? tmp.length - 1 : tmp.length) );
13-
pattern += o ? '(?:/([^/]+?))?' : '/([^/]+?)';
11+
o = tmp.indexOf('?', 1);
12+
ext = tmp.indexOf('.', 1);
13+
keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
14+
pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
15+
if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
1416
} else {
1517
pattern += '/' + tmp;
1618
}

test/index.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,32 @@ test('param :: multiple', t => {
103103
t.end();
104104
});
105105

106+
test('param :: suffix', t => {
107+
let { keys, pattern } = fn('/movies/:title.mp4');
108+
t.same(keys, ['title'], '~> keys has "title" only (no suffix)');
109+
t.false(pattern.test('/movies'), '~> does not match naked base');
110+
t.false(pattern.test('/movies/'), '~> does not match naked base w/ trailing slash');
111+
t.false(pattern.test('/movies/foo'), '~> does not match without suffix');
112+
t.false(pattern.test('/movies/foo.mp3'), '~> does not match with wrong suffix');
113+
t.true(pattern.test('/movies/foo.mp4'), '~> does match with correct suffix');
114+
t.true(pattern.test('/movies/foo.mp4/'), '~> does match with trailing slash');
115+
t.end();
116+
});
117+
118+
test('param :: suffices', t => {
119+
let { keys, pattern } = fn('/movies/:title.(mp4|mov)');
120+
t.same(keys, ['title'], '~> keys has "title" only (no suffix)');
121+
t.false(pattern.test('/movies'), '~> does not match naked base');
122+
t.false(pattern.test('/movies/'), '~> does not match naked base w/ trailing slash');
123+
t.false(pattern.test('/movies/foo'), '~> does not match without suffix');
124+
t.false(pattern.test('/movies/foo.mp3'), '~> does not match with wrong suffix');
125+
t.true(pattern.test('/movies/foo.mp4'), '~> does match with correct suffix (mp4)');
126+
t.true(pattern.test('/movies/foo.mp4/'), '~> does match with trailing slash (mp4)');
127+
t.true(pattern.test('/movies/foo.mov'), '~> does match with correct suffix (mov)');
128+
t.true(pattern.test('/movies/foo.mov/'), '~> does match with trailing slash (mov)');
129+
t.end();
130+
});
131+
106132
test('param :: optional', t => {
107133
let { keys, pattern } = fn('/books/:author/:title?');
108134
t.same(keys, ['author', 'title'], '~> keys has "author" & "title" values');

0 commit comments

Comments
 (0)