Skip to content

Commit ac33118

Browse files
committed
improvement(useLocation): Add tests for useLocation function
1 parent 3361352 commit ac33118

File tree

10 files changed

+196
-16
lines changed

10 files changed

+196
-16
lines changed

src/components/useClickAway/useClickAway.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ const testComponent = () => ({
2828
describe('useClickAway', () => {
2929
it('should call document.addEventListener', async () => {
3030
const addEventListenerSpy = jest.spyOn(document, 'addEventListener')
31-
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
3231
expect(addEventListenerSpy).not.toHaveBeenCalled()
32+
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
3333
const wrapper = mount(testComponent())
3434
await wrapper.vm.$nextTick()
3535
expect(addEventListenerSpy).toHaveBeenCalled()

src/components/useGeolocation/stories/useGeolocation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ function useGeolocation(
3838

3939
### Returns
4040

41-
- `isTracking: Ref<boolean>` whether the function is tracking the user's location or not
4241
- `geo: Ref<UseGeolocation>` the geolocation object
42+
- `isTracking: Ref<boolean>` whether the function is tracking the user's location or not
4343
- `start: Function` the function used for starting the geolocation tracking
4444
- `stop: Function` the function used for stopping the geolocation tracking
4545

src/components/useIdle/useIdle.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ describe('useIdle', () => {
2525

2626
it('should call document.addEventListener', async () => {
2727
const addEventListenerSpy = jest.spyOn(document, 'addEventListener')
28-
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
2928
expect(addEventListenerSpy).not.toHaveBeenCalled()
29+
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
3030
const wrapper = mount(testComponent())
3131
await wrapper.vm.$nextTick()
3232
expect(addEventListenerSpy).toHaveBeenCalledTimes(totEvents)

src/components/useLocation/stories/UseLocationDemo.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<button class="button is-primary" @click="push">
1919
Fire push event
2020
</button>
21-
<button class="button is-danger" @click="replace">
21+
<button class="button is-info" @click="replace">
2222
Fire replace event
2323
</button>
2424
</td>

src/components/useLocation/stories/useLocation.md

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,84 @@ Vue function that tracks bar navigation location state.
55
## Reference
66

77
```typescript
8-
// function useLocation()
8+
interface UseLocationState {
9+
trigger: string
10+
state: any
11+
length: number
12+
hash: string
13+
host: string
14+
hostname: string
15+
href: string
16+
origin: string
17+
pathname: string
18+
port: string
19+
protocol: string
20+
search: string
21+
}
22+
```
23+
24+
```typescript
25+
function useLocation(
26+
runOnMount?: boolean
27+
): {
28+
locationState: Ref<UseLocationState>
29+
isTracking: Ref<boolean>
30+
start: () => void
31+
stop: () => void
32+
}
933
```
1034

1135
### Parameters
1236

13-
- `value: string` lorem ipsa
37+
- `runOnMount: boolean` whether to start tracking the bar navigation location state on mount, `true` by default
1438

1539
### Returns
1640

17-
- `value: Ref<string>` lorem ipsa
41+
- `locationState: Ref<object>` the location object
42+
- `isTracking: Ref<UseLocationState>` whether the location state is being currently tracked or not
43+
- `start: Function` the function used for starting the location tracking
44+
- `stop: Function` the function used for stopping the location tracking
1845

1946
## Usage
2047

2148
```html
22-
<template></template>
49+
<template>
50+
<div>
51+
<div>
52+
locationState:
53+
<pre>{{ JSON.stringify(locationState, null, 2) }}</pre>
54+
</div>
55+
<div>
56+
<button @click="push">Fire push event</button>
57+
<button @click="replace">Fire replace event</button>
58+
</div>
59+
<div>
60+
<button @click="start" v-if="!isTracking">Start tracking location</button>
61+
<button @click="stop" v-else>Stop tracking location</button>
62+
</div>
63+
</div>
64+
</template>
65+
66+
<script lang="ts">
67+
import Vue from 'vue'
68+
import { useLocation } from 'vue-use-kit'
69+
70+
export default Vue.extend({
71+
name: 'UseLocationDemo',
72+
setup() {
73+
let count = 0
74+
const url = location.origin + location.pathname + location.search
75+
const push = () => {
76+
count++
77+
history.pushState({ page: count }, '', `${url}&page=${count}`)
78+
}
79+
const replace = () => {
80+
count--
81+
history.replaceState({ page: count }, '', `${url}&page=${count}`)
82+
}
83+
const { locationState, isTracking, start, stop } = useLocation()
84+
return { locationState, isTracking, start, stop, push, replace }
85+
}
86+
})
87+
</script>
2388
```

src/components/useLocation/stories/useLocation.story.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@ const basicDemo = () => ({
1717
demo-name="UseLocationDemo.vue"
1818
>
1919
<template v-slot:title></template>
20-
<template v-slot:intro></template>
20+
<template v-slot:intro>
21+
<p>
22+
<strong>Try pressing the 'Fire push event' and 'Fire replace event' buttons</strong> to see the state change
23+
on the fly.
24+
</p>
25+
<p>
26+
<strong>Please note that in this demo you won't see the browser's bar navigation change</strong>
27+
because this example is within an iframe. Click the "Open canvas in new tab" button on the
28+
top right hand corner to see the demo without iframe.
29+
</p>
30+
</template>
2131
</story-title>
2232
<demo />
2333
</div>`
Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,100 @@
1-
// import { mount } from '@src/helpers/test'
2-
// import { useLocation } from '@src/vue-use-kit'
1+
import { mount } from '@src/helpers/test'
2+
import { useLocation } from '@src/vue-use-kit'
33

44
afterEach(() => {
55
jest.clearAllMocks()
66
})
77

8+
const testComponent = (onMount = true) => ({
9+
template: `
10+
<div>
11+
<div id="isTracking" v-if="isTracking"></div>
12+
<div id="locationState">{{JSON.stringify(locationState)}}</div>
13+
<button id="start" @click="start"></button>
14+
<button id="stop" @click="stop"></button>
15+
</div>
16+
`,
17+
setup() {
18+
const { locationState, isTracking, start, stop } = useLocation(onMount)
19+
return { locationState, isTracking, start, stop }
20+
}
21+
})
22+
823
describe('useLocation', () => {
9-
it('should do something', () => {
10-
// Add test here
24+
const locationStateKeys = [
25+
'trigger',
26+
'state',
27+
'length',
28+
'hash',
29+
'host',
30+
'hostname',
31+
'href',
32+
'origin',
33+
'pathname',
34+
'port',
35+
'protocol',
36+
'search'
37+
]
38+
const events = ['popstate', 'pushstate', 'replacestate']
39+
40+
it('should call popstate, pushstate and replacestate onMounted', async () => {
41+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener')
42+
expect(addEventListenerSpy).not.toHaveBeenCalled()
43+
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener')
44+
const wrapper = mount(testComponent())
45+
await wrapper.vm.$nextTick()
46+
expect(addEventListenerSpy).toHaveBeenCalledTimes(events.length)
47+
events.forEach(event => {
48+
expect(addEventListenerSpy).toBeCalledWith(event, expect.any(Function))
49+
})
50+
51+
// Destroy instance to check if the remove event listener is being called
52+
wrapper.destroy()
53+
expect(removeEventListenerSpy).toHaveBeenCalledTimes(events.length)
54+
events.forEach(event => {
55+
expect(removeEventListenerSpy).toBeCalledWith(event, expect.any(Function))
56+
})
57+
})
58+
59+
it('should call document.addEventListener again when start is called', async () => {
60+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener')
61+
const wrapper = mount(testComponent())
62+
expect(addEventListenerSpy).toHaveBeenCalledTimes(events.length)
63+
wrapper.find('#stop').trigger('click')
64+
65+
// Wait for Vue to append #start in the DOM
66+
await wrapper.vm.$nextTick()
67+
wrapper.find('#start').trigger('click')
68+
expect(addEventListenerSpy).toHaveBeenCalledTimes(events.length * 2)
69+
})
70+
71+
it('should call document.removeEventListener when stop is called', async () => {
72+
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener')
73+
const wrapper = mount(testComponent())
74+
wrapper.find('#stop').trigger('click')
75+
76+
// Wait for Vue to append #start in the DOM
77+
await wrapper.vm.$nextTick()
78+
expect(removeEventListenerSpy).toHaveBeenCalledTimes(events.length)
79+
})
80+
81+
it('should show #isTracking when onMount is true', async () => {
82+
const wrapper = mount(testComponent(true))
83+
await wrapper.vm.$nextTick()
84+
expect(wrapper.find('#isTracking').exists()).toBe(true)
85+
})
86+
87+
it('should not show #isTracking when onMount is false', async () => {
88+
const wrapper = mount(testComponent(false))
89+
await wrapper.vm.$nextTick()
90+
expect(wrapper.find('#isTracking').exists()).toBe(false)
91+
})
92+
93+
it('should display the locationState object', async () => {
94+
const wrapper = mount(testComponent(true))
95+
await wrapper.vm.$nextTick()
96+
locationStateKeys.forEach(locationKey => {
97+
expect(wrapper.text().includes(locationKey)).toBe(true)
98+
})
1199
})
12100
})

src/components/useLocation/useLocation.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import { ref, onMounted, onUnmounted, Ref } from '@src/api'
22

3+
export interface UseLocationState {
4+
trigger: string
5+
state: any
6+
length: number
7+
hash: string
8+
host: string
9+
hostname: string
10+
href: string
11+
origin: string
12+
pathname: string
13+
port: string
14+
protocol: string
15+
search: string
16+
}
17+
318
// The history methods 'pushState' and 'replaceState' by default do not fire an event
419
// unless it is coming from user interaction with the browser navigation bar,
520
// so we are adding a patch to make them detectable
@@ -54,7 +69,7 @@ export function useLocation(runOnMount = true) {
5469
}
5570
}
5671
const isTracking = ref(false)
57-
const locationState = ref(buildState('load'))
72+
const locationState: Ref<UseLocationState> = ref(buildState('load'))
5873

5974
const popState = () => (locationState.value = buildState('popstate'))
6075
const pushState = () => (locationState.value = buildState('pushstate'))
@@ -65,6 +80,8 @@ export function useLocation(runOnMount = true) {
6580

6681
if (isTracking.value) return
6782
isTracking.value = true
83+
84+
locationState.value = buildState('start')
6885
window.addEventListener('popstate', popState)
6986
window.addEventListener('pushstate', pushState)
7087
window.addEventListener('replacestate', replaceState)

src/components/useMouse/useMouse.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const testComponent = () => ({
2121
describe('useMouse', () => {
2222
it('should call document.addEventListener', async () => {
2323
const addEventListenerSpy = jest.spyOn(document, 'addEventListener')
24-
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
2524
expect(addEventListenerSpy).not.toHaveBeenCalled()
25+
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
2626
const wrapper = mount(testComponent())
2727
await wrapper.vm.$nextTick()
2828
expect(addEventListenerSpy).toHaveBeenCalledTimes(1)

src/components/useMouseElement/useMouseElement.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ const testComponent = () => ({
3838
describe('useMouseElement', () => {
3939
it('should call document.addEventListener', async () => {
4040
const addEventListenerSpy = jest.spyOn(document, 'addEventListener')
41-
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
4241
expect(addEventListenerSpy).not.toHaveBeenCalled()
42+
const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener')
4343
const wrapper = mount(testComponent())
4444
await wrapper.vm.$nextTick()
4545
expect(addEventListenerSpy).toHaveBeenCalledTimes(1)

0 commit comments

Comments
 (0)