Skip to content

Commit 4415a81

Browse files
committed
add tests
1 parent 0f72bd3 commit 4415a81

File tree

3 files changed

+186
-18
lines changed

3 files changed

+186
-18
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ node_modules
99

1010
# logs
1111
npm-debug.log
12+
13+
# coverage
14+
coverage

package.json

+24-18
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,22 @@
33
"version": "1.0.32",
44
"description": "Universal named routes for next.js",
55
"repository": "fridays/next-routes",
6-
"main": "dist/index.js",
6+
"main": "dist",
77
"files": [
88
"dist"
99
],
1010
"scripts": {
11-
"build": "babel src --out-dir dist",
12-
"prepublish": "npm run build",
13-
"lint": "standard 'src/*'",
14-
"test": "npm run lint"
11+
"build": "del dist && babel src --out-dir dist",
12+
"lint": "standard 'src/*' 'test/*'",
13+
"pretest": "npm run lint",
14+
"test": "jest \\.test.js --coverage",
15+
"watch": "nodemon -w src -x 'npm run build && npm run test -- --watch'",
16+
"prepare": "npm run build && npm run test",
17+
"preversion": "npm run prepare"
1518
},
1619
"standard": {
1720
"parser": "babel-eslint"
1821
},
19-
"keywords": [
20-
"next",
21-
"next.js",
22-
"react",
23-
"route",
24-
"router",
25-
"routes",
26-
"routing"
27-
],
28-
"author": "fridays",
29-
"license": "MIT",
3022
"dependencies": {
3123
"path-to-regexp": "^1.7.0"
3224
},
@@ -38,10 +30,24 @@
3830
"babel-cli": "^6.24.1",
3931
"babel-eslint": "^7.2.3",
4032
"babel-preset-env": "^1.5.2",
33+
"del-cli": "^1.1.0",
34+
"jest": "^20.0.4",
4135
"next": "^2.4.4",
42-
"pre-commit": "^1.2.2",
36+
"nodemon": "^1.11.0",
4337
"react": "^15.6.1",
4438
"react-dom": "^15.6.1",
39+
"react-test-renderer": "^15.6.1",
4540
"standard": "^10.0.2"
46-
}
41+
},
42+
"author": "fridays",
43+
"license": "MIT",
44+
"keywords": [
45+
"next",
46+
"next.js",
47+
"react",
48+
"route",
49+
"router",
50+
"routes",
51+
"routing"
52+
]
4753
}

test/index.test.js

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/* global jest, describe, test, expect */
2+
import React from 'react'
3+
import ReactShallowRenderer from 'react-test-renderer/shallow'
4+
import NextLink from 'next/link'
5+
import nextRoutes from '../dist/index'
6+
7+
const renderer = new ReactShallowRenderer()
8+
9+
const setupRoute = (...args) => {
10+
const routes = nextRoutes().add(...args)
11+
const route = routes.routes[routes.routes.length - 1]
12+
return {routes, route}
13+
}
14+
15+
describe('Routes', () => {
16+
const setup = (...args) => {
17+
const {routes, route} = setupRoute(...args)
18+
const testRoute = expected => expect(route).toMatchObject(expected)
19+
return {routes, route, testRoute}
20+
}
21+
22+
test('add with name', () => {
23+
setup('a').testRoute({name: 'a', pattern: '/a', page: '/a'})
24+
})
25+
26+
test('add with name and pattern', () => {
27+
setup('a', '/:a').testRoute({name: 'a', pattern: '/:a', page: '/a'})
28+
})
29+
30+
test('add with name, pattern and page', () => {
31+
setup('a', '/:a', 'b').testRoute({name: 'a', pattern: '/:a', page: '/b'})
32+
})
33+
34+
test('add with pattern and page', () => {
35+
setup('/:a', 'b').testRoute({name: null, pattern: '/:a', page: '/b'})
36+
})
37+
38+
test('add with only pattern throws', () => {
39+
expect(() => setup('/:a')).toThrow()
40+
})
41+
42+
test('match and merge params into query', () => {
43+
const routes = nextRoutes().add('a').add('b', '/b/:b').add('c')
44+
expect(routes.match('/b/b?b=x&c=c').query).toMatchObject({b: 'b', c: 'c'})
45+
})
46+
47+
test('generate urls from params', () => {
48+
const {route} = setup('a', '/a/:b/:c+')
49+
const params = {b: 'b', c: [1, 2], d: 'd'}
50+
const expected = {as: '/a/b/1/2?d=d', href: '/a?b=b&c=1%2F2&d=d'}
51+
expect(route.getLinkProps(params)).toEqual(expected)
52+
expect(setup('a').route.getLinkProps()).toEqual({as: '/a', href: '/a?'})
53+
})
54+
55+
test('with custom Link and Router', () => {
56+
const CustomLink = () => <div />
57+
const CustomRouter = {}
58+
const {Link, Router} = nextRoutes({Link: CustomLink, Router: CustomRouter})
59+
expect(renderer.render(<Link />).type).toBe(CustomLink)
60+
expect(Router).toBe(CustomRouter)
61+
})
62+
})
63+
64+
describe('Request handler', () => {
65+
const setup = url => {
66+
const routes = nextRoutes()
67+
const nextHandler = jest.fn()
68+
const app = {getRequestHandler: () => nextHandler, render: jest.fn()}
69+
return {app, routes, req: {url}, res: {}}
70+
}
71+
72+
test('find route and call render', () => {
73+
const {routes, app, req, res} = setup('/a')
74+
const {route, query} = routes.add('a').match('/a')
75+
routes.getRequestHandler(app)(req, res)
76+
expect(app.render).toBeCalledWith(req, res, route.page, query)
77+
})
78+
79+
test('find route and call custom handler', () => {
80+
const {routes, app, req, res} = setup('/a')
81+
const {route, query} = routes.add('a').match('/a')
82+
const customHandler = jest.fn()
83+
const expected = expect.objectContaining({req, res, route, query})
84+
routes.getRequestHandler(app, customHandler)(req, res)
85+
expect(customHandler).toBeCalledWith(expected)
86+
})
87+
88+
test('find no route and call next handler', () => {
89+
const {routes, app, req, res} = setup('/a')
90+
const {parsedUrl} = routes.match('/a')
91+
routes.getRequestHandler(app)(req, res)
92+
expect(app.getRequestHandler()).toBeCalledWith(req, res, parsedUrl)
93+
})
94+
})
95+
96+
describe('Link', () => {
97+
const setup = (...args) => {
98+
const {routes, route} = setupRoute(...args)
99+
const {Link} = routes
100+
const props = {children: <a>hello</a>}
101+
const testLink = (addProps, expected) => {
102+
const actual = renderer.render(<Link {...props} {...addProps} />)
103+
expect(actual.type).toBe(NextLink)
104+
expect(actual.props).toEqual({...props, ...expected})
105+
}
106+
return {routes, route, testLink}
107+
}
108+
109+
test('with name and params', () => {
110+
const {route, testLink} = setup('a', '/a/:b')
111+
testLink({route: 'a', params: {b: 'b'}}, route.getLinkProps({b: 'b'}))
112+
})
113+
114+
test('with route url', () => {
115+
const {routes, route, testLink} = setup('/a/:b', 'a')
116+
testLink({route: '/a/b'}, route.getLinkProps(routes.match('/a/b').query))
117+
})
118+
119+
test('with route not found', () => {
120+
setup('a').testLink({route: '/b'}, {href: '/b'})
121+
})
122+
123+
test('without route', () => {
124+
setup('a').testLink({href: '/'}, {href: '/'})
125+
})
126+
})
127+
128+
const routerMethods = ['push', 'replace', 'prefetch']
129+
130+
describe(`Router ${routerMethods.join(', ')}`, () => {
131+
const setup = (...args) => {
132+
const {routes, route} = setupRoute(...args)
133+
const testMethods = (args, expected) => {
134+
routerMethods.forEach(method => {
135+
const Router = routes.getRouter({[method]: jest.fn()})
136+
Router[`${method}Route`](...args)
137+
expect(Router[method]).toBeCalledWith(...expected)
138+
})
139+
}
140+
return {routes, route, testMethods}
141+
}
142+
143+
test('with name and params', () => {
144+
const {route, testMethods} = setup('a', '/a/:b')
145+
const {as, href} = route.getLinkProps({b: 'b'})
146+
testMethods(['a', {b: 'b'}, {}], [href, as, {}])
147+
})
148+
149+
test('with route url', () => {
150+
const {routes, testMethods} = setup('/a', 'a')
151+
const {route, query} = routes.match('/a')
152+
const {as, href} = route.getLinkProps(query)
153+
testMethods(['/a', {}], [href, as, {}])
154+
})
155+
156+
test('with route not found', () => {
157+
setup('a').testMethods(['/b', {}], ['/b', '/b', {}])
158+
})
159+
})

0 commit comments

Comments
 (0)