-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseAsyncTask.test.js
122 lines (89 loc) · 3.35 KB
/
useAsyncTask.test.js
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
/**
* @jest-environment jsdom
*/
import { render, act } from "@testing-library/react"
import { useAsyncTask, FINISHED, RUNNING, ERROR } from "../src/index"
const TASK_1_RESULT = "TASK_1_RESULT"
const TASK_1 = () => delay(10).then(() => TASK_1_RESULT)
const TASK_2_RESULT = "TASK_2_RESULT"
const TASK_2 = () => delay(10).then(() => TASK_2_RESULT)
const results = []
const TestComponent = ({ task }) => {
const taskState = useAsyncTask(task)
results.push(taskState)
return <></>
}
describe("useAsyncTask", () => {
beforeEach(() => {
results.length = 0
})
test("shows the children when the checkbox is checked", async () => {
render(<TestComponent task={TASK_1} />)
await act(() => delay(20))
expect(results.length).toBe(2)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: FINISHED, result: TASK_1_RESULT })
})
test("should finish task", async () => {
render(<TestComponent task={TASK_1} />)
await act(() => delay(20))
expect(results.length).toBe(2)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: FINISHED, result: TASK_1_RESULT })
})
test("should cancel task", async () => {
const { unmount } = render(<TestComponent task={TASK_1} />)
unmount()
await act(() => delay(20))
expect(results.length).toBe(1)
expect(results[0]).toEqual({ status: RUNNING })
})
test("should not re-run task on rerender", async () => {
const { rerender } = render(<TestComponent task={TASK_1} />)
await act(() => delay(20))
rerender(<TestComponent task={TASK_1} />)
await act(() => delay(20))
expect(results.length).toBe(3)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: FINISHED, result: TASK_1_RESULT })
expect(results[2]).toEqual({ status: FINISHED, result: TASK_1_RESULT })
})
test("should run another task after first task", async () => {
const { rerender } = render(<TestComponent task={TASK_1} />)
await act(() => delay(20))
rerender(<TestComponent task={TASK_2} />)
await act(() => delay(20))
expect(results.length).toBe(4)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: FINISHED, result: TASK_1_RESULT })
expect(results[2]).toEqual({ status: RUNNING })
expect(results[3]).toEqual({ status: FINISHED, result: TASK_2_RESULT })
})
test("should run another task after first task cancelled", async () => {
const { rerender } = render(<TestComponent task={TASK_1} />)
rerender(<TestComponent task={TASK_2} />)
await act(() => delay(20))
expect(results.length).toBe(3)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: RUNNING })
expect(results[2]).toEqual({ status: FINISHED, result: TASK_2_RESULT })
})
test("should return error on error", async () => {
render(
<TestComponent
task={() =>
delay(10).then(() => {
throw new Error("This is an error")
})
}
/>
)
await act(() => delay(20))
expect(results.length).toBe(2)
expect(results[0]).toEqual({ status: RUNNING })
expect(results[1]).toEqual({ status: ERROR, error: new Error("This is an error") })
})
})
function delay(time) {
return new Promise((resolve) => setTimeout(() => resolve(), time))
}