Skip to content

Commit 2b47e9a

Browse files
committed
test: 🔧 add test
1 parent ad21c6b commit 2b47e9a

File tree

3 files changed

+209
-90
lines changed

3 files changed

+209
-90
lines changed
Lines changed: 91 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,104 @@
11
import useBoolean from '..'
22

33
describe('useBoolean', () => {
4-
// 基础功能测试
5-
it('should be defined', () => {
6-
expect(useBoolean).toBeDefined()
4+
describe('Basic functionality', () => {
5+
it('should be defined', () => {
6+
expect(useBoolean).toBeDefined()
7+
})
8+
9+
it('default value should be false', () => {
10+
const [state] = useBoolean()
11+
expect(state.value).toBe(false)
12+
})
13+
14+
it('should accept custom default value', () => {
15+
const [state] = useBoolean(true)
16+
expect(state.value).toBe(true)
17+
})
718
})
819

9-
// 默认值测试
10-
it('should default to be false', () => {
11-
const [state] = useBoolean()
12-
expect(state.value).toBeFalsy()
20+
describe('Operations', () => {
21+
let state: ReturnType<typeof useBoolean>[0]
22+
let actions: ReturnType<typeof useBoolean>[1]
23+
beforeEach(() => {
24+
;[state, actions] = useBoolean(true)
25+
})
26+
27+
it('toggle should switch state', () => {
28+
actions.toggle()
29+
expect(state.value).toBe(false)
30+
actions.toggle()
31+
expect(state.value).toBe(true)
32+
})
33+
34+
it('set should set specified value', () => {
35+
actions.set(false)
36+
expect(state.value).toBe(false)
37+
actions.set(true)
38+
expect(state.value).toBe(true)
39+
})
40+
41+
it('setTrue/setFalse should set to true/false respectively', () => {
42+
actions.setFalse()
43+
expect(state.value).toBe(false)
44+
actions.setTrue()
45+
expect(state.value).toBe(true)
46+
})
1347
})
1448

15-
// 自定义默认值测试
16-
it('should accept custom default value', () => {
17-
const [state] = useBoolean(true)
18-
expect(state.value).toBeTruthy()
49+
describe('Reactivity', () => {
50+
let state: ReturnType<typeof useBoolean>[0]
51+
let set: ReturnType<typeof useBoolean>[1]['set']
52+
beforeEach(() => {
53+
;[state, { set }] = useBoolean(false)
54+
})
55+
56+
it('set should update state multiple times', () => {
57+
set(true)
58+
expect(state.value).toBe(true)
59+
set(false)
60+
set(true)
61+
set(false)
62+
expect(state.value).toBe(false)
63+
})
1964
})
2065

21-
// 完整功能测试
22-
it('should work with all actions', () => {
23-
const [state, { set, setFalse, setTrue, toggle }] = useBoolean(true)
24-
25-
// 初始值测试
26-
expect(state.value).toBeTruthy()
27-
28-
// toggle 功能测试
29-
toggle()
30-
expect(state.value).toBeFalsy()
31-
toggle()
32-
expect(state.value).toBeTruthy()
33-
34-
// set 功能测试
35-
set(false)
36-
expect(state.value).toBeFalsy()
37-
set(true)
38-
expect(state.value).toBeTruthy()
39-
40-
// setTrue 功能测试
41-
setFalse()
42-
expect(state.value).toBeFalsy()
43-
setTrue()
44-
expect(state.value).toBeTruthy()
45-
46-
// setFalse 功能测试
47-
setTrue()
48-
expect(state.value).toBeTruthy()
49-
setFalse()
50-
expect(state.value).toBeFalsy()
66+
describe('Edge cases', () => {
67+
let state: ReturnType<typeof useBoolean>[0]
68+
let set: ReturnType<typeof useBoolean>[1]['set']
69+
beforeEach(() => {
70+
;[state, { set }] = useBoolean(false)
71+
})
72+
73+
it('set(null) should be false', () => {
74+
set(null as any)
75+
expect(state.value).toBe(false)
76+
})
77+
it('set(undefined) should be false', () => {
78+
set(undefined as any)
79+
expect(state.value).toBe(false)
80+
})
81+
it('set(NaN) should be false', () => {
82+
set(NaN as any)
83+
expect(state.value).toBe(false)
84+
})
85+
it('set({}) should be true', () => {
86+
set({} as any)
87+
expect(state.value).toBe(true)
88+
})
89+
it('set([]) should be true', () => {
90+
set([] as any)
91+
expect(state.value).toBe(true)
92+
})
5193
})
52-
// 响应式测试
53-
it('should be reactive', () => {
54-
const [state, { set }] = useBoolean(false)
55-
56-
// 测试响应式更新
57-
set(true)
58-
expect(state.value).toBeTruthy()
59-
60-
// 测试多次更新
61-
set(false)
62-
set(true)
63-
set(false)
64-
expect(state.value).toBeFalsy()
65-
})
66-
67-
// 边界情况测试
68-
it('should handle edge cases', () => {
69-
const [state, { set }] = useBoolean(false)
70-
71-
// 测试 null
72-
set(null as any)
73-
expect(state.value).toBeFalsy()
74-
75-
// 测试 undefined
76-
set(undefined as any)
77-
expect(state.value).toBeFalsy()
78-
79-
// 测试 NaN
80-
set(NaN as any)
81-
expect(state.value).toBeFalsy()
82-
83-
// 测试对象
84-
set({} as any)
85-
expect(state.value).toBeTruthy()
86-
87-
// 测试数组
88-
set([] as any)
89-
expect(state.value).toBeTruthy()
90-
})
91-
92-
// 性能测试
93-
it('should handle rapid toggles', () => {
94-
const [state, { toggle }] = useBoolean(false)
95-
96-
// 快速切换测试
97-
for (let i = 0; i < 100; i++) {
98-
toggle()
99-
}
10094

101-
expect(state.value).toBeFalsy() // 偶数次切换应该回到初始值
95+
describe('Performance', () => {
96+
it('should return to initial value after toggling 100 times quickly', () => {
97+
const [state, { toggle }] = useBoolean(false)
98+
for (let i = 0; i < 100; i++) {
99+
toggle()
100+
}
101+
expect(state.value).toBe(false)
102+
})
102103
})
103104
})

packages/hooks/src/useCookieState/__tests__/index.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,52 @@ describe('useCookieState', () => {
4040
})
4141
expect(message.value).toEqual('hello')
4242
})
43+
44+
it('should remove cookie when set to undefined', () => {
45+
const COOKIE_KEY = 'test-remove-cookie'
46+
const [message, setMessage] = useCookieState(COOKIE_KEY, { defaultValue: 'to-be-removed' })
47+
expect(message.value).toBe('to-be-removed')
48+
setMessage(undefined)
49+
expect(message.value).toBeUndefined()
50+
// Should not find the cookie in document.cookie
51+
expect(document.cookie.includes(COOKIE_KEY)).toBe(false)
52+
})
53+
54+
it('should persist value across multiple hook calls', () => {
55+
const COOKIE_KEY = 'test-persist'
56+
const [, setMessage1] = useCookieState(COOKIE_KEY, { defaultValue: 'first' })
57+
setMessage1('persisted')
58+
// Simulate re-mount
59+
const [message2] = useCookieState(COOKIE_KEY, { defaultValue: 'should-not-use' })
60+
expect(message2.value).toBe('persisted')
61+
})
62+
63+
it('should support different data types (number, boolean, object, array)', () => {
64+
const COOKIE_KEY = 'test-types'
65+
const [message, setMessage] = useCookieState(COOKIE_KEY, { defaultValue: '0' })
66+
setMessage('123')
67+
expect(message.value).toBe('123')
68+
setMessage('true')
69+
expect(message.value).toBe('true')
70+
setMessage(JSON.stringify({ a: 1 }))
71+
expect(message.value).toBe('{"a":1}')
72+
setMessage(JSON.stringify([1, 2, 3]))
73+
expect(message.value).toBe('[1,2,3]')
74+
})
75+
76+
it('should support cookie options (expires, path)', () => {
77+
const COOKIE_KEY = 'test-options'
78+
const [message, setMessage] = useCookieState(COOKIE_KEY, { defaultValue: 'opt', expires: 7, path: '/' })
79+
setMessage('with-options', { expires: 1, path: '/' })
80+
expect(message.value).toBe('with-options')
81+
// We cannot easily check cookie attributes in jsdom, but this ensures no error
82+
})
83+
84+
it('should read value from cookie if it exists, ignoring defaultValue', () => {
85+
const COOKIE_KEY = 'test-existing-cookie'
86+
// Set cookie manually
87+
document.cookie = `${COOKIE_KEY}=existing-value`
88+
const [message] = useCookieState(COOKIE_KEY, { defaultValue: 'should-not-use' })
89+
expect(message.value).toBe('existing-value')
90+
})
4391
})

packages/hooks/src/useDebounce/__tests__/index.spec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,74 @@ describe('useDebounce', () => {
2020
await sleep(300)
2121
expect(debouncedCount.value).toEqual(5)
2222
})
23+
it('should debounce string ref', async () => {
24+
const text = ref('hello')
25+
const [debouncedText] = renderHook(() => useDebounce(text, { wait: 100 }))
26+
text.value = 'world'
27+
text.value = 'vue'
28+
expect(debouncedText.value).toBe('hello')
29+
await sleep(150)
30+
expect(debouncedText.value).toBe('vue')
31+
})
32+
it('should debounce object ref', async () => {
33+
const obj = ref({ a: 1 })
34+
const [debouncedObj] = renderHook(() => useDebounce(obj, { wait: 100 }))
35+
obj.value = { a: 2 }
36+
obj.value = { a: 3 }
37+
expect(debouncedObj.value).toEqual({ a: 1 })
38+
await sleep(150)
39+
expect(debouncedObj.value).toEqual({ a: 3 })
40+
})
41+
it('should support leading option', async () => {
42+
const count = ref(0)
43+
const [debouncedCount] = renderHook(() => useDebounce(count, { wait: 100, leading: true, trailing: false }))
44+
count.value = 1
45+
count.value = 2
46+
count.value = 3
47+
// Should not update immediately
48+
expect(debouncedCount.value).toBe(0)
49+
await sleep(150)
50+
// According to lodash debounce, with leading: true and trailing: false,
51+
// only the last change within the debounce window is taken.
52+
expect(debouncedCount.value).toBe(3)
53+
})
54+
it('should support trailing option', async () => {
55+
const count = ref(0)
56+
const [debouncedCount] = renderHook(() => useDebounce(count, { wait: 100, leading: false, trailing: true }))
57+
count.value = 1
58+
count.value = 2
59+
count.value = 3
60+
expect(debouncedCount.value).toBe(0)
61+
await sleep(150)
62+
expect(debouncedCount.value).toBe(3)
63+
})
64+
it('should support maxWait option', async () => {
65+
const count = ref(0)
66+
const [debouncedCount] = renderHook(() => useDebounce(count, { wait: 100, maxWait: 200 }))
67+
count.value = 1
68+
await sleep(90)
69+
count.value = 2
70+
await sleep(90)
71+
count.value = 3
72+
expect(debouncedCount.value).toBe(0)
73+
await sleep(50)
74+
expect(debouncedCount.value).toBe(3)
75+
})
76+
it('should debounce with wait = 0', async () => {
77+
const count = ref(0)
78+
const [debouncedCount] = renderHook(() => useDebounce(count, { wait: 0 }))
79+
count.value = 1
80+
count.value = 2
81+
await sleep(10)
82+
expect(debouncedCount.value).toBe(2)
83+
})
84+
it('should cancel debounce on unmount', async () => {
85+
const count = ref(0)
86+
const [debouncedCount, app] = renderHook(() => useDebounce(count, { wait: 100 }))
87+
count.value = 1
88+
app.unmount()
89+
await sleep(150)
90+
// Should not update after unmount
91+
expect(debouncedCount.value).toBe(0)
92+
})
2393
})

0 commit comments

Comments
 (0)