|
3 | 3 | */ |
4 | 4 |
|
5 | 5 | import { beforeEach, expect, test, vi } from 'vitest'; |
6 | | -import { act, renderHook } from '@testing-library/react'; |
| 6 | +import { act, render, renderHook } from '@testing-library/react'; |
7 | 7 | import React, { StrictMode } from 'react'; |
8 | | -import { ExecutorManager, ExecutorManagerProvider, useExecutor } from '../main/index.js'; |
| 8 | +import { ExecutorEvent, ExecutorManager, ExecutorManagerProvider, useExecutor } from '../main/index.js'; |
9 | 9 |
|
10 | 10 | let testIndex = 0; |
11 | 11 | let executorKey: string; |
12 | 12 |
|
| 13 | +vi.useFakeTimers(); |
| 14 | + |
13 | 15 | beforeEach(() => { |
| 16 | + vi.clearAllTimers(); |
| 17 | + |
14 | 18 | executorKey = 'executor' + testIndex++; |
15 | 19 | }); |
16 | 20 |
|
@@ -163,5 +167,90 @@ test('re-renders after task execute', async () => { |
163 | 167 | expect(executor.reason).toBeUndefined(); |
164 | 168 | expect(executor.task).toBe(task); |
165 | 169 |
|
166 | | - expect(renderMock).toHaveBeenCalledTimes(6); |
| 170 | + expect(renderMock).toHaveBeenCalledTimes(4); |
| 171 | +}); |
| 172 | + |
| 173 | +test('deactivates an executor when key changes after parent component render', async () => { |
| 174 | + const task = vi.fn(); |
| 175 | + const listenerMock = vi.fn(); |
| 176 | + |
| 177 | + const manager = new ExecutorManager(); |
| 178 | + |
| 179 | + const Parent = (props: { executorKey: string }) => ( |
| 180 | + <ExecutorManagerProvider value={manager}> |
| 181 | + <Child executorKey={props.executorKey} /> |
| 182 | + </ExecutorManagerProvider> |
| 183 | + ); |
| 184 | + |
| 185 | + const Child = (props: { executorKey: string }) => { |
| 186 | + useExecutor(props.executorKey, task, [executor => executor.subscribe(listenerMock)]); |
| 187 | + return null; |
| 188 | + }; |
| 189 | + |
| 190 | + const { rerender } = await act(() => render(<Parent executorKey={'xxx'} />)); |
| 191 | + |
| 192 | + expect(manager['_executors'].size).toBe(1); |
| 193 | + |
| 194 | + expect(manager.get('xxx')!.isActive).toBe(true); |
| 195 | + |
| 196 | + expect(listenerMock).toHaveBeenCalledTimes(4); |
| 197 | + expect(listenerMock).toHaveBeenNthCalledWith(1, { |
| 198 | + type: 'attached', |
| 199 | + target: manager.get('xxx')!, |
| 200 | + version: 0, |
| 201 | + payload: undefined, |
| 202 | + } satisfies ExecutorEvent); |
| 203 | + expect(listenerMock).toHaveBeenNthCalledWith(2, { |
| 204 | + type: 'pending', |
| 205 | + target: manager.get('xxx')!, |
| 206 | + version: 1, |
| 207 | + payload: undefined, |
| 208 | + } satisfies ExecutorEvent); |
| 209 | + expect(listenerMock).toHaveBeenNthCalledWith(3, { |
| 210 | + type: 'activated', |
| 211 | + target: manager.get('xxx')!, |
| 212 | + version: 1, |
| 213 | + payload: undefined, |
| 214 | + } satisfies ExecutorEvent); |
| 215 | + expect(listenerMock).toHaveBeenNthCalledWith(4, { |
| 216 | + type: 'fulfilled', |
| 217 | + target: manager.get('xxx')!, |
| 218 | + version: 2, |
| 219 | + payload: undefined, |
| 220 | + } satisfies ExecutorEvent); |
| 221 | + |
| 222 | + act(() => rerender(<Parent executorKey={'yyy'} />)); |
| 223 | + |
| 224 | + vi.runAllTimers(); |
| 225 | + |
| 226 | + expect(manager['_executors'].size).toBe(2); |
| 227 | + |
| 228 | + expect(manager.get('xxx')!.isActive).toBe(false); |
| 229 | + expect(manager.get('yyy')!.isActive).toBe(true); |
| 230 | + |
| 231 | + expect(listenerMock).toHaveBeenCalledTimes(8); |
| 232 | + expect(listenerMock).toHaveBeenNthCalledWith(5, { |
| 233 | + type: 'attached', |
| 234 | + target: manager.get('yyy')!, |
| 235 | + version: 0, |
| 236 | + payload: undefined, |
| 237 | + } satisfies ExecutorEvent); |
| 238 | + expect(listenerMock).toHaveBeenNthCalledWith(6, { |
| 239 | + type: 'pending', |
| 240 | + target: manager.get('yyy')!, |
| 241 | + version: 1, |
| 242 | + payload: undefined, |
| 243 | + } satisfies ExecutorEvent); |
| 244 | + expect(listenerMock).toHaveBeenNthCalledWith(7, { |
| 245 | + type: 'deactivated', |
| 246 | + target: expect.objectContaining({ key: 'xxx' }), |
| 247 | + version: 2, |
| 248 | + payload: undefined, |
| 249 | + } satisfies ExecutorEvent); |
| 250 | + expect(listenerMock).toHaveBeenNthCalledWith(8, { |
| 251 | + type: 'activated', |
| 252 | + target: manager.get('yyy')!, |
| 253 | + version: 1, |
| 254 | + payload: undefined, |
| 255 | + } satisfies ExecutorEvent); |
167 | 256 | }); |
0 commit comments