Skip to content

Commit f0da294

Browse files
committed
feat: stub components
1 parent 8ba4439 commit f0da294

File tree

4 files changed

+87
-56
lines changed

4 files changed

+87
-56
lines changed

README.md

+14-41
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,29 @@
11
# vue-router-mock [![Build Status](https://badgen.net/circleci/github/posva/vue-router-mock/v2)](https://circleci.com/gh/posva/vue-router-mock) [![npm package](https://badgen.net/npm/v/vue-router-mock)](https://www.npmjs.com/package/vue-router-mock) [![coverage](https://badgen.net/codecov/c/github/posva/vue-router-mock/v2)](https://codecov.io/github/posva/vue-router-mock) [![thanks](https://badgen.net/badge/thanks/♥/pink)](https://github.com/posva/thanks)
22

3-
> Some awesome description
3+
> Easily mock routing interactions in your Vue apps
44
5-
Demo (TODO link)
6-
7-
## Copying this project
8-
9-
You can directly create a project from this template by using the [Use this template button](https://github.com/posva/vue-ts-lib/generate) if you plan on hosting it on GitHub.
10-
11-
You can also use [degit](https://github.com/Rich-Harris/degit):
12-
13-
```sh
14-
degit posva/vue-ts-lib
15-
```
16-
17-
### Checklist of things to do when creating a lib
18-
19-
#### Rename the project
5+
## Installation
206

217
```sh
22-
sed -i '' 's/vue-router-mock/vue-global-events/g' README.md package.json .github/workflows/release-tag.yml size-checks/*
8+
yarn add vue-router-mock@next
9+
# or
10+
npm install vue-router-mock@next
2311
```
2412

25-
#### Circle CI
26-
27-
- Add the project: https://circleci.com/projects/gh/posva
28-
- Check _Build on forked pull requests_: https://circleci.com/gh/posva/vue-router-mock/edit#advanced-settings
29-
- Check _Auto cancel redundant build_ (same place)
30-
31-
## Dependabot
32-
33-
- Activate it: https://docs.github.com/en/github/administering-a-repository/enabling-and-disabling-version-updates
34-
- Or use dependabot.com
35-
36-
## Github Settings
37-
38-
- Activate Sponsor section
13+
## Usage
3914

40-
## Remove this section
15+
### Stubs
4116

42-
Remove the section _Checklist_ before releasing.
17+
By default, both `<router-link>` and `<router-view>` are stubbed but you can override them locally. This is specially useful when you have nested `<router-view>` and you rely on them for a test:
4318

44-
## Installation
45-
46-
```sh
47-
yarn add vue-router-mock
48-
# or
49-
npm install vue-router-mock
19+
```js
20+
const wrapper = mount(MyComponent, {
21+
global: {
22+
stubs: { RouterView: MyNestedComponent },
23+
},
24+
})
5025
```
5126

52-
## Usage
53-
5427
## API
5528

5629
## Related

__tests__/components.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { mount } from '@vue/test-utils'
2+
import { addGlobalInjections, createMockedRouter } from '../src'
3+
4+
describe('components', () => {
5+
beforeAll(() => {
6+
const router = createMockedRouter()
7+
addGlobalInjections(router)
8+
})
9+
10+
it('stubs router link', async () => {
11+
const wrapper = mount(
12+
{
13+
template: `<router-link>Hello</router-link>`,
14+
}
15+
// { global: { stubs: { RouterLink: true } } }
16+
)
17+
18+
expect(wrapper.html()).toMatchInlineSnapshot(
19+
`"<router-link>Hello</router-link>"`
20+
)
21+
})
22+
})

__tests__/navigations.spec.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { addGlobalInjections, createMockedRouter } from '../src'
33
import Test from './fixtures/Test'
44

55
describe('Navigations', () => {
6+
const router = createMockedRouter()
67
beforeAll(() => {
7-
const router = createMockedRouter()
88
addGlobalInjections(router)
99
})
1010

@@ -28,4 +28,18 @@ describe('Navigations', () => {
2828
const wrapper = mount(Test)
2929
expect(wrapper.vm.$router.push).toHaveBeenCalledTimes(0)
3030
})
31+
32+
it('rejects next navigation with an error', async () => {
33+
const wrapper = mount(Test)
34+
const error = new Error('fail')
35+
router.failNextNavigation(error)
36+
await expect(wrapper.vm.$router.push('/foo')).rejects.toBe(error)
37+
})
38+
39+
it('can abort the next navigation', async () => {
40+
const wrapper = mount(Test)
41+
const error = new Error('fail')
42+
router.failNextNavigation(error)
43+
expect(wrapper.vm.$router.push).toHaveBeenCalledTimes(0)
44+
})
3145
})

src/index.ts

+36-14
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
import {
22
createRouter,
33
createWebHashHistory,
4+
isNavigationFailure,
45
routeLocationKey,
56
RouteLocationNormalizedLoaded,
7+
RouteLocationRaw,
68
Router,
79
routerKey,
810
} from 'vue-router'
911
import { config, VueWrapper } from '@vue/test-utils'
1012
import { computed, ComputedRef, reactive, Ref } from 'vue'
1113

12-
export function routerMockPlugin(wrapper: VueWrapper<any>) {
13-
const router = createMockedRouter()
14-
15-
// console.log('plugins', config.global.plugins)
16-
// config.global.plugins.push(router)
17-
console.log('hey')
18-
19-
addGlobalInjections(router)
20-
14+
export function routerMockPlugin(
15+
wrapper: VueWrapper<any>,
16+
{ router }: { router: Router }
17+
) {
2118
return {}
2219
}
2320

@@ -51,14 +48,12 @@ export function createMockedRouter() {
5148

5249
const pushMock = jest.fn((to) => {
5350
router.currentRoute.value = router.resolve(to)
54-
// resolve pending navigation failure
55-
return Promise.resolve()
51+
return consumeNavigationFailure()
5652
})
5753

5854
const replaceMock = jest.fn((to) => {
5955
router.currentRoute.value = router.resolve(to)
60-
// resolve pending navigation failure
61-
return Promise.resolve()
56+
return consumeNavigationFailure()
6257
})
6358

6459
router.push = pushMock
@@ -69,7 +64,34 @@ export function createMockedRouter() {
6964
replaceMock.mockClear()
7065
})
7166

72-
return router
67+
let nextFailure: Error | boolean | RouteLocationRaw | undefined = undefined
68+
69+
function failNextNavigation(
70+
failure: Error | boolean | RouteLocationRaw | undefined
71+
) {
72+
nextFailure = failure
73+
}
74+
75+
function consumeNavigationFailure() {
76+
let p: Promise<any> = Promise.resolve()
77+
78+
if (nextFailure) {
79+
if (isNavigationFailure(nextFailure)) {
80+
p = Promise.resolve(nextFailure)
81+
} else {
82+
p = Promise.reject(nextFailure)
83+
}
84+
}
85+
86+
nextFailure = undefined
87+
88+
return p
89+
}
90+
91+
return {
92+
...router,
93+
failNextNavigation,
94+
}
7395
}
7496

7597
function createReactiveRouteLocation(

0 commit comments

Comments
 (0)