@zat-design/sisyphus-react 3.13.18 → 3.13.19-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/tests/setup.ts DELETED
@@ -1,477 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- import 'jest-canvas-mock';
3
- import React from 'react';
4
-
5
- // Ensure JSDOM document.body exists and setup proper DOM environment
6
- if (typeof document !== 'undefined') {
7
- // Ensure documentElement exists
8
- if (!document.documentElement) {
9
- const html = document.createElement('html');
10
- document.appendChild(html);
11
- }
12
-
13
- // Ensure head exists
14
- if (!document.head) {
15
- const head = document.createElement('head');
16
- document.documentElement.appendChild(head);
17
- }
18
-
19
- // Ensure body exists
20
- if (!document.body) {
21
- const body = document.createElement('body');
22
- document.documentElement.appendChild(body);
23
- }
24
- }
25
-
26
- // Mock testing library environment setup
27
- Object.defineProperty(global, 'MutationObserver', {
28
- writable: true,
29
- value: jest.fn().mockImplementation(() => ({
30
- observe: jest.fn(),
31
- disconnect: jest.fn(),
32
- takeRecords: jest.fn(),
33
- })),
34
- });
35
-
36
- // Setup test container div
37
- beforeEach(() => {
38
- if (typeof document !== 'undefined' && document.body) {
39
- try {
40
- // Clean up any existing test containers
41
- const existingContainers = document.querySelectorAll('[data-testid="test-container"]');
42
- existingContainers.forEach(container => {
43
- if (container.parentNode) {
44
- try {
45
- container.parentNode.removeChild(container);
46
- } catch (e) {
47
- // Ignore cleanup errors
48
- }
49
- }
50
- });
51
-
52
- // Create a fresh test container
53
- const testContainer = document.createElement('div');
54
- testContainer.setAttribute('data-testid', 'test-container');
55
- testContainer.id = 'test-container';
56
- document.body.appendChild(testContainer);
57
- } catch (e) {
58
- // Ignore setup errors - React Testing Library will handle this
59
- }
60
- }
61
- });
62
-
63
- // 抑制控制台错误
64
- const originalError = console.error;
65
- beforeAll(() => {
66
- console.error = (...args: any[]) => {
67
- if (
68
- args.find(
69
- arg =>
70
- typeof arg === 'string' &&
71
- (
72
- arg.includes('Warning: ReactDOM.render is deprecated') ||
73
- arg.includes('Warning: componentWillReceiveProps') ||
74
- arg.includes('validateDOMNesting') ||
75
- arg.includes('Warning: componentWillMount') ||
76
- arg.includes('Warning: React.createFactory() is deprecated') ||
77
- arg.includes('Warning: findDOMNode is deprecated') ||
78
- arg.includes('act(...)') ||
79
- arg.includes('useLayoutEffect does nothing on the server') ||
80
- arg.includes('Invalid hook call') ||
81
- arg.includes('Hooks can only be called inside') ||
82
- arg.includes('Warning: Each child in a list should have a unique') ||
83
- arg.includes('Warning: validateDOMNesting')
84
- )
85
- )
86
- ) {
87
- return;
88
- }
89
- originalError.call(console, ...args);
90
- };
91
- });
92
-
93
- afterAll(() => {
94
- console.error = originalError;
95
- });
96
-
97
- // Mock window APIs
98
- Object.defineProperty(window, 'matchMedia', {
99
- writable: true,
100
- value: jest.fn().mockImplementation(query => ({
101
- matches: false,
102
- media: query,
103
- onchange: null,
104
- addListener: jest.fn(),
105
- removeListener: jest.fn(),
106
- addEventListener: jest.fn(),
107
- removeEventListener: jest.fn(),
108
- dispatchEvent: jest.fn(),
109
- })),
110
- });
111
-
112
- // Mock ahooks hooks - 基于ahooks官方测试实践改进
113
- jest.mock('ahooks', () => ({
114
- useSetState: jest.fn((initialState) => {
115
- const mockState = { current: initialState || {} };
116
- const mockSetState = jest.fn((patch) => {
117
- if (typeof patch === 'function') {
118
- mockState.current = patch(mockState.current);
119
- } else {
120
- mockState.current = { ...mockState.current, ...patch };
121
- }
122
- return mockState.current;
123
- });
124
- return [mockState.current, mockSetState];
125
- }),
126
-
127
- useRequest: jest.fn((service, options = {}) => {
128
- const mockState = {
129
- loading: false,
130
- data: null,
131
- error: null,
132
- params: [],
133
- };
134
-
135
- const mockActions = {
136
- run: jest.fn((...params) => {
137
- mockState.loading = true;
138
- mockState.params = params;
139
- // 模拟异步操作
140
- setTimeout(() => {
141
- mockState.loading = false;
142
- mockState.data = 'mock-data';
143
- }, 100);
144
- return Promise.resolve('mock-data');
145
- }),
146
- refresh: jest.fn(() => {
147
- mockState.loading = true;
148
- setTimeout(() => {
149
- mockState.loading = false;
150
- }, 100);
151
- return Promise.resolve('mock-data');
152
- }),
153
- cancel: jest.fn(() => {
154
- mockState.loading = false;
155
- }),
156
- mutate: jest.fn((data) => {
157
- mockState.data = data;
158
- }),
159
- };
160
-
161
- const result = {
162
- ...mockState,
163
- ...mockActions,
164
- };
165
-
166
- // 如果提供了service函数,模拟调用
167
- if (service && typeof service === 'function') {
168
- result.run = jest.fn((...params) => {
169
- mockState.loading = true;
170
- mockState.params = params;
171
-
172
- return new Promise((resolve, reject) => {
173
- setTimeout(() => {
174
- try {
175
- const serviceResult = service(...params);
176
- if (serviceResult instanceof Promise) {
177
- serviceResult.then(resolve).catch(reject);
178
- } else {
179
- resolve(serviceResult);
180
- }
181
- } catch (error) {
182
- reject(error);
183
- } finally {
184
- mockState.loading = false;
185
- }
186
- }, 100);
187
- });
188
- });
189
- }
190
-
191
- // 处理options
192
- if (options.manual !== true) {
193
- // 自动执行
194
- setTimeout(() => {
195
- result.run();
196
- }, 0);
197
- }
198
-
199
- return result;
200
- }),
201
-
202
- useDebounce: jest.fn((value, delay) => value),
203
-
204
- useThrottle: jest.fn((value, delay) => value),
205
-
206
- useLocalStorageState: jest.fn((key, defaultValue) => {
207
- const [state, setState] = [defaultValue, jest.fn()];
208
- return [state, setState];
209
- }),
210
-
211
- useSessionStorageState: jest.fn((key, defaultValue) => {
212
- const [state, setState] = [defaultValue, jest.fn()];
213
- return [state, setState];
214
- }),
215
-
216
- useDeepCompareEffect: jest.fn((effect, deps) => {
217
- if (effect && typeof effect === 'function') {
218
- effect();
219
- }
220
- }),
221
-
222
- useUpdateEffect: jest.fn((effect, deps) => {
223
- if (effect && typeof effect === 'function') {
224
- effect();
225
- }
226
- }),
227
-
228
- useSize: jest.fn(() => ({ width: 100, height: 100 })),
229
-
230
- useInViewport: jest.fn(() => [true, jest.fn()]),
231
-
232
- useMemoizedFn: jest.fn((fn) => fn),
233
-
234
- useMount: jest.fn((fn) => {
235
- if (fn && typeof fn === 'function') {
236
- fn();
237
- }
238
- }),
239
-
240
- useUnmount: jest.fn((fn) => {
241
- if (fn && typeof fn === 'function') {
242
- fn();
243
- }
244
- }),
245
-
246
- useDebounceEffect: jest.fn((effect, deps, wait) => {
247
- if (effect && typeof effect === 'function') {
248
- effect();
249
- }
250
- }),
251
-
252
- useThrottleEffect: jest.fn((effect, deps, wait) => {
253
- if (effect && typeof effect === 'function') {
254
- effect();
255
- }
256
- }),
257
- }));
258
-
259
- Object.defineProperty(window, 'ResizeObserver', {
260
- writable: true,
261
- value: jest.fn().mockImplementation(() => ({
262
- observe: jest.fn(),
263
- unobserve: jest.fn(),
264
- disconnect: jest.fn(),
265
- })),
266
- });
267
-
268
- Object.defineProperty(window, 'IntersectionObserver', {
269
- writable: true,
270
- value: jest.fn().mockImplementation(() => ({
271
- observe: jest.fn(),
272
- unobserve: jest.fn(),
273
- disconnect: jest.fn(),
274
- })),
275
- });
276
-
277
- // Mock getBoundingClientRect
278
- Element.prototype.getBoundingClientRect = jest.fn(() => ({
279
- width: 120,
280
- height: 120,
281
- top: 0,
282
- left: 0,
283
- bottom: 0,
284
- right: 0,
285
- x: 0,
286
- y: 0,
287
- toJSON: jest.fn(),
288
- }));
289
-
290
- // Mock scrollIntoView
291
- Element.prototype.scrollIntoView = jest.fn();
292
-
293
- // Mock getComputedStyle
294
- window.getComputedStyle = jest.fn(() => ({
295
- getPropertyValue: jest.fn(() => ''),
296
- setProperty: jest.fn(),
297
- removeProperty: jest.fn(),
298
- } as any));
299
-
300
- // Mock URL methods
301
- global.URL.createObjectURL = jest.fn(() => 'mock-url');
302
- global.URL.revokeObjectURL = jest.fn();
303
-
304
- // Mock fetch
305
- global.fetch = jest.fn(() =>
306
- Promise.resolve({
307
- ok: true,
308
- json: () => Promise.resolve({}),
309
- blob: () => Promise.resolve(new Blob()),
310
- text: () => Promise.resolve(''),
311
- } as Response)
312
- );
313
-
314
- // Mock String methods to prevent format.match and format.replace errors
315
- String.prototype.match = String.prototype.match || jest.fn(() => []);
316
- String.prototype.replace = String.prototype.replace || jest.fn((pattern, replacement) => {
317
- if (typeof pattern === 'string') {
318
- return this.split(pattern).join(replacement);
319
- }
320
- return this;
321
- });
322
-
323
- // Mock FileReader
324
- class MockFileReader {
325
- result: any = null;
326
- error: any = null;
327
- readyState: number = 0;
328
- onload: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null = null;
329
- onerror: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null = null;
330
- onloadend: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null = null;
331
-
332
- readAsDataURL = jest.fn(() => {
333
- this.readyState = 2;
334
- this.result = 'data:image/png;base64,test';
335
- setTimeout(() => {
336
- if (this.onload) this.onload({} as ProgressEvent<FileReader>);
337
- if (this.onloadend) this.onloadend({} as ProgressEvent<FileReader>);
338
- }, 0);
339
- });
340
-
341
- readAsText = jest.fn(() => {
342
- this.readyState = 2;
343
- this.result = 'test content';
344
- setTimeout(() => {
345
- if (this.onload) this.onload({} as ProgressEvent<FileReader>);
346
- if (this.onloadend) this.onloadend({} as ProgressEvent<FileReader>);
347
- }, 0);
348
- });
349
-
350
- abort = jest.fn();
351
- addEventListener = jest.fn();
352
- removeEventListener = jest.fn();
353
- dispatchEvent = jest.fn();
354
- }
355
-
356
- global.FileReader = MockFileReader as any;
357
-
358
- // Mock Blob
359
- global.Blob = jest.fn().mockImplementation(() => ({
360
- size: 1024,
361
- type: 'image/png',
362
- slice: jest.fn(),
363
- stream: jest.fn(),
364
- text: jest.fn(() => Promise.resolve('mock text')),
365
- arrayBuffer: jest.fn(() => Promise.resolve(new ArrayBuffer(8))),
366
- }));
367
-
368
- // Store original createElement
369
- const originalCreateElement = document.createElement;
370
-
371
- // Simple mock for specific elements only when needed
372
- document.createElement = jest.fn((tagName: string) => {
373
- try {
374
- return originalCreateElement.call(document, tagName);
375
- } catch (e) {
376
- // Fallback for special cases
377
- const mockElement = {
378
- tagName: tagName.toUpperCase(),
379
- style: {},
380
- className: '',
381
- textContent: '',
382
- innerHTML: '',
383
- addEventListener: jest.fn(),
384
- removeEventListener: jest.fn(),
385
- dispatchEvent: jest.fn(),
386
- setAttribute: jest.fn(),
387
- getAttribute: jest.fn(),
388
- removeAttribute: jest.fn(),
389
- appendChild: jest.fn(),
390
- removeChild: jest.fn(),
391
- insertBefore: jest.fn(),
392
- querySelector: jest.fn(),
393
- querySelectorAll: jest.fn(() => []),
394
- parentNode: null,
395
- childNodes: [],
396
- children: [],
397
- };
398
-
399
- // Add specific properties for different elements
400
- if (tagName === 'canvas') {
401
- Object.assign(mockElement, {
402
- getContext: jest.fn(() => ({
403
- drawImage: jest.fn(),
404
- getImageData: jest.fn(),
405
- putImageData: jest.fn(),
406
- toDataURL: jest.fn(() => 'data:image/png;base64,test'),
407
- })),
408
- toDataURL: jest.fn(() => 'data:image/png;base64,test'),
409
- width: 100,
410
- height: 100,
411
- });
412
- } else if (tagName === 'a') {
413
- Object.assign(mockElement, {
414
- click: jest.fn(),
415
- download: '',
416
- href: '',
417
- });
418
- }
419
-
420
- return mockElement as any;
421
- }
422
- });
423
-
424
- // Store original methods
425
- const originalAppendChild = document.body.appendChild;
426
- const originalRemoveChild = document.body.removeChild;
427
-
428
- // Mock but still allow actual functionality for testing
429
- document.body.appendChild = jest.fn((node) => {
430
- try {
431
- // Check if node is a valid DOM element
432
- if (node && typeof node === 'object' && node.nodeType !== undefined) {
433
- return originalAppendChild.call(document.body, node);
434
- }
435
- // For non-DOM elements, just return the node
436
- return node;
437
- } catch (e) {
438
- // If original fails, just return the node
439
- return node;
440
- }
441
- });
442
-
443
- document.body.removeChild = jest.fn((node) => {
444
- try {
445
- // Check if node is a valid DOM element
446
- if (node && typeof node === 'object' && node.nodeType !== undefined) {
447
- return originalRemoveChild.call(document.body, node);
448
- }
449
- // For non-DOM elements, just return the node
450
- return node;
451
- } catch (e) {
452
- // If original fails, just return the node
453
- return node;
454
- }
455
- });
456
-
457
- // Mock getElementsByTagName to prevent ProIcon DOM access issues
458
- const originalGetElementsByTagName = document.getElementsByTagName;
459
- document.getElementsByTagName = jest.fn((tagName: string) => {
460
- if (tagName === 'script') {
461
- // Return empty collection for script tags to prevent ProIcon issues
462
- return [];
463
- }
464
- try {
465
- return originalGetElementsByTagName.call(document, tagName);
466
- } catch (e) {
467
- // Fallback for testing
468
- return [];
469
- }
470
- });
471
-
472
- // Mock ProIcon to prevent DOM manipulation
473
- jest.mock('../src/ProIcon', () => ({
474
- __esModule: true,
475
- default: jest.fn(() => null),
476
- ProIcon: jest.fn(() => null),
477
- }));
@@ -1,81 +0,0 @@
1
- import React from 'react';
2
- import { render, RenderOptions } from '@testing-library/react';
3
- import { ConfigProvider } from 'antd';
4
- import zhCN from 'antd/locale/zh_CN';
5
-
6
- // 确保document.body存在
7
- const ensureDocumentSetup = () => {
8
- if (typeof document !== 'undefined') {
9
- if (!document.body) {
10
- document.body = document.createElement('body');
11
- document.documentElement.appendChild(document.body);
12
- }
13
-
14
- // 创建一个测试容器
15
- let testContainer = document.getElementById('test-container');
16
- if (!testContainer) {
17
- testContainer = document.createElement('div');
18
- testContainer.id = 'test-container';
19
- document.body.appendChild(testContainer);
20
- }
21
- }
22
- };
23
-
24
- // Mock ProConfigProvider
25
- const MockProConfigProvider = ({ children }: { children: React.ReactNode }) => {
26
- const mockValue = {
27
- state: {
28
- ProTable: {},
29
- ProForm: {},
30
- ProEnum: {},
31
- ProSelect: {},
32
- storage: {},
33
- theme: {},
34
- locale: {},
35
- },
36
- setState: jest.fn(),
37
- };
38
-
39
- const MockContext = React.createContext(mockValue);
40
- return React.createElement(MockContext.Provider, { value: mockValue }, children);
41
- };
42
-
43
- // Mock FieldProvider
44
- const MockFieldProvider = ({ children }: { children: React.ReactNode }) => {
45
- const mockValue = {
46
- readonly: false,
47
- disabled: false,
48
- };
49
-
50
- const MockFieldContext = React.createContext(mockValue);
51
- return React.createElement(MockFieldContext.Provider, { value: mockValue }, children);
52
- };
53
-
54
- // All providers wrapper
55
- const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
56
- ensureDocumentSetup();
57
-
58
- return (
59
- <ConfigProvider locale={zhCN}>
60
- <MockProConfigProvider>
61
- <MockFieldProvider>
62
- {children}
63
- </MockFieldProvider>
64
- </MockProConfigProvider>
65
- </ConfigProvider>
66
- );
67
- };
68
-
69
- const customRender = (ui: React.ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => {
70
- ensureDocumentSetup();
71
-
72
- return render(ui, {
73
- wrapper: AllTheProviders,
74
- container: document.getElementById('test-container') || document.body,
75
- ...options
76
- });
77
- };
78
-
79
- export * from '@testing-library/react';
80
- export { customRender as render };
81
- export { AllTheProviders, ensureDocumentSetup };