forked from StellarSend/frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusePendingIds.test.ts
More file actions
133 lines (105 loc) · 3.72 KB
/
Copy pathusePendingIds.test.ts
File metadata and controls
133 lines (105 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { act, renderHook } from '@testing-library/react'
import { describe, it, expect, vi } from 'vitest'
import { usePendingIds } from './usePendingIds'
function deferred<T>() {
let resolve!: (value: T) => void
let reject!: (reason?: unknown) => void
const promise = new Promise<T>((res, rej) => {
resolve = res
reject = rej
})
return { promise, resolve, reject }
}
describe('usePendingIds', () => {
it('marks an id pending immediately when tracked', () => {
const { result } = renderHook(() => usePendingIds())
const { promise } = deferred<void>()
act(() => {
result.current.track('a', promise)
})
expect(result.current.pendingIds.has('a')).toBe(true)
})
it('two different ids tracked concurrently stay independently pending', () => {
const { result } = renderHook(() => usePendingIds())
const a = deferred<void>()
const b = deferred<void>()
act(() => {
result.current.track('a', a.promise)
result.current.track('b', b.promise)
})
expect(result.current.pendingIds.has('a')).toBe(true)
expect(result.current.pendingIds.has('b')).toBe(true)
})
it('resolving one id does not clear a different, still-pending id (#52)', async () => {
const { result } = renderHook(() => usePendingIds())
const a = deferred<void>()
const b = deferred<void>()
act(() => {
result.current.track('a', a.promise)
result.current.track('b', b.promise)
})
await act(async () => {
b.resolve()
await b.promise
})
expect(result.current.pendingIds.has('a')).toBe(true)
expect(result.current.pendingIds.has('b')).toBe(false)
})
it('clears the id once its promise resolves', async () => {
const { result } = renderHook(() => usePendingIds())
const { promise, resolve } = deferred<void>()
act(() => {
result.current.track('a', promise)
})
expect(result.current.pendingIds.has('a')).toBe(true)
await act(async () => {
resolve()
await promise
})
expect(result.current.pendingIds.has('a')).toBe(false)
})
it('clears the id even when its promise rejects, without an unhandled rejection', async () => {
const { result } = renderHook(() => usePendingIds())
const { promise, reject } = deferred<void>()
act(() => {
result.current.track('a', promise)
})
await act(async () => {
reject(new Error('boom'))
await promise.catch(() => {})
})
expect(result.current.pendingIds.has('a')).toBe(false)
})
it('tracking the same id twice while the first is still pending is a no-op on entry', () => {
const { result } = renderHook(() => usePendingIds())
const a = deferred<void>()
const b = deferred<void>()
act(() => {
result.current.track('a', a.promise)
result.current.track('a', b.promise)
})
expect(result.current.pendingIds.has('a')).toBe(true)
expect(result.current.pendingIds.size).toBe(1)
})
it('track is referentially stable across renders', () => {
const { result, rerender } = renderHook(() => usePendingIds())
const first = result.current.track
rerender()
expect(result.current.track).toBe(first)
})
it('does not produce an unhandled rejection warning for a rejected promise', async () => {
const onUnhandledRejection = vi.fn()
process.on('unhandledRejection', onUnhandledRejection)
const { result } = renderHook(() => usePendingIds())
const { promise, reject } = deferred<void>()
act(() => {
result.current.track('a', promise)
})
await act(async () => {
reject(new Error('boom'))
await new Promise((r) => setTimeout(r, 0))
})
expect(onUnhandledRejection).not.toHaveBeenCalled()
process.off('unhandledRejection', onUnhandledRejection)
})
})