Skip to content

Commit b7aba7f

Browse files
author
lmhcoding
committed
Merge branch 'test-useWindowScroll'
2 parents 2b2b89f + e42c5dc commit b7aba7f

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed

src/useHistory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { reactive, toRefs, ToRefs, UnwrapRef } from 'vue'
22
import { useEvent } from './useEvent'
3-
import { def } from './util'
3+
import { def, isClient } from './util'
44

55
type PathMethod = Extract<keyof History, 'replaceState' | 'pushState'>
66

@@ -22,7 +22,7 @@ function patchHistoryMethod(method: PathMethod): void {
2222
)
2323
}
2424

25-
if (typeof window !== 'undefined') {
25+
if (isClient) {
2626
patchHistoryMethod('pushState')
2727
patchHistoryMethod('replaceState')
2828
}

src/useWindowScroll.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ref, readonly, DeepReadonly, Ref } from 'vue'
22
import { useEvent } from './useEvent'
33
import { throttle } from 'throttle-debounce'
4+
import { isClient } from './util'
45

56
export interface IWindowScrollState {
67
x: DeepReadonly<Ref<number>>
@@ -9,8 +10,8 @@ export interface IWindowScrollState {
910
}
1011

1112
export function useWindowScroll(delay = 200): IWindowScrollState {
12-
const x = ref(0)
13-
const y = ref(0)
13+
const x = ref(isClient ? window.scrollX : 0)
14+
const y = ref(isClient ? window.scrollY : 0)
1415
let cb = () => {
1516
x.value = window.scrollX
1617
y.value = window.scrollY

src/util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ export function tryOnUnmounted(cb: () => any): void {
4242
onUnmounted(cb)
4343
}
4444
}
45+
46+
export const isClient = typeof window !== 'undefined'

tests/useWindowScroll.test.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { VueWrapper } from '@vue/test-utils'
2+
import { DeepReadonly, Ref } from 'vue'
3+
import { useWindowScroll } from '../src/useWindowScroll'
4+
import { invokeHook } from './util'
5+
6+
let wrapper: VueWrapper<any>
7+
let x: DeepReadonly<Ref<number>>
8+
let y: DeepReadonly<Ref<number>>
9+
let clear: () => void
10+
11+
function patchWindow () {
12+
let x = 200
13+
let y = 300
14+
const originAdd = window.addEventListener
15+
const originRemove = window.removeEventListener
16+
const originDispatch = window.dispatchEvent
17+
const addEventListener = jest.fn(function (event, cb, options) {
18+
originAdd.call(addEventListener.mock.instances[0], event, cb, options)
19+
})
20+
const removeEventListener = jest.fn(function (event, cb, options) {
21+
originRemove.call(removeEventListener.mock.instances[0], event, cb, options)
22+
})
23+
window.addEventListener = addEventListener
24+
window.removeEventListener = removeEventListener
25+
Object.defineProperties(window, {
26+
scrollX: {
27+
get () {
28+
return x
29+
}
30+
},
31+
scrollY: {
32+
get () {
33+
return y
34+
}
35+
}
36+
})
37+
const dispatchEvent = jest.fn(function (e: Event) {
38+
if (e.type === 'scroll') {
39+
x = 1000
40+
y = 700
41+
originDispatch.call(dispatchEvent.mock.instances[0], e)
42+
}
43+
})
44+
window.dispatchEvent = dispatchEvent as any
45+
return () => {
46+
x = 200
47+
y = 300
48+
}
49+
}
50+
51+
const reset = patchWindow()
52+
53+
function testWindowScroll (description: string, delay = 200) {
54+
describe(description, () => {
55+
beforeEach(() => {
56+
jest.useFakeTimers()
57+
wrapper = invokeHook(() => {
58+
const res = useWindowScroll(delay)
59+
x = res.x
60+
y = res.y
61+
clear = res.clear
62+
})
63+
})
64+
65+
afterEach(() => {
66+
jest.useRealTimers()
67+
jest.clearAllMocks()
68+
})
69+
70+
afterEach(() => {
71+
reset()
72+
})
73+
test('window.addEventListener should be called when mounted', () => {
74+
expect(window.addEventListener).toHaveBeenCalledTimes(1)
75+
expect(window.addEventListener).toHaveBeenCalledWith('scroll', expect.any(Function), {
76+
capture: false,
77+
passive: true
78+
})
79+
})
80+
81+
test('width/height should not be undefined', () => {
82+
expect(x).toBeDefined()
83+
expect(y).toBeDefined()
84+
expect(x.value).toBe(200)
85+
expect(y.value).toBe(300)
86+
})
87+
88+
test('x / y should be changed when resized', () => {
89+
window.dispatchEvent(new Event('scroll'))
90+
delay && jest.advanceTimersByTime(200)
91+
expect(x.value).toBe(1000)
92+
expect(y.value).toBe(700)
93+
})
94+
95+
test('window.removeEventListener should be called when unmounted', () => {
96+
wrapper.unmount()
97+
expect(window.removeEventListener).toHaveBeenCalledTimes(1)
98+
expect(window.removeEventListener).toHaveBeenCalledWith('scroll', expect.any(Function), {
99+
capture: false,
100+
passive: true
101+
})
102+
})
103+
test('window.removeEventListener should be called when called clear', () => {
104+
clear()
105+
expect(window.removeEventListener).toHaveBeenCalledTimes(1)
106+
expect(window.removeEventListener).toHaveBeenCalledWith('scroll', expect.any(Function), {
107+
capture: false,
108+
passive: true
109+
})
110+
})
111+
})
112+
}
113+
114+
testWindowScroll('test useWindowScroll with throttle')
115+
testWindowScroll('test useWindowScroll without throttle')

0 commit comments

Comments
 (0)