f4c54a997fb26a0adcf944f208dfa1e81cb73fbf
1 /* eslint-disable capitalized-comments */
5 const assert
= require('assert');
6 const sinon
= require('sinon'); // eslint-disable-line node/no-unpublished-require
7 const Router
= require('../../lib/router');
8 const { DingusError
} = require('../../lib/errors');
10 const noExpectedException
= 'did not get expected exception';
12 describe('Router', function () {
13 const router
= new Router();
14 let _its
; // Save and restore ignoreTrailingSlash
16 beforeEach(function () {
17 _its
= router
.ignoreTrailingSlash
;
20 afterEach(function () {
22 router
.ignoreTrailingSlash
= _its
;
25 describe('_pathDefinitionToPathMatch', function () {
26 it('defines a simple path', function () {
28 const expected
= ['', 'a', 'b', 'c'];
29 expected
[router
.METHODS
] = {};
30 const r
= router
._pathDefinitionToPathMatch(p
);
31 assert
.deepStrictEqual(r
, expected
);
33 it('defines a path with parameter', function () {
35 const expected
= ['', 'a', 'b', { [router
.PARAM
]: 'c' }];
36 expected
[router
.METHODS
] = {};
37 const r
= router
._pathDefinitionToPathMatch(p
);
38 assert
.deepStrictEqual(r
, expected
);
40 it('defines a path with trailing slash', function () {
41 router
.ignoreTrailingSlash
= true;
43 const expected
= ['', 'a', 'b', { [router
.PARAM
]: 'c' }];
44 expected
[router
.METHODS
] = {};
45 const r
= router
._pathDefinitionToPathMatch(p
);
46 assert
.deepStrictEqual(r
, expected
);
48 }); // _pathDefinitionToPathMatch
50 describe('_pathCompareExact', function () {
51 let fixedPath
, checkPath
;
53 it('compares static paths which match', function () {
54 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
55 checkPath
= router
._pathDefinitionToPathMatch('/a/b/c');
56 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
57 assert
.strictEqual(r
, true);
59 it('compares static paths which do not match', function () {
60 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
61 checkPath
= router
._pathDefinitionToPathMatch('/a/b/d');
62 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
63 assert
.strictEqual(r
, false);
65 it('compares unequal static paths', function () {
66 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
67 checkPath
= router
._pathDefinitionToPathMatch('/a/b');
68 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
69 assert
.strictEqual(r
, false);
71 it('compares param paths which match', function () {
72 fixedPath
= router
._pathDefinitionToPathMatch('/a/:b/c');
73 checkPath
= router
._pathDefinitionToPathMatch('/a/:b/c');
74 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
75 assert
.strictEqual(r
, true);
77 it('compares param paths which do not match', function () {
78 fixedPath
= router
._pathDefinitionToPathMatch('/a/:b/c');
79 checkPath
= router
._pathDefinitionToPathMatch('/a/:g/c');
80 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
81 assert
.strictEqual(r
, false);
83 }); // _pathCompareExact
85 describe('_pathCompareParam', function () {
86 let fixedPath
, checkPath
;
88 it('compares static paths which match', function () {
90 const expectedParams
= {};
91 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
92 checkPath
= router
._pathDefinitionToPathMatch('/a/b/c');
93 const r
= Router
._pathCompareParam(fixedPath
, checkPath
);
94 assert
.strictEqual(r
, true);
95 assert
.deepStrictEqual(params
, expectedParams
);
97 it('compares static paths which do not match', function () {
99 const expectedParams
= {};
100 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
101 checkPath
= router
._pathDefinitionToPathMatch('/a/b/d');
102 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
103 assert
.strictEqual(r
, false);
104 assert
.deepStrictEqual(params
, expectedParams
);
106 it('compares unequal static paths', function () {
108 const expectedParams
= {};
109 fixedPath
= router
._pathDefinitionToPathMatch('/a/b/c');
110 checkPath
= router
._pathDefinitionToPathMatch('/a/b');
111 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
112 assert
.strictEqual(r
, false);
113 assert
.deepStrictEqual(params
, expectedParams
);
115 it('compares param paths which match', function () {
117 const expectedParams
= {
120 fixedPath
= router
._pathDefinitionToPathMatch('/a/:b/c');
121 checkPath
= router
._pathDefinitionToPathMatch('/a/bar/c');
122 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
123 assert
.strictEqual(r
, true);
124 assert
.deepStrictEqual(params
, expectedParams
);
126 it('compares multi param path which match', function () {
128 const expectedParams
= {
132 fixedPath
= router
._pathDefinitionToPathMatch('/a/:b/:c');
133 checkPath
= router
._pathDefinitionToPathMatch('/a/gaz/123');
134 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
135 assert
.strictEqual(r
, true);
136 assert
.deepStrictEqual(params
, expectedParams
);
138 }); // _pathCompareParam
140 describe('_pathFind / _pathFindExact', function () {
141 let pathsByLengthOrig
;
143 beforeEach(function () {
144 pathsByLengthOrig
= router
.pathsByLength
;
145 router
.pathsByLength
= {
146 2: [ router
._pathDefinitionToPathMatch('/:id') ],
147 3: [ router
._pathDefinitionToPathMatch('/a/b') ],
150 afterEach(function () {
151 router
.pathsByLength
= pathsByLengthOrig
;
154 describe('_pathFind', function () {
155 it('finds a path', function () {
156 const pathParts
= ['', '46123f1e-bdca-40ee-9f62-93ad38647aa1'];
157 const { matchedPath
, pathParams
} = router
._pathFind(pathParts
);
158 assert
.strictEqual(matchedPath
, router
.pathsByLength
[2][0]);
159 assert
.deepStrictEqual(pathParams
, { id: pathParts
[1] });
161 it('does not find a path', function () {
162 const pathParts
= ['', 'flarp', 'baz'];
163 const { matchedPath
} = router
._pathFind(pathParts
);
164 assert
.strictEqual(matchedPath
, undefined);
168 describe('_pathFindExact', function () {
169 it('finds a path', function () {
170 const pathParts
= ['', { [router
.PARAM
]: 'id' }];
171 const r
= router
._pathFindExact(pathParts
);
172 assert
.strictEqual(r
, router
.pathsByLength
[2][0]);
174 it('does not find a path', function () {
175 const pathParts
= ['', 'flarp', 'baz'];
176 const r
= router
._pathFindExact(pathParts
);
177 assert
.strictEqual(r
, undefined);
179 }); // _pathFindExact
181 }); // _pathFind / _pathFindExact
183 describe('on', function () {
184 let pathsByLengthOrig
;
185 const stubHandler
= () => {};
187 beforeEach(function () {
188 pathsByLengthOrig
= router
.pathsByLength
;
189 router
.pathsByLength
= {
190 2: [ router
._pathDefinitionToPathMatch('/:id') ],
193 afterEach(function () {
194 router
.pathsByLength
= pathsByLengthOrig
;
197 it('adds new path', function () {
198 const urlPath
= '/a/:id';
199 const expected
= router
._pathDefinitionToPathMatch(urlPath
);
200 expected
[router
.METHODS
]['GET'] = stubHandler
;
201 router
.on('GET', urlPath
, stubHandler
);
202 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
205 it('adds new method to path', function () {
206 const urlPath
= '/a/:id';
207 const expected
= router
._pathDefinitionToPathMatch(urlPath
);
208 expected
[router
.METHODS
]['GET'] = stubHandler
;
209 expected
[router
.METHODS
]['POST'] = stubHandler
;
210 router
.on('GET', urlPath
, stubHandler
);
212 router
.on('POST', urlPath
, stubHandler
);
213 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
216 it('add some more paths', function () {
217 let urlPath
= '/a/b/c/d';
218 const expected
= router
._pathDefinitionToPathMatch(urlPath
);
219 expected
[router
.METHODS
]['GET'] = stubHandler
;
220 router
.on('GET', urlPath
, stubHandler
);
221 urlPath
= '/a/b/x/y';
222 router
.on('GET', urlPath
, stubHandler
);
224 assert
.strictEqual(router
.pathsByLength
[5].length
, 2);
227 it('adds multiple methods', function () {
228 const urlPath
= '/:id';
229 const expected
= router
._pathDefinitionToPathMatch(urlPath
);
230 expected
[router
.METHODS
]['GET'] = stubHandler
;
231 expected
[router
.METHODS
]['HEAD'] = stubHandler
;
233 router
.on(['GET', 'HEAD'], urlPath
, stubHandler
);
234 assert
.deepStrictEqual(router
.pathsByLength
[2][0], expected
);
237 it('adds new wildcard path', function () {
238 const urlPath
= '/a/:id';
239 const expected
= router
._pathDefinitionToPathMatch(urlPath
);
240 expected
[router
.METHODS
]['*'] = stubHandler
;
241 router
.on('*', urlPath
, stubHandler
);
242 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
245 it('fails to add unknown method path', function () {
246 const urlPath
= '/a/:id';
248 router
.on('FLARP', urlPath
, stubHandler
);
249 assert
.fail('expected an exception');
251 assert
.strictEqual(e
.name
, 'DingusError');
252 assert
.strictEqual(e
.message
, 'invalid method \'FLARP\'');
257 describe('lookup', function () {
258 let pathsByLengthOrig
;
262 beforeEach(function () {
264 pathsByLengthOrig
= router
.pathsByLength
;
265 stubHandler
= sinon
.stub();
267 afterEach(function () {
268 router
.pathsByLength
= pathsByLengthOrig
;
271 it('finds handler', function () {
272 const urlPath
= '/:id';
273 const method
= 'GET';
274 router
.on(method
, urlPath
, stubHandler
);
277 const handler
= router
.lookup(method
, path
, ctx
);
278 assert
.strictEqual(handler
, stubHandler
);
280 it('does not find handler with trailing slash', function () {
281 router
.ignoreTrailingSlash
= false;
282 const urlPath
= '/:id';
283 const method
= 'GET';
284 router
.on(method
, urlPath
, stubHandler
);
285 const path
= '/abc/';
288 router
.lookup(method
, path
, ctx
);
289 assert
.fail(noExpectedException
);
291 assert(e
instanceof DingusError
);
292 assert
.strictEqual(e
.message
, 'NoPath');
295 it('finds handler', function () {
296 router
.ignoreTrailingSlash
= true;
297 const urlPath
= '/:id';
298 const method
= 'GET';
299 router
.on(method
, urlPath
, stubHandler
);
300 const path
= '/abc/';
302 const handler
= router
.lookup(method
, path
, ctx
);
303 assert
.strictEqual(handler
, stubHandler
);
305 it('finds handler without context', async
function () {
306 const urlPath
= '/:id';
307 const method
= 'GET';
308 router
.on(method
, urlPath
, stubHandler
);
311 const handler
= router
.lookup(method
, path
);
312 assert
.strictEqual(handler
, stubHandler
);
314 it('finds fallback handler', async
function () {
315 const urlPath
= '/abc/:id';
316 const method
= 'GET';
317 router
.on('*', urlPath
, stubHandler
);
318 const path
= '/abc/def';
320 const handler
= router
.lookup(method
, path
, ctx
);
321 assert
.strictEqual(handler
, stubHandler
);
323 it('calls unsupported method', async
function () {
324 const urlPath
= '/:id';
325 const method
= 'POST';
326 router
.on('GET', urlPath
, stubHandler
);
330 router
.lookup(method
, path
, ctx
);
331 assert
.fail(noExpectedException
);
333 assert(e
instanceof DingusError
);
334 assert
.strictEqual(e
.message
, 'NoMethod');
337 it('does not lookup nonexistant path', async
function () {
338 const path
= '/foo/bar';
339 const method
= 'GET';
342 router
.lookup(method
, path
, ctx
);
343 assert
.fail(noExpectedException
);
345 assert(e
instanceof DingusError
);
346 assert
.strictEqual(e
.message
, 'NoPath');