Skip to content

Commit 979bf66

Browse files
authored
test: ✅ unit testing
test: unit testing
2 parents 3ea944b + b2fd6f8 commit 979bf66

File tree

18 files changed

+535
-85
lines changed

18 files changed

+535
-85
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ dist
33
.DS_Store
44
.cache
55
.temp
6+
coverage
67

78

89
# lock

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"build:types": "cd packages/hooks && vue-tsc --noEmit && vite build --mode fullTypes",
1313
"test": "vitest",
1414
"test:ui": "vitest --ui",
15+
"coverage": "vitest run --coverage",
1516
"prepare": "husky install"
1617
},
1718
"devDependencies": {
@@ -35,6 +36,7 @@
3536
"@vue-hooks-plus/vitepress": "1.0.1",
3637
"@vue-hooks-plus/vitepress-demo-block": "^1.2.7",
3738
"@vue/test-utils": "^2.1.0",
39+
"@vitest/coverage-c8":"^0.25.7",
3840
"eslint": "^8.20.0",
3941
"eslint-config-prettier": "^8.5.0",
4042
"eslint-plugin-prettier": "^4.2.1",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import renderHook from 'test-utils/renderHook'
2+
import useNetwork from '../index'
3+
4+
describe('useNetwork', () => {
5+
it('toggle network state', () => {
6+
const [hook] = renderHook(() => useNetwork())
7+
expect(hook.online).toBeTruthy()
8+
})
9+
})
Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,86 @@
1+
/* eslint-disable no-unused-vars */
12
import { watchEffect, ref } from 'vue'
23

34
export interface NetworkState {
4-
since?: Date
5-
online?: boolean
6-
rtt?: number
7-
type?: string
8-
downlink?: number
9-
saveData?: boolean
10-
downlinkMax?: number
11-
effectiveType?: string
5+
since?: Date
6+
online?: boolean
7+
rtt?: number
8+
type?: string
9+
downlink?: number
10+
saveData?: boolean
11+
downlinkMax?: number
12+
effectiveType?: string
1213
}
1314

1415
enum NetworkEventType {
15-
ONLINE = 'online',
16-
OFFLINE = 'offline',
17-
CHANGE = 'change',
16+
ONLINE = 'online',
17+
OFFLINE = 'offline',
18+
CHANGE = 'change',
1819
}
1920

2021
function getConnection() {
21-
const nav = navigator as any
22-
if (typeof nav !== 'object') return null
23-
return nav.connection || nav.mozConnection || nav.webkitConnection
22+
const nav = navigator as any
23+
if (typeof nav !== 'object') return null
24+
return nav.connection || nav.mozConnection || nav.webkitConnection
2425
}
2526

2627
function getConnectionProperty(): NetworkState {
27-
const c = getConnection()
28-
if (!c) return {}
29-
return {
30-
rtt: c.rtt,
31-
type: c.type,
32-
saveData: c.saveData,
33-
downlink: c.downlink,
34-
downlinkMax: c.downlinkMax,
35-
effectiveType: c.effectiveType,
36-
}
28+
const c = getConnection()
29+
if (!c) return {}
30+
return {
31+
rtt: c.rtt,
32+
type: c.type,
33+
saveData: c.saveData,
34+
downlink: c.downlink,
35+
downlinkMax: c.downlinkMax,
36+
effectiveType: c.effectiveType,
37+
}
3738
}
3839

3940
function useNetwork(): NetworkState {
40-
const state = ref({
41-
since: undefined,
42-
online: navigator?.onLine,
43-
...getConnectionProperty(),
44-
})
45-
watchEffect((onInvalidate) => {
46-
const onOnline = () => {
47-
state.value = {
48-
...state.value,
49-
online: true,
50-
since: new Date(),
51-
}
52-
}
41+
const state = ref({
42+
since: undefined,
43+
online: navigator?.onLine,
44+
...getConnectionProperty(),
45+
})
46+
watchEffect(onInvalidate => {
47+
const onOnline = () => {
48+
state.value = {
49+
...state.value,
50+
online: true,
51+
since: new Date(),
52+
}
53+
}
5354

54-
const onOffline = () => {
55-
state.value = {
56-
...state.value,
57-
online: false,
58-
since: new Date(),
59-
}
60-
}
55+
const onOffline = () => {
56+
state.value = {
57+
...state.value,
58+
online: false,
59+
since: new Date(),
60+
}
61+
}
6162

62-
const onConnectionChange = () => {
63-
state.value = {
64-
...state.value,
65-
...getConnectionProperty(),
66-
}
67-
}
63+
const onConnectionChange = () => {
64+
state.value = {
65+
...state.value,
66+
...getConnectionProperty(),
67+
}
68+
}
6869

69-
window.addEventListener(NetworkEventType.ONLINE, onOnline)
70-
window.addEventListener(NetworkEventType.OFFLINE, onOffline)
70+
window.addEventListener(NetworkEventType.ONLINE, onOnline)
71+
window.addEventListener(NetworkEventType.OFFLINE, onOffline)
7172

72-
const connection = getConnection()
73-
connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange)
73+
const connection = getConnection()
74+
connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange)
7475

75-
onInvalidate(() => {
76-
window.removeEventListener(NetworkEventType.ONLINE, onOnline)
77-
window.removeEventListener(NetworkEventType.OFFLINE, onOffline)
78-
connection?.removeEventListener(
79-
NetworkEventType.CHANGE,
80-
onConnectionChange
81-
)
82-
})
83-
})
76+
onInvalidate(() => {
77+
window.removeEventListener(NetworkEventType.ONLINE, onOnline)
78+
window.removeEventListener(NetworkEventType.OFFLINE, onOffline)
79+
connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange)
80+
})
81+
})
8482

85-
return state.value
83+
return state.value
8684
}
8785

8886
export default useNetwork

packages/hooks/src/useRequest/docs/throttle/index.zh-CN.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,7 @@ throttle 所有参数用法和效果同 [lodash.throttle](https://www.lodashjs.c
2929

3030
## 注意
3131

32-
- `options.throttleWait``options.throttleLeading``options.throttleTrailing` 支持动态变化。
32+
- `options.throttleWait` 支持动态变化。
33+
- `options.throttleLeading` 支持动态变化。
34+
- `options.throttleTrailing` 支持动态变化。
3335
- `runAsync` 在真正执行时,会返回 `Promise`。在未被执行时,不会有任何返回。
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import renderHook from 'test-utils/renderHook'
2+
import useSetState from '../index'
3+
4+
describe('useSetState', () => {
5+
const setUp = <T extends object>(initialValue: T) =>
6+
renderHook(() => {
7+
const [state, setState] = useSetState<T>(initialValue)
8+
return {
9+
state,
10+
setState,
11+
} as const
12+
})
13+
14+
it('should support initialValue', () => {
15+
const [hook] = setUp({
16+
hello: 'world',
17+
})
18+
expect(hook.state.value).toEqual({ hello: 'world' })
19+
})
20+
21+
it('should support object', () => {
22+
const [hook] = setUp<any>({
23+
hello: 'world',
24+
})
25+
hook.setState({ foo: 'bar' })
26+
expect(hook.state.value).toEqual({ hello: 'world', foo: 'bar' })
27+
})
28+
29+
it('should support function update', () => {
30+
const [hook] = setUp({
31+
count: 0,
32+
})
33+
hook.setState({ count: hook.state.value.count + 1 })
34+
expect(hook.state.value).toEqual({ count: 1 })
35+
})
36+
})

packages/hooks/src/useSetState/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ref, Ref, unref, UnwrapRef, readonly, DeepReadonly, UnwrapNestedRefs } from 'vue'
2-
import { merge } from 'lodash'
2+
import merge from 'lodash/merge'
33

44
type StateType<S> = S | (() => S) | Ref<S> | (() => Ref<S>)
55

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import renderHook from 'test-utils/renderHook'
2+
import useSize from '../index'
3+
4+
// let callback: (arg0: { target: { clientWidth: number; clientHeight: number } }[]) => void
5+
// vitest.mock('resize-observer-polyfill', () => {
6+
// return vitest.fn().mockImplementation(cb => {
7+
// callback = cb
8+
// return {
9+
// observe: () => {},
10+
// disconnect: () => {},
11+
// }
12+
// })
13+
// })
14+
15+
describe('useSize', () => {
16+
it('should not work when target is null', () => {
17+
renderHook(() => useSize(null))
18+
})
19+
})
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import renderHook from 'test-utils/renderHook'
2+
import { sleep } from 'test-utils/sleep'
3+
import useThrottleFn from '../index'
4+
5+
describe('useThrottleFn', () => {
6+
it('run.value, cancel and flush should work', async () => {
7+
let count = 0
8+
const throttleFn = () => {
9+
count++
10+
}
11+
const [hook] = renderHook(() => useThrottleFn(throttleFn, { wait: 500 }))
12+
hook.run.value()
13+
expect(count).toBe(1)
14+
hook.run.value()
15+
hook.run.value()
16+
hook.run.value()
17+
expect(count).toBe(1)
18+
await sleep(450) // t: 450
19+
hook.run.value()
20+
expect(count).toBe(1)
21+
await sleep(100) // t: 550
22+
hook.run.value()
23+
expect(count).toBe(2)
24+
hook.run.value()
25+
hook.run.value()
26+
await sleep(500) // t: 1050
27+
expect(count).toBe(3)
28+
hook.run.value()
29+
hook.run.value()
30+
hook.cancel()
31+
await sleep(500) // t: 1550
32+
expect(count).toBe(4)
33+
hook.run.value()
34+
hook.run.value()
35+
expect(count).toBe(5)
36+
hook.flush()
37+
expect(count).toBe(6)
38+
await sleep(550) // t: 2100
39+
expect(count).toBe(6)
40+
})
41+
42+
// it('should output error when fn is not a function', () => {
43+
// const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
44+
// renderHook(() => useThrottleFn(1 as any));
45+
// expect(errSpy).toBeCalledWith('useThrottleFn expected parameter is a function, got number');
46+
// errSpy.mockRestore();
47+
// });
48+
})
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import renderHook from 'test-utils/renderHook'
2+
import useTimeout from '../index'
3+
4+
interface ParamsObj {
5+
fn: (...arg: any) => any
6+
delay: number | undefined
7+
}
8+
9+
const setUp = ({ fn, delay }: ParamsObj) => renderHook(() => useTimeout(fn, delay))
10+
11+
describe('useTimeout', () => {
12+
vitest.useFakeTimers()
13+
vitest.spyOn(global, 'clearTimeout')
14+
15+
it('timeout should work', () => {
16+
const callback = vitest.fn()
17+
18+
setUp({ fn: callback, delay: 20 })
19+
20+
expect(callback).not.toBeCalled()
21+
vitest.advanceTimersByTime(70)
22+
expect(callback).toHaveBeenCalledTimes(1)
23+
})
24+
25+
it('timeout should stop', () => {
26+
const callback = vitest.fn()
27+
28+
setUp({ fn: callback, delay: undefined })
29+
vitest.advanceTimersByTime(50)
30+
expect(callback).toHaveBeenCalledTimes(0)
31+
32+
setUp({ fn: callback, delay: -2 })
33+
vitest.advanceTimersByTime(50)
34+
expect(callback).toHaveBeenCalledTimes(0)
35+
})
36+
37+
it('timeout should be clear', () => {
38+
const callback = vitest.fn()
39+
40+
setUp({ fn: callback, delay: 20 })
41+
expect(callback).not.toBeCalled()
42+
vitest.advanceTimersByTime(30)
43+
expect(callback).toHaveBeenCalledTimes(1)
44+
expect(clearTimeout).toHaveBeenCalledTimes(0)
45+
})
46+
})

0 commit comments

Comments
 (0)