@pageai/ralph-loop 1.0.0

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.
Files changed (120) hide show
  1. package/.agent/PROMPT.md +58 -0
  2. package/.agent/STEERING.md +3 -0
  3. package/.agent/logs/LOG.md +13 -0
  4. package/.agent/prd/.gitkeep +0 -0
  5. package/.agent/screenshots/.gitkeep +0 -0
  6. package/.agent/skills/component-refactoring/SKILL.md +247 -0
  7. package/.agent/skills/component-refactoring/references/complexity-patterns.md +485 -0
  8. package/.agent/skills/component-refactoring/references/component-splitting.md +419 -0
  9. package/.agent/skills/component-refactoring/references/hook-extraction.md +317 -0
  10. package/.agent/skills/e2e-tester/SKILL.md +595 -0
  11. package/.agent/skills/frontend-code-review/SKILL.md +73 -0
  12. package/.agent/skills/frontend-code-review/references/code-quality.md +28 -0
  13. package/.agent/skills/frontend-code-review/references/performance.md +36 -0
  14. package/.agent/skills/frontend-testing/SKILL.md +316 -0
  15. package/.agent/skills/frontend-testing/assets/component-test.template.tsx +293 -0
  16. package/.agent/skills/frontend-testing/assets/hook-test.template.ts +207 -0
  17. package/.agent/skills/frontend-testing/assets/utility-test.template.ts +154 -0
  18. package/.agent/skills/frontend-testing/references/async-testing.md +345 -0
  19. package/.agent/skills/frontend-testing/references/checklist.md +188 -0
  20. package/.agent/skills/frontend-testing/references/common-patterns.md +449 -0
  21. package/.agent/skills/frontend-testing/references/mocking.md +289 -0
  22. package/.agent/skills/frontend-testing/references/workflow.md +265 -0
  23. package/.agent/skills/prd-creator/JSON.md +613 -0
  24. package/.agent/skills/prd-creator/PRD.md +196 -0
  25. package/.agent/skills/prd-creator/SKILL.md +143 -0
  26. package/.agent/skills/skill-creator/SKILL.md +355 -0
  27. package/.agent/skills/skill-creator/references/output-patterns.md +86 -0
  28. package/.agent/skills/skill-creator/references/workflows.md +28 -0
  29. package/.agent/skills/skill-creator/scripts/init_skill.py +300 -0
  30. package/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
  31. package/.agent/skills/vercel-react-best-practices/AGENTS.md +2249 -0
  32. package/.agent/skills/vercel-react-best-practices/SKILL.md +125 -0
  33. package/.agent/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  34. package/.agent/skills/vercel-react-best-practices/rules/advanced-use-latest.md +49 -0
  35. package/.agent/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  36. package/.agent/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  37. package/.agent/skills/vercel-react-best-practices/rules/async-dependencies.md +36 -0
  38. package/.agent/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  39. package/.agent/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  40. package/.agent/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  41. package/.agent/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  42. package/.agent/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  43. package/.agent/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  44. package/.agent/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  45. package/.agent/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  46. package/.agent/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  47. package/.agent/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +82 -0
  48. package/.agent/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  49. package/.agent/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  50. package/.agent/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  51. package/.agent/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  52. package/.agent/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  53. package/.agent/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  54. package/.agent/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  55. package/.agent/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  56. package/.agent/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  57. package/.agent/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  58. package/.agent/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  59. package/.agent/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  60. package/.agent/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  61. package/.agent/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  62. package/.agent/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  63. package/.agent/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  64. package/.agent/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  65. package/.agent/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  66. package/.agent/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  67. package/.agent/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  68. package/.agent/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  69. package/.agent/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  70. package/.agent/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  71. package/.agent/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  72. package/.agent/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  73. package/.agent/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  74. package/.agent/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  75. package/.agent/skills/vercel-react-best-practices/rules/server-cache-react.md +26 -0
  76. package/.agent/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +79 -0
  77. package/.agent/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  78. package/.agent/skills/vitest-best-practices/AGENTS.md +84 -0
  79. package/.agent/skills/vitest-best-practices/SKILL.md +130 -0
  80. package/.agent/skills/vitest-best-practices/references/aaa-pattern.md +260 -0
  81. package/.agent/skills/vitest-best-practices/references/assertions.md +393 -0
  82. package/.agent/skills/vitest-best-practices/references/async-testing.md +454 -0
  83. package/.agent/skills/vitest-best-practices/references/error-handling.md +382 -0
  84. package/.agent/skills/vitest-best-practices/references/organization.md +212 -0
  85. package/.agent/skills/vitest-best-practices/references/parameterized-tests.md +297 -0
  86. package/.agent/skills/vitest-best-practices/references/performance.md +528 -0
  87. package/.agent/skills/vitest-best-practices/references/snapshot-testing.md +483 -0
  88. package/.agent/skills/vitest-best-practices/references/test-doubles.md +499 -0
  89. package/.agent/skills/vitest-best-practices/references/vitest-features.md +529 -0
  90. package/.agent/skills/web-design-guidelines/SKILL.md +39 -0
  91. package/.agent/tasks/.gitkeep +0 -0
  92. package/.agent/tasks.json +1 -0
  93. package/.claude/agents/code-reviewer.md +172 -0
  94. package/.claude/commands/aw.md +50 -0
  95. package/.claude/hooks/play-sound.js +87 -0
  96. package/.claude/hooks/pre-tool-use.js +40 -0
  97. package/.claude/settings.json +54 -0
  98. package/.claude/settings.local.json +13 -0
  99. package/.mcp.json +31 -0
  100. package/AGENTS.md +44 -0
  101. package/CLAUDE.md +1 -0
  102. package/README.md +236 -0
  103. package/bin/cli.js +156 -0
  104. package/bin/lib/copy.js +149 -0
  105. package/bin/lib/display.js +137 -0
  106. package/package.json +65 -0
  107. package/ralph.sh +333 -0
  108. package/scripts/lib/args.sh +44 -0
  109. package/scripts/lib/cleanup.sh +53 -0
  110. package/scripts/lib/constants.sh +25 -0
  111. package/scripts/lib/display.sh +196 -0
  112. package/scripts/lib/logging.sh +30 -0
  113. package/scripts/lib/notify.sh +41 -0
  114. package/scripts/lib/output.sh +147 -0
  115. package/scripts/lib/preflight.sh +57 -0
  116. package/scripts/lib/preview.sh +77 -0
  117. package/scripts/lib/promise.sh +76 -0
  118. package/scripts/lib/spinner.sh +85 -0
  119. package/scripts/lib/terminal.sh +57 -0
  120. package/scripts/lib/timing.sh +223 -0
@@ -0,0 +1,528 @@
1
+ # 1.8 Performance
2
+
3
+ Keep tests fast by avoiding expensive operations and optimizing setup/teardown. Fast tests encourage developers to run them frequently.
4
+
5
+ ## Keep Tests Fast
6
+
7
+ Tests should run in milliseconds, not seconds.
8
+
9
+ **✅ Correct: fast, focused test**
10
+ ```ts
11
+ it('should calculate total price', () => {
12
+ const order = { items: [{ price: 10 }, { price: 20 }] };
13
+ expect(calculateTotal(order)).toBe(30);
14
+ });
15
+ // Runs in <1ms
16
+ ```
17
+
18
+ **❌ Incorrect: unnecessarily slow test**
19
+ ```ts
20
+ it('should calculate total price', async () => {
21
+ await delay(1000); // Why?
22
+ const order = await fetchOrderFromAPI(); // Use test data instead!
23
+ expect(calculateTotal(order)).toBeGreaterThan(0);
24
+ });
25
+ // Runs in >1 second
26
+ ```
27
+
28
+ ## Avoid Real Network Calls
29
+
30
+ Never make actual HTTP requests in unit tests.
31
+
32
+ **❌ Incorrect: real network calls**
33
+ ```ts
34
+ it('should fetch user data', async () => {
35
+ const response = await fetch('https://api.example.com/users/123');
36
+ const user = await response.json();
37
+ expect(user.id).toBe('123');
38
+ });
39
+ // Slow, flaky, requires network
40
+ ```
41
+
42
+ **✅ Correct: mocked network calls**
43
+ ```ts
44
+ it('should fetch user data', async () => {
45
+ const mockFetch = vi.fn().mockResolvedValue({
46
+ json: async () => ({ id: '123', name: 'John' }),
47
+ });
48
+
49
+ const user = await fetchUser('123', mockFetch);
50
+ expect(user.id).toBe('123');
51
+ });
52
+ // Fast, reliable, no network needed
53
+ ```
54
+
55
+ ## Minimize Setup and Teardown
56
+
57
+ Only set up what you need for each test.
58
+
59
+ **❌ Incorrect: expensive shared setup**
60
+ ```ts
61
+ describe('UserService', () => {
62
+ let database: Database;
63
+ let cache: Cache;
64
+ let emailService: EmailService;
65
+ let analyticsService: AnalyticsService;
66
+
67
+ beforeEach(async () => {
68
+ // Setting up everything for every test!
69
+ database = await createRealDatabase();
70
+ await database.migrate();
71
+ cache = await createRedisCache();
72
+ emailService = new EmailService(await createSMTPConnection());
73
+ analyticsService = new AnalyticsService(await createKafkaProducer());
74
+ });
75
+
76
+ it('should validate email format', () => {
77
+ // Only needs email validation, but set up entire system!
78
+ expect(UserService.isValidEmail('test@example.com')).toBe(true);
79
+ });
80
+ });
81
+ ```
82
+
83
+ **✅ Correct: minimal setup per test**
84
+ ```ts
85
+ describe('UserService', () => {
86
+ it('should validate email format', () => {
87
+ // No setup needed for pure function
88
+ expect(UserService.isValidEmail('test@example.com')).toBe(true);
89
+ });
90
+
91
+ it('should save user to database', async () => {
92
+ // Only set up what's needed
93
+ const db = new InMemoryDatabase();
94
+ const service = new UserService(db);
95
+
96
+ await service.saveUser({ name: 'John', email: 'john@example.com' });
97
+
98
+ const users = await db.findAll();
99
+ expect(users).toHaveLength(1);
100
+ });
101
+ });
102
+ ```
103
+
104
+ ## Use In-Memory Implementations
105
+
106
+ Prefer in-memory fakes over real external services.
107
+
108
+ **✅ Correct: in-memory database**
109
+ ```ts
110
+ class InMemoryUserRepository {
111
+ private users = new Map<string, User>();
112
+
113
+ async save(user: User) {
114
+ this.users.set(user.id, user);
115
+ }
116
+
117
+ async findById(id: string) {
118
+ return this.users.get(id) || null;
119
+ }
120
+ }
121
+
122
+ describe('UserService', () => {
123
+ it('should create and retrieve user', async () => {
124
+ const repo = new InMemoryUserRepository();
125
+ const service = new UserService(repo);
126
+
127
+ const created = await service.createUser({ name: 'John' });
128
+ const retrieved = await service.getUser(created.id);
129
+
130
+ expect(retrieved).toEqual(created);
131
+ });
132
+ });
133
+ // Fast: no database connection, no I/O
134
+ ```
135
+
136
+ ## Avoid File System I/O
137
+
138
+ Mock file system operations in unit tests.
139
+
140
+ **❌ Incorrect: real file operations**
141
+ ```ts
142
+ it('should save config to file', async () => {
143
+ const config = { theme: 'dark', language: 'en' };
144
+ await saveConfig('./test-config.json', config);
145
+
146
+ const loaded = await loadConfig('./test-config.json');
147
+ expect(loaded).toEqual(config);
148
+
149
+ // Clean up
150
+ await fs.unlink('./test-config.json');
151
+ });
152
+ ```
153
+
154
+ **✅ Correct: mocked file system**
155
+ ```ts
156
+ it('should save config to file', async () => {
157
+ const mockFs = {
158
+ writeFile: vi.fn().mockResolvedValue(undefined),
159
+ readFile: vi.fn().mockResolvedValue('{"theme":"dark","language":"en"}'),
160
+ };
161
+
162
+ const config = { theme: 'dark', language: 'en' };
163
+ await saveConfig('./test-config.json', config, mockFs);
164
+
165
+ expect(mockFs.writeFile).toHaveBeenCalledWith(
166
+ './test-config.json',
167
+ JSON.stringify(config)
168
+ );
169
+ });
170
+ ```
171
+
172
+ ## Optimize Fake Timers
173
+
174
+ Use fake timers instead of real delays.
175
+
176
+ **❌ Incorrect: real delays**
177
+ ```ts
178
+ it('should throttle function calls', async () => {
179
+ const fn = vi.fn();
180
+ const throttled = throttle(fn, 1000);
181
+
182
+ throttled();
183
+ await delay(500);
184
+ throttled(); // Ignored
185
+ await delay(600);
186
+ throttled(); // Called
187
+
188
+ expect(fn).toHaveBeenCalledTimes(2);
189
+ });
190
+ // Takes 1.1+ seconds
191
+ ```
192
+
193
+ **✅ Correct: fake timers**
194
+ ```ts
195
+ it('should throttle function calls', () => {
196
+ vi.useFakeTimers();
197
+
198
+ const fn = vi.fn();
199
+ const throttled = throttle(fn, 1000);
200
+
201
+ throttled();
202
+ vi.advanceTimersByTime(500);
203
+ throttled(); // Ignored
204
+ vi.advanceTimersByTime(600);
205
+ throttled(); // Called
206
+
207
+ expect(fn).toHaveBeenCalledTimes(2);
208
+
209
+ vi.useRealTimers();
210
+ });
211
+ // Runs in milliseconds
212
+ ```
213
+
214
+ ## Avoid Unnecessary Async
215
+
216
+ Don't make tests async if they don't need to be.
217
+
218
+ **❌ Incorrect: unnecessary async**
219
+ ```ts
220
+ it('should add two numbers', async () => {
221
+ const result = add(2, 3);
222
+ expect(result).toBe(5);
223
+ });
224
+ ```
225
+
226
+ **✅ Correct: synchronous test**
227
+ ```ts
228
+ it('should add two numbers', () => {
229
+ const result = add(2, 3);
230
+ expect(result).toBe(5);
231
+ });
232
+ ```
233
+
234
+ ## Batch Similar Tests
235
+
236
+ Use `it.each` to reduce setup duplication.
237
+
238
+ **❌ Incorrect: repeated setup**
239
+ ```ts
240
+ describe('isValidEmail', () => {
241
+ it('should return true for test@example.com', () => {
242
+ expect(isValidEmail('test@example.com')).toBe(true);
243
+ });
244
+
245
+ it('should return true for user.name@example.co.uk', () => {
246
+ expect(isValidEmail('user.name@example.co.uk')).toBe(true);
247
+ });
248
+
249
+ it('should return false for invalid', () => {
250
+ expect(isValidEmail('invalid')).toBe(false);
251
+ });
252
+
253
+ it('should return false for @example.com', () => {
254
+ expect(isValidEmail('@example.com')).toBe(false);
255
+ });
256
+ });
257
+ ```
258
+
259
+ **✅ Correct: parameterized tests**
260
+ ```ts
261
+ describe('isValidEmail', () => {
262
+ it.each([
263
+ { email: 'test@example.com', expected: true },
264
+ { email: 'user.name@example.co.uk', expected: true },
265
+ { email: 'invalid', expected: false },
266
+ { email: '@example.com', expected: false },
267
+ ])('should return $expected for "$email"', ({ email, expected }) => {
268
+ expect(isValidEmail(email)).toBe(expected);
269
+ });
270
+ });
271
+ // Less overhead, faster execution
272
+ ```
273
+
274
+ ## Lazy Initialization
275
+
276
+ Only create expensive objects when needed.
277
+
278
+ **❌ Incorrect: eager initialization**
279
+ ```ts
280
+ describe('OrderService', () => {
281
+ const emailService = new EmailService(); // Created even if not used
282
+ const paymentGateway = new PaymentGateway(); // Created even if not used
283
+
284
+ it('should calculate order total', () => {
285
+ const order = { items: [{ price: 10 }] };
286
+ expect(OrderService.calculateTotal(order)).toBe(10);
287
+ // Didn't need emailService or paymentGateway!
288
+ });
289
+ });
290
+ ```
291
+
292
+ **✅ Correct: lazy initialization**
293
+ ```ts
294
+ describe('OrderService', () => {
295
+ function createEmailService() {
296
+ return new EmailService();
297
+ }
298
+
299
+ function createPaymentGateway() {
300
+ return new PaymentGateway();
301
+ }
302
+
303
+ it('should calculate order total', () => {
304
+ // No services created
305
+ const order = { items: [{ price: 10 }] };
306
+ expect(OrderService.calculateTotal(order)).toBe(10);
307
+ });
308
+
309
+ it('should send confirmation email', async () => {
310
+ // Only create what's needed
311
+ const emailService = createEmailService();
312
+ const orderService = new OrderService(emailService);
313
+
314
+ await orderService.confirmOrder(order);
315
+ expect(emailService.getSentEmails()).toHaveLength(1);
316
+ });
317
+ });
318
+ ```
319
+
320
+ ## Cleanup Between Tests
321
+
322
+ Always clean up to prevent memory leaks and test pollution.
323
+
324
+ **✅ Correct: proper cleanup**
325
+ ```ts
326
+ describe('EventEmitter', () => {
327
+ let emitter: EventEmitter;
328
+
329
+ beforeEach(() => {
330
+ emitter = new EventEmitter();
331
+ });
332
+
333
+ afterEach(() => {
334
+ emitter.removeAllListeners(); // Clean up listeners
335
+ vi.clearAllMocks(); // Clear mock call history
336
+ });
337
+
338
+ it('should emit event', () => {
339
+ const listener = vi.fn();
340
+ emitter.on('test', listener);
341
+ emitter.emit('test');
342
+ expect(listener).toHaveBeenCalled();
343
+ });
344
+ });
345
+ ```
346
+
347
+ ## Use Test-Specific Data
348
+
349
+ Create minimal test data instead of large fixtures.
350
+
351
+ **❌ Incorrect: large, realistic data**
352
+ ```ts
353
+ it('should validate user name', () => {
354
+ const user = {
355
+ id: '550e8400-e29b-41d4-a716-446655440000',
356
+ name: 'John Doe',
357
+ email: 'john.doe@example.com',
358
+ phone: '+1-555-123-4567',
359
+ address: {
360
+ street: '123 Main St',
361
+ city: 'Springfield',
362
+ state: 'IL',
363
+ zip: '62701',
364
+ country: 'USA',
365
+ },
366
+ preferences: {
367
+ theme: 'dark',
368
+ language: 'en',
369
+ timezone: 'America/Chicago',
370
+ notifications: {
371
+ email: true,
372
+ sms: false,
373
+ push: true,
374
+ },
375
+ },
376
+ createdAt: new Date('2024-01-01'),
377
+ updatedAt: new Date('2024-01-15'),
378
+ };
379
+
380
+ expect(validateUserName(user.name)).toBe(true);
381
+ // Only needed name!
382
+ });
383
+ ```
384
+
385
+ **✅ Correct: minimal test data**
386
+ ```ts
387
+ it('should validate user name', () => {
388
+ expect(validateUserName('John Doe')).toBe(true);
389
+ });
390
+
391
+ it('should validate full user object', () => {
392
+ const user = {
393
+ name: 'John Doe',
394
+ email: 'john@example.com',
395
+ };
396
+ expect(validateUser(user)).toBe(true);
397
+ });
398
+ ```
399
+
400
+ ## Avoid Deep Object Comparisons
401
+
402
+ Use specific assertions instead of comparing entire objects.
403
+
404
+ **❌ Incorrect: deep comparison**
405
+ ```ts
406
+ it('should update user name', async () => {
407
+ const user = await userService.updateName('user-123', 'Jane Doe');
408
+
409
+ expect(user).toEqual({
410
+ id: 'user-123',
411
+ name: 'Jane Doe',
412
+ email: 'user@example.com',
413
+ createdAt: expect.any(Date),
414
+ updatedAt: expect.any(Date),
415
+ preferences: { /* large nested object */ },
416
+ // ... many more fields
417
+ });
418
+ });
419
+ ```
420
+
421
+ **✅ Correct: specific assertions**
422
+ ```ts
423
+ it('should update user name', async () => {
424
+ const user = await userService.updateName('user-123', 'Jane Doe');
425
+
426
+ expect(user.name).toBe('Jane Doe');
427
+ expect(user.id).toBe('user-123');
428
+ });
429
+ ```
430
+
431
+ ## Run Tests in Parallel
432
+
433
+ Vitest runs tests in parallel by default. Don't disable it unless necessary.
434
+
435
+ **✅ Correct: parallel execution (default)**
436
+ ```ts
437
+ // vitest.config.ts
438
+ export default {
439
+ test: {
440
+ // No need to configure - parallel by default
441
+ },
442
+ };
443
+ ```
444
+
445
+ **❌ Incorrect: forcing sequential execution**
446
+ ```ts
447
+ // vitest.config.ts
448
+ export default {
449
+ test: {
450
+ pool: 'forks',
451
+ poolOptions: {
452
+ threads: {
453
+ singleThread: true, // Slow!
454
+ },
455
+ },
456
+ },
457
+ };
458
+ ```
459
+
460
+ ## Isolate Test Files
461
+
462
+ Avoid shared global state between test files.
463
+
464
+ **❌ Incorrect: shared mutable state**
465
+ ```ts
466
+ // global-state.ts
467
+ export const cache = new Map();
468
+
469
+ // test1.test.ts
470
+ import { cache } from './global-state';
471
+
472
+ it('should add item to cache', () => {
473
+ cache.set('key', 'value');
474
+ expect(cache.get('key')).toBe('value');
475
+ });
476
+
477
+ // test2.test.ts
478
+ import { cache } from './global-state';
479
+
480
+ it('should have empty cache', () => {
481
+ expect(cache.size).toBe(0); // Fails if test1 runs first!
482
+ });
483
+ ```
484
+
485
+ **✅ Correct: isolated state**
486
+ ```ts
487
+ // test1.test.ts
488
+ it('should add item to cache', () => {
489
+ const cache = new Map();
490
+ cache.set('key', 'value');
491
+ expect(cache.get('key')).toBe('value');
492
+ });
493
+
494
+ // test2.test.ts
495
+ it('should have empty cache', () => {
496
+ const cache = new Map();
497
+ expect(cache.size).toBe(0);
498
+ });
499
+ ```
500
+
501
+ ## Monitor Test Performance
502
+
503
+ Identify and fix slow tests using Vitest's reporter.
504
+
505
+ ```bash
506
+ # Run tests with timing information
507
+ vitest --reporter=verbose
508
+
509
+ # Find slow tests
510
+ vitest --reporter=default --slow-test-threshold=1000
511
+ ```
512
+
513
+ **✅ Correct: refactor slow tests**
514
+ ```ts
515
+ // Before: 5 seconds
516
+ it('should process large dataset', async () => {
517
+ const data = await fetchLargeDataset(); // Slow API call
518
+ const result = processData(data);
519
+ expect(result.length).toBeGreaterThan(0);
520
+ });
521
+
522
+ // After: <10ms
523
+ it('should process large dataset', () => {
524
+ const data = createMockDataset(1000); // Fast mock data
525
+ const result = processData(data);
526
+ expect(result.length).toBe(1000);
527
+ });
528
+ ```