Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: setQuery and setHash #47

Merged
merged 2 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ it('should display the user details', async () => {
})
```

It can be awaited if you need to wait for Vue to render again:

```js
it('should display the user details', async () => {
const wrapper = mount(UserDetails)
await getRouter().setParams({ userId: 12 })

// test...
})
```

`setQuery` and `setHash` are very similar.
They can be used to set the route query or hash without triggering a navigation,
and can be awaited too.

### Setting the initial location

By default the router mock starts on [`START_LOCATION`](https://next.router.vuejs.org/api/#start-location). In some scenarios this might need to be adjusted by pushing a new location and awaiting it before testing:
Expand Down
2 changes: 1 addition & 1 deletion __tests__/navigations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ describe('Navigations', () => {
expect(wrapper.text()).toBe('/bar')
})

it.skip('can wait for an ongoing navigation', async () => {
it('can wait for an ongoing navigation', async () => {
const wrapper = mount(Test)
const router = getRouter()

Expand Down
28 changes: 0 additions & 28 deletions __tests__/params.spec.ts

This file was deleted.

80 changes: 80 additions & 0 deletions __tests__/partialLocation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { mount } from '@vue/test-utils'
import { watch } from 'vue'
import { getRouter } from '../src'

describe('partial location', () => {
describe('setParams', () => {
it('sets current route params', async () => {
const router = getRouter()
router.setParams({ userId: 12 })
const wrapper = mount({
template: `<p>{{ $route.params.userId }}</p>`,
})
const spy = jest.fn()

watch(wrapper.vm.$route, spy)

expect(wrapper.vm.$route.params).toEqual({ userId: '12' })
expect(wrapper.text()).toBe('12')
expect(spy).toHaveBeenCalledTimes(0)

await router.setParams({ userId: 12 })
expect(spy).toHaveBeenCalledTimes(1)
expect(wrapper.text()).toBe('12')

await router.setParams({ userId: 2 })
expect(spy).toHaveBeenCalledTimes(2)
expect(wrapper.text()).toBe('2')
})
})

describe('setQuery', () => {
it('sets current route query', async () => {
const router = getRouter()
router.setQuery({ page: 2 })
const wrapper = mount({
template: `<p>{{ $route.query.page }}</p>`,
})
const spy = jest.fn()

watch(wrapper.vm.$route, spy)

expect(wrapper.vm.$route.query).toEqual({ page: '2' })
expect(wrapper.text()).toBe('2')
expect(spy).toHaveBeenCalledTimes(0)

await router.setQuery({ page: 2 })
expect(spy).toHaveBeenCalledTimes(1)
expect(wrapper.text()).toBe('2')

await router.setQuery({ page: 3 })
expect(spy).toHaveBeenCalledTimes(2)
expect(wrapper.text()).toBe('3')
})
})

describe('setHash', () => {
it('sets current route hash', async () => {
const router = getRouter()
router.setHash('#more')
const wrapper = mount({
template: `<p>{{ $route.hash }}</p>`,
})
const spy = jest.fn()

watch(wrapper.vm.$route, spy)

expect(wrapper.vm.$route.hash).toEqual('#more')
expect(wrapper.text()).toBe('#more')
expect(spy).toHaveBeenCalledTimes(0)

await router.setHash('#more')
expect(spy).toHaveBeenCalledTimes(1)
expect(wrapper.text()).toBe('#more')

await router.setHash('#about')
expect(spy).toHaveBeenCalledTimes(2)
expect(wrapper.text()).toBe('#about')
})
})
})
31 changes: 30 additions & 1 deletion src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, nextTick, Ref, ref } from 'vue'
import {
createMemoryHistory,
createRouter,
LocationQueryRaw,
RouteLocationRaw,
RouteParamsRaw,
Router,
Expand Down Expand Up @@ -48,7 +49,23 @@ export interface RouterMock extends Router {
*
* @param params - params to set in the current route
*/
setParams(params: RouteParamsRaw): void
setParams(params: RouteParamsRaw): Promise<void>

/**
* Sets the query of the current route without triggering a navigation. Can
* be awaited to wait for Vue to render again.
*
* @param query - query to set in the current route
*/
setQuery(query: LocationQueryRaw): Promise<void>

/**
* Sets the hash of the current route without triggering a navigation. Can
* be awaited to wait for Vue to render again.
*
* @param hash - hash to set in the current route
*/
setHash(hash: string): Promise<void>
}

export interface RouterMockOptions extends Partial<RouterOptions> {
Expand Down Expand Up @@ -188,6 +205,16 @@ export function createRouterMock(options: RouterMockOptions = {}): RouterMock {
return nextTick()
}

function setQuery(query: LocationQueryRaw) {
router.currentRoute.value = router.resolve({ query })
return nextTick()
}

function setHash(hash: string) {
router.currentRoute.value = router.resolve({ hash })
return nextTick()
}

const depth = ref(0)

return {
Expand All @@ -196,5 +223,7 @@ export function createRouterMock(options: RouterMockOptions = {}): RouterMock {
setNextGuardReturn,
getPendingNavigation,
setParams,
setQuery,
setHash,
}
}