f9a2401eba045bb3b0972acac39287a07a907a01
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 PathParameter
= require('../../lib/router/path-parameter')
9 const { DingusError
} = require('../../lib/errors');
11 const noExpectedException
= 'did not get expected exception';
13 describe('Router', function () {
14 const router
= new Router();
15 let _its
; // Save and restore ignoreTrailingSlash
17 beforeEach(function () {
18 _its
= router
.ignoreTrailingSlash
;
21 afterEach(function () {
23 router
.ignoreTrailingSlash
= _its
;
26 describe('_pathToRoutePath', function () {
27 it('defines a simple path', function () {
29 const expected
= ['', 'a', 'b', 'c'];
30 expected
[Router
.kPathMethods
] = {};
31 const r
= router
._pathToRoutePath(p
);
32 assert
.deepStrictEqual(r
, expected
);
34 it('defines a path with parameter', function () {
36 const expected
= ['', 'a', 'b', new PathParameter('c')];
37 expected
[Router
.kPathMethods
] = {};
38 const r
= router
._pathToRoutePath(p
);
39 assert
.deepStrictEqual(r
, expected
);
41 it('defines a path with trailing slash', function () {
42 router
.ignoreTrailingSlash
= true;
44 const expected
= ['', 'a', 'b', new PathParameter('c')];
45 expected
[Router
.kPathMethods
] = {};
46 const r
= router
._pathToRoutePath(p
);
47 assert
.deepStrictEqual(r
, expected
);
49 it('defines a path with escaped parameter', function () {
50 const p
= '/a/\\:b/c';
51 const expected
= ['', 'a', ':b', 'c'];
52 expected
[Router
.kPathMethods
] = {};
53 const r
= router
._pathToRoutePath(p
);
54 assert
.deepStrictEqual(r
, expected
);
56 }); // _pathToRoutePath
58 describe('_pathCompareExact', function () {
59 let fixedPath
, checkPath
;
61 it('compares static paths which match', function () {
62 fixedPath
= router
._pathToRoutePath('/a/b/c');
63 checkPath
= router
._pathToRoutePath('/a/b/c');
64 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
65 assert
.strictEqual(r
, true);
67 it('compares static paths which do not match', function () {
68 fixedPath
= router
._pathToRoutePath('/a/b/c');
69 checkPath
= router
._pathToRoutePath('/a/b/d');
70 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
71 assert
.strictEqual(r
, false);
73 it('compares unequal static paths', function () {
74 fixedPath
= router
._pathToRoutePath('/a/b/c');
75 checkPath
= router
._pathToRoutePath('/a/b');
76 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
77 assert
.strictEqual(r
, false);
79 it('compares param paths which match', function () {
80 fixedPath
= router
._pathToRoutePath('/a/:b/c');
81 checkPath
= router
._pathToRoutePath('/a/:b/c');
82 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
83 assert
.strictEqual(r
, true);
85 it('compares param paths which do not match', function () {
86 fixedPath
= router
._pathToRoutePath('/a/:b/c');
87 checkPath
= router
._pathToRoutePath('/a/:g/c');
88 const r
= Router
._pathCompareExact(fixedPath
, checkPath
);
89 assert
.strictEqual(r
, false);
91 }); // _pathCompareExact
93 describe('_pathCompareParam', function () {
94 let fixedPath
, checkPath
;
96 it('compares static paths which match', function () {
98 const expectedParams
= {};
99 fixedPath
= router
._pathToRoutePath('/a/b/c');
100 checkPath
= router
._pathToRoutePath('/a/b/c');
101 const r
= Router
._pathCompareParam(fixedPath
, checkPath
);
102 assert
.strictEqual(r
, true);
103 assert
.deepStrictEqual(params
, expectedParams
);
105 it('compares static paths which do not match', function () {
107 const expectedParams
= {};
108 fixedPath
= router
._pathToRoutePath('/a/b/c');
109 checkPath
= router
._pathToRoutePath('/a/b/d');
110 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
111 assert
.strictEqual(r
, false);
112 assert
.deepStrictEqual(params
, expectedParams
);
114 it('compares unequal static paths', function () {
116 const expectedParams
= {};
117 fixedPath
= router
._pathToRoutePath('/a/b/c');
118 checkPath
= router
._pathToRoutePath('/a/b');
119 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
120 assert
.strictEqual(r
, false);
121 assert
.deepStrictEqual(params
, expectedParams
);
123 it('compares param paths which match', function () {
125 const expectedParams
= {
128 fixedPath
= router
._pathToRoutePath('/a/:b/c');
129 checkPath
= router
._pathToRoutePath('/a/bar/c');
130 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
131 assert
.strictEqual(r
, true);
132 assert
.deepStrictEqual(params
, expectedParams
);
134 it('compares multi param path which match', function () {
136 const expectedParams
= {
140 fixedPath
= router
._pathToRoutePath('/a/:b/:c');
141 checkPath
= router
._pathToRoutePath('/a/gaz/123');
142 const r
= Router
._pathCompareParam(fixedPath
, checkPath
, params
);
143 assert
.strictEqual(r
, true);
144 assert
.deepStrictEqual(params
, expectedParams
);
146 }); // _pathCompareParam
148 describe('_pathFind / _pathFindExact', function () {
149 let pathsByLengthOrig
;
151 beforeEach(function () {
152 pathsByLengthOrig
= router
.pathsByLength
;
153 router
.pathsByLength
= {
154 2: [ router
._pathToRoutePath('/:id') ],
155 3: [ router
._pathToRoutePath('/a/b') ],
158 afterEach(function () {
159 router
.pathsByLength
= pathsByLengthOrig
;
162 describe('_pathFind', function () {
163 it('finds a path', function () {
164 const pathParts
= ['', '46123f1e-bdca-40ee-9f62-93ad38647aa1'];
165 const { matchedPath
, pathParams
} = router
._pathFind(pathParts
);
166 assert
.strictEqual(matchedPath
, router
.pathsByLength
[2][0]);
167 assert
.deepStrictEqual(pathParams
, { id: pathParts
[1] });
169 it('does not find a path', function () {
170 const pathParts
= ['', 'flarp', 'baz'];
171 const { matchedPath
} = router
._pathFind(pathParts
);
172 assert
.strictEqual(matchedPath
, undefined);
176 describe('_pathFindExact', function () {
177 it('finds a path', function () {
178 const pathParts
= ['', new PathParameter('id')];
179 const r
= router
._pathFindExact(pathParts
);
180 assert
.strictEqual(r
, router
.pathsByLength
[2][0]);
182 it('does not find a path', function () {
183 const pathParts
= ['', 'flarp', 'baz'];
184 const r
= router
._pathFindExact(pathParts
);
185 assert
.strictEqual(r
, undefined);
187 }); // _pathFindExact
189 }); // _pathFind / _pathFindExact
191 describe('on', function () {
192 let pathsByLengthOrig
;
193 const stubHandler
= () => {};
195 handler: stubHandler
,
199 beforeEach(function () {
200 pathsByLengthOrig
= router
.pathsByLength
;
201 router
.pathsByLength
= {
202 2: [ router
._pathToRoutePath('/:id') ],
205 afterEach(function () {
206 router
.pathsByLength
= pathsByLengthOrig
;
209 it('adds new path', function () {
210 const urlPath
= '/a/:id';
211 const expected
= router
._pathToRoutePath(urlPath
);
212 expected
[Router
.kPathMethods
]['GET'] = stubEntry
;
213 router
.on('GET', urlPath
, stubHandler
);
214 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
217 it('adds new method to path', function () {
218 const urlPath
= '/a/:id';
219 const expected
= router
._pathToRoutePath(urlPath
);
220 expected
[Router
.kPathMethods
]['GET'] = stubEntry
;
221 expected
[Router
.kPathMethods
]['POST'] = stubEntry
;
222 router
.on('GET', urlPath
, stubHandler
);
224 router
.on('POST', urlPath
, stubHandler
);
225 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
228 it('add some more paths', function () {
229 let urlPath
= '/a/b/c/d';
230 const expected
= router
._pathToRoutePath(urlPath
);
231 expected
[Router
.kPathMethods
]['GET'] = stubEntry
;
232 router
.on('GET', urlPath
, stubHandler
);
233 urlPath
= '/a/b/x/y';
234 router
.on('GET', urlPath
, stubHandler
);
236 assert
.strictEqual(router
.pathsByLength
[5].length
, 2);
239 it('adds multiple methods', function () {
240 const urlPath
= '/:id';
241 const expected
= router
._pathToRoutePath(urlPath
);
242 expected
[Router
.kPathMethods
]['GET'] = stubEntry
;
243 expected
[Router
.kPathMethods
]['HEAD'] = stubEntry
;
245 router
.on(['GET', 'HEAD'], urlPath
, stubHandler
);
246 assert
.deepStrictEqual(router
.pathsByLength
[2][0], expected
);
249 it('adds new wildcard path', function () {
250 const urlPath
= '/a/:id';
251 const expected
= router
._pathToRoutePath(urlPath
);
252 expected
[Router
.kPathMethods
]['*'] = stubEntry
;
253 router
.on('*', urlPath
, stubHandler
);
254 assert
.deepStrictEqual(router
.pathsByLength
[3][0], expected
);
257 it('fails to add unknown method path', function () {
258 const urlPath
= '/a/:id';
260 router
.on('FLARP', urlPath
, stubHandler
);
261 assert
.fail('expected an exception');
263 assert
.strictEqual(e
.name
, 'DingusError');
264 assert
.strictEqual(e
.message
, 'invalid method \'FLARP\'');
268 it('requires args to be array', function () {
269 const urlPath
= '/a';
271 router
.on('GET', urlPath
, stubHandler
, {});
272 assert
.fail('expected an exception');
274 assert(e
instanceof TypeError
);
279 describe('lookup', function () {
280 let pathsByLengthOrig
;
284 beforeEach(function () {
286 pathsByLengthOrig
= router
.pathsByLength
;
287 stubHandler
= sinon
.stub();
289 afterEach(function () {
290 router
.pathsByLength
= pathsByLengthOrig
;
293 it('finds handler', function () {
294 const urlPath
= '/:id';
295 const method
= 'GET';
296 router
.on(method
, urlPath
, stubHandler
);
299 const { handler
} = router
.lookup(method
, path
, ctx
);
300 assert
.strictEqual(handler
, stubHandler
);
302 it('does not find handler with trailing slash', function () {
303 router
.ignoreTrailingSlash
= false;
304 const urlPath
= '/:id';
305 const method
= 'GET';
306 router
.on(method
, urlPath
, stubHandler
);
307 const path
= '/abc/';
310 router
.lookup(method
, path
, ctx
);
311 assert
.fail(noExpectedException
);
313 assert(e
instanceof DingusError
);
314 assert
.strictEqual(e
.message
, 'NoPath');
317 it('finds handler', function () {
318 router
.ignoreTrailingSlash
= true;
319 const urlPath
= '/:id';
320 const method
= 'GET';
321 router
.on(method
, urlPath
, stubHandler
);
322 const path
= '/abc/';
324 const { handler
} = router
.lookup(method
, path
, ctx
);
325 assert
.strictEqual(handler
, stubHandler
);
327 it('finds handler without context', async
function () {
328 const urlPath
= '/:id';
329 const method
= 'GET';
330 router
.on(method
, urlPath
, stubHandler
);
333 const { handler
} = router
.lookup(method
, path
);
334 assert
.strictEqual(handler
, stubHandler
);
336 it('finds fallback handler', async
function () {
337 const urlPath
= '/abc/:id';
338 const method
= 'GET';
339 router
.on('*', urlPath
, stubHandler
);
340 const path
= '/abc/def';
342 const { handler
} = router
.lookup(method
, path
, ctx
);
343 assert
.strictEqual(handler
, stubHandler
);
345 it('calls unsupported method', async
function () {
346 const urlPath
= '/:id';
347 const method
= 'POST';
348 router
.on('GET', urlPath
, stubHandler
);
352 router
.lookup(method
, path
, ctx
);
353 assert
.fail(noExpectedException
);
355 assert(e
instanceof DingusError
);
356 assert
.strictEqual(e
.message
, 'NoMethod');
359 it('does not lookup non-existent path', async
function () {
360 const path
= '/foo/bar';
361 const method
= 'GET';
364 router
.lookup(method
, path
, ctx
);
365 assert
.fail(noExpectedException
);
367 assert(e
instanceof DingusError
);
368 assert
.strictEqual(e
.message
, 'NoPath');