@patricio0312rev/skillset 0.1.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 (115) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +21 -0
  3. package/README.md +176 -0
  4. package/bin/cli.js +37 -0
  5. package/package.json +55 -0
  6. package/src/commands/init.js +301 -0
  7. package/src/index.js +168 -0
  8. package/src/lib/config.js +200 -0
  9. package/src/lib/generator.js +166 -0
  10. package/src/utils/display.js +95 -0
  11. package/src/utils/readme.js +196 -0
  12. package/src/utils/tool-specific.js +233 -0
  13. package/templates/ai-engineering/agent-orchestration-planner/ SKILL.md +266 -0
  14. package/templates/ai-engineering/cost-latency-optimizer/ SKILL.md +270 -0
  15. package/templates/ai-engineering/doc-to-vector-dataset-generator/ SKILL.md +239 -0
  16. package/templates/ai-engineering/evaluation-harness/ SKILL.md +219 -0
  17. package/templates/ai-engineering/guardrails-safety-filter-builder/ SKILL.md +226 -0
  18. package/templates/ai-engineering/llm-debugger/ SKILL.md +283 -0
  19. package/templates/ai-engineering/prompt-regression-tester/ SKILL.md +216 -0
  20. package/templates/ai-engineering/prompt-template-builder/ SKILL.md +393 -0
  21. package/templates/ai-engineering/rag-pipeline-builder/ SKILL.md +244 -0
  22. package/templates/ai-engineering/tool-function-schema-designer/ SKILL.md +219 -0
  23. package/templates/architecture/adr-writer/ SKILL.md +250 -0
  24. package/templates/architecture/api-versioning-deprecation-planner/ SKILL.md +331 -0
  25. package/templates/architecture/domain-model-boundaries-mapper/ SKILL.md +300 -0
  26. package/templates/architecture/migration-planner/ SKILL.md +376 -0
  27. package/templates/architecture/performance-budget-setter/ SKILL.md +318 -0
  28. package/templates/architecture/reliability-strategy-builder/ SKILL.md +286 -0
  29. package/templates/architecture/rfc-generator/ SKILL.md +362 -0
  30. package/templates/architecture/scalability-playbook/ SKILL.md +279 -0
  31. package/templates/architecture/system-design-generator/ SKILL.md +339 -0
  32. package/templates/architecture/tech-debt-prioritizer/ SKILL.md +329 -0
  33. package/templates/backend/api-contract-normalizer/ SKILL.md +487 -0
  34. package/templates/backend/api-endpoint-generator/ SKILL.md +415 -0
  35. package/templates/backend/auth-module-builder/ SKILL.md +99 -0
  36. package/templates/backend/background-jobs-designer/ SKILL.md +166 -0
  37. package/templates/backend/caching-strategist/ SKILL.md +190 -0
  38. package/templates/backend/error-handling-standardizer/ SKILL.md +174 -0
  39. package/templates/backend/rate-limiting-abuse-protection/ SKILL.md +147 -0
  40. package/templates/backend/rbac-permissions-builder/ SKILL.md +158 -0
  41. package/templates/backend/service-layer-extractor/ SKILL.md +269 -0
  42. package/templates/backend/webhook-receiver-hardener/ SKILL.md +211 -0
  43. package/templates/ci-cd/artifact-sbom-publisher/ SKILL.md +236 -0
  44. package/templates/ci-cd/caching-strategy-optimizer/ SKILL.md +195 -0
  45. package/templates/ci-cd/deployment-checklist-generator/ SKILL.md +381 -0
  46. package/templates/ci-cd/github-actions-pipeline-creator/ SKILL.md +348 -0
  47. package/templates/ci-cd/monorepo-ci-optimizer/ SKILL.md +298 -0
  48. package/templates/ci-cd/preview-environments-builder/ SKILL.md +187 -0
  49. package/templates/ci-cd/quality-gates-enforcer/ SKILL.md +342 -0
  50. package/templates/ci-cd/release-automation-builder/ SKILL.md +281 -0
  51. package/templates/ci-cd/rollback-workflow-builder/ SKILL.md +372 -0
  52. package/templates/ci-cd/secrets-env-manager/ SKILL.md +242 -0
  53. package/templates/db-management/backup-restore-runbook-generator/ SKILL.md +505 -0
  54. package/templates/db-management/data-integrity-auditor/ SKILL.md +505 -0
  55. package/templates/db-management/data-retention-archiving-planner/ SKILL.md +430 -0
  56. package/templates/db-management/data-seeding-fixtures-builder/ SKILL.md +375 -0
  57. package/templates/db-management/db-performance-watchlist/ SKILL.md +425 -0
  58. package/templates/db-management/etl-sync-job-builder/ SKILL.md +457 -0
  59. package/templates/db-management/multi-tenant-safety-checker/ SKILL.md +398 -0
  60. package/templates/db-management/prisma-migration-assistant/ SKILL.md +379 -0
  61. package/templates/db-management/schema-consistency-checker/ SKILL.md +440 -0
  62. package/templates/db-management/sql-query-optimizer/ SKILL.md +324 -0
  63. package/templates/foundation/changelog-writer/ SKILL.md +431 -0
  64. package/templates/foundation/code-formatter-installer/ SKILL.md +320 -0
  65. package/templates/foundation/codebase-summarizer/ SKILL.md +360 -0
  66. package/templates/foundation/dependency-doctor/ SKILL.md +163 -0
  67. package/templates/foundation/dev-environment-bootstrapper/ SKILL.md +259 -0
  68. package/templates/foundation/dev-onboarding-builder/ SKILL.md +556 -0
  69. package/templates/foundation/docs-starter-kit/ SKILL.md +574 -0
  70. package/templates/foundation/explaining-code/SKILL.md +13 -0
  71. package/templates/foundation/git-hygiene-enforcer/ SKILL.md +455 -0
  72. package/templates/foundation/project-scaffolder/ SKILL.md +65 -0
  73. package/templates/foundation/project-scaffolder/references/templates.md +126 -0
  74. package/templates/foundation/repo-structure-linter/ SKILL.md +0 -0
  75. package/templates/foundation/repo-structure-linter/references/conventions.md +98 -0
  76. package/templates/frontend/animation-micro-interaction-pack/ SKILL.md +41 -0
  77. package/templates/frontend/component-scaffold-generator/ SKILL.md +562 -0
  78. package/templates/frontend/design-to-component-translator/ SKILL.md +547 -0
  79. package/templates/frontend/form-wizard-builder/ SKILL.md +553 -0
  80. package/templates/frontend/frontend-refactor-planner/ SKILL.md +37 -0
  81. package/templates/frontend/i18n-frontend-implementer/ SKILL.md +44 -0
  82. package/templates/frontend/modal-drawer-system/ SKILL.md +377 -0
  83. package/templates/frontend/page-layout-builder/ SKILL.md +630 -0
  84. package/templates/frontend/state-ux-flow-builder/ SKILL.md +23 -0
  85. package/templates/frontend/table-builder/ SKILL.md +350 -0
  86. package/templates/performance/alerting-dashboard-builder/ SKILL.md +162 -0
  87. package/templates/performance/backend-latency-profiler-helper/ SKILL.md +108 -0
  88. package/templates/performance/caching-cdn-strategy-planner/ SKILL.md +150 -0
  89. package/templates/performance/capacity-planning-helper/ SKILL.md +242 -0
  90. package/templates/performance/core-web-vitals-tuner/ SKILL.md +126 -0
  91. package/templates/performance/incident-runbook-generator/ SKILL.md +162 -0
  92. package/templates/performance/load-test-scenario-builder/ SKILL.md +256 -0
  93. package/templates/performance/observability-setup/ SKILL.md +232 -0
  94. package/templates/performance/postmortem-writer/ SKILL.md +203 -0
  95. package/templates/performance/structured-logging-standardizer/ SKILL.md +122 -0
  96. package/templates/security/auth-security-reviewer/ SKILL.md +428 -0
  97. package/templates/security/dependency-vulnerability-triage/ SKILL.md +495 -0
  98. package/templates/security/input-validation-sanitization-auditor/ SKILL.md +76 -0
  99. package/templates/security/pii-redaction-logging-policy-builder/ SKILL.md +65 -0
  100. package/templates/security/rbac-policy-tester/ SKILL.md +80 -0
  101. package/templates/security/secrets-scanner/ SKILL.md +462 -0
  102. package/templates/security/secure-headers-csp-builder/ SKILL.md +404 -0
  103. package/templates/security/security-incident-playbook-generator/ SKILL.md +76 -0
  104. package/templates/security/security-pr-checklist-skill/ SKILL.md +62 -0
  105. package/templates/security/threat-model-generator/ SKILL.md +394 -0
  106. package/templates/testing/contract-testing-builder/ SKILL.md +492 -0
  107. package/templates/testing/coverage-strategist/ SKILL.md +436 -0
  108. package/templates/testing/e2e-test-builder/ SKILL.md +382 -0
  109. package/templates/testing/flaky-test-detective/ SKILL.md +416 -0
  110. package/templates/testing/integration-test-builder/ SKILL.md +525 -0
  111. package/templates/testing/mocking-assistant/ SKILL.md +383 -0
  112. package/templates/testing/snapshot-test-refactorer/ SKILL.md +375 -0
  113. package/templates/testing/test-data-factory-builder/ SKILL.md +449 -0
  114. package/templates/testing/test-reporting-triage-skill/ SKILL.md +469 -0
  115. package/templates/testing/unit-test-generator/ SKILL.md +548 -0
@@ -0,0 +1,548 @@
1
+ ---
2
+ name: unit-test-generator
3
+ description: Generates comprehensive unit tests with AAA pattern (Arrange-Act-Assert), edge cases, error scenarios, and coverage analysis. Creates test files matching source structure with complete test suites. Use for "unit testing", "test generation", "Jest tests", or "test coverage".
4
+ ---
5
+
6
+ # Unit Test Generator
7
+
8
+ Generate comprehensive unit tests with edge cases and AAA pattern.
9
+
10
+ ## AAA Pattern Template
11
+
12
+ ```typescript
13
+ // tests/utils/validator.test.ts
14
+ import { describe, it, expect } from "vitest";
15
+ import { validateEmail } from "@/utils/validator";
16
+
17
+ describe("validateEmail", () => {
18
+ it("should return true for valid email", () => {
19
+ // Arrange
20
+ const email = "user@example.com";
21
+
22
+ // Act
23
+ const result = validateEmail(email);
24
+
25
+ // Assert
26
+ expect(result).toBe(true);
27
+ });
28
+
29
+ it("should return false for invalid email - missing @", () => {
30
+ // Arrange
31
+ const email = "userexample.com";
32
+
33
+ // Act
34
+ const result = validateEmail(email);
35
+
36
+ // Assert
37
+ expect(result).toBe(false);
38
+ });
39
+
40
+ it("should return false for invalid email - missing domain", () => {
41
+ // Arrange
42
+ const email = "user@";
43
+
44
+ // Act
45
+ const result = validateEmail(email);
46
+
47
+ // Assert
48
+ expect(result).toBe(false);
49
+ });
50
+ });
51
+ ```
52
+
53
+ ## Comprehensive Test Cases
54
+
55
+ ```typescript
56
+ // src/utils/calculator.ts
57
+ export function divide(a: number, b: number): number {
58
+ if (b === 0) {
59
+ throw new Error("Division by zero");
60
+ }
61
+ return a / b;
62
+ }
63
+
64
+ // tests/utils/calculator.test.ts
65
+ describe("divide", () => {
66
+ describe("happy path", () => {
67
+ it("should divide positive numbers", () => {
68
+ expect(divide(10, 2)).toBe(5);
69
+ });
70
+
71
+ it("should divide negative numbers", () => {
72
+ expect(divide(-10, 2)).toBe(-5);
73
+ expect(divide(10, -2)).toBe(-5);
74
+ expect(divide(-10, -2)).toBe(5);
75
+ });
76
+
77
+ it("should handle decimal results", () => {
78
+ expect(divide(10, 3)).toBeCloseTo(3.333, 3);
79
+ });
80
+ });
81
+
82
+ describe("edge cases", () => {
83
+ it("should handle zero dividend", () => {
84
+ expect(divide(0, 5)).toBe(0);
85
+ });
86
+
87
+ it("should handle very large numbers", () => {
88
+ expect(divide(Number.MAX_SAFE_INTEGER, 2)).toBe(
89
+ Number.MAX_SAFE_INTEGER / 2
90
+ );
91
+ });
92
+
93
+ it("should handle very small numbers", () => {
94
+ expect(divide(0.0001, 0.0001)).toBe(1);
95
+ });
96
+ });
97
+
98
+ describe("error cases", () => {
99
+ it("should throw error when dividing by zero", () => {
100
+ expect(() => divide(10, 0)).toThrow("Division by zero");
101
+ });
102
+
103
+ it("should throw error when dividing by negative zero", () => {
104
+ expect(() => divide(10, -0)).toThrow("Division by zero");
105
+ });
106
+ });
107
+ });
108
+ ```
109
+
110
+ ## Async Function Testing
111
+
112
+ ```typescript
113
+ // src/services/userService.ts
114
+ export async function fetchUser(id: string): Promise<User> {
115
+ const response = await fetch(`/api/users/${id}`);
116
+
117
+ if (!response.ok) {
118
+ throw new Error(`User not found: ${id}`);
119
+ }
120
+
121
+ return response.json();
122
+ }
123
+
124
+ // tests/services/userService.test.ts
125
+ describe("fetchUser", () => {
126
+ beforeEach(() => {
127
+ global.fetch = vi.fn();
128
+ });
129
+
130
+ afterEach(() => {
131
+ vi.resetAllMocks();
132
+ });
133
+
134
+ it("should fetch user successfully", async () => {
135
+ // Arrange
136
+ const mockUser = { id: "123", name: "John" };
137
+ (global.fetch as any).mockResolvedValueOnce({
138
+ ok: true,
139
+ json: async () => mockUser,
140
+ });
141
+
142
+ // Act
143
+ const user = await fetchUser("123");
144
+
145
+ // Assert
146
+ expect(user).toEqual(mockUser);
147
+ expect(global.fetch).toHaveBeenCalledWith("/api/users/123");
148
+ });
149
+
150
+ it("should throw error when user not found", async () => {
151
+ // Arrange
152
+ (global.fetch as any).mockResolvedValueOnce({
153
+ ok: false,
154
+ });
155
+
156
+ // Act & Assert
157
+ await expect(fetchUser("999")).rejects.toThrow("User not found: 999");
158
+ });
159
+
160
+ it("should handle network error", async () => {
161
+ // Arrange
162
+ (global.fetch as any).mockRejectedValueOnce(new Error("Network error"));
163
+
164
+ // Act & Assert
165
+ await expect(fetchUser("123")).rejects.toThrow("Network error");
166
+ });
167
+ });
168
+ ```
169
+
170
+ ## Testing Classes
171
+
172
+ ```typescript
173
+ // src/models/ShoppingCart.ts
174
+ export class ShoppingCart {
175
+ private items: CartItem[] = [];
176
+
177
+ add(item: CartItem): void {
178
+ this.items.push(item);
179
+ }
180
+
181
+ remove(itemId: string): void {
182
+ this.items = this.items.filter((i) => i.id !== itemId);
183
+ }
184
+
185
+ getTotal(): number {
186
+ return this.items.reduce(
187
+ (sum, item) => sum + item.price * item.quantity,
188
+ 0
189
+ );
190
+ }
191
+
192
+ clear(): void {
193
+ this.items = [];
194
+ }
195
+ }
196
+
197
+ // tests/models/ShoppingCart.test.ts
198
+ describe("ShoppingCart", () => {
199
+ let cart: ShoppingCart;
200
+
201
+ beforeEach(() => {
202
+ cart = new ShoppingCart();
203
+ });
204
+
205
+ describe("add", () => {
206
+ it("should add item to cart", () => {
207
+ // Arrange
208
+ const item = { id: "1", name: "Product", price: 10, quantity: 1 };
209
+
210
+ // Act
211
+ cart.add(item);
212
+
213
+ // Assert
214
+ expect(cart.getTotal()).toBe(10);
215
+ });
216
+
217
+ it("should add multiple items", () => {
218
+ // Arrange
219
+ const item1 = { id: "1", name: "Product 1", price: 10, quantity: 1 };
220
+ const item2 = { id: "2", name: "Product 2", price: 20, quantity: 2 };
221
+
222
+ // Act
223
+ cart.add(item1);
224
+ cart.add(item2);
225
+
226
+ // Assert
227
+ expect(cart.getTotal()).toBe(50); // 10 + (20 * 2)
228
+ });
229
+ });
230
+
231
+ describe("remove", () => {
232
+ it("should remove item from cart", () => {
233
+ // Arrange
234
+ const item = { id: "1", name: "Product", price: 10, quantity: 1 };
235
+ cart.add(item);
236
+
237
+ // Act
238
+ cart.remove("1");
239
+
240
+ // Assert
241
+ expect(cart.getTotal()).toBe(0);
242
+ });
243
+
244
+ it("should not throw when removing non-existent item", () => {
245
+ // Act & Assert
246
+ expect(() => cart.remove("999")).not.toThrow();
247
+ });
248
+ });
249
+
250
+ describe("getTotal", () => {
251
+ it("should return 0 for empty cart", () => {
252
+ expect(cart.getTotal()).toBe(0);
253
+ });
254
+
255
+ it("should calculate total with quantities", () => {
256
+ // Arrange
257
+ cart.add({ id: "1", name: "Product", price: 10, quantity: 3 });
258
+
259
+ // Assert
260
+ expect(cart.getTotal()).toBe(30);
261
+ });
262
+ });
263
+
264
+ describe("clear", () => {
265
+ it("should remove all items", () => {
266
+ // Arrange
267
+ cart.add({ id: "1", name: "Product 1", price: 10, quantity: 1 });
268
+ cart.add({ id: "2", name: "Product 2", price: 20, quantity: 1 });
269
+
270
+ // Act
271
+ cart.clear();
272
+
273
+ // Assert
274
+ expect(cart.getTotal()).toBe(0);
275
+ });
276
+ });
277
+ });
278
+ ```
279
+
280
+ ## Testing React Components
281
+
282
+ ```typescript
283
+ // src/components/Counter.tsx
284
+ export function Counter() {
285
+ const [count, setCount] = useState(0);
286
+
287
+ return (
288
+ <div>
289
+ <p>Count: {count}</p>
290
+ <button onClick={() => setCount(count + 1)}>Increment</button>
291
+ <button onClick={() => setCount(0)}>Reset</button>
292
+ </div>
293
+ );
294
+ }
295
+
296
+ // tests/components/Counter.test.tsx
297
+ import { render, screen, fireEvent } from "@testing-library/react";
298
+
299
+ describe("Counter", () => {
300
+ it("should render with initial count of 0", () => {
301
+ // Arrange & Act
302
+ render(<Counter />);
303
+
304
+ // Assert
305
+ expect(screen.getByText("Count: 0")).toBeInTheDocument();
306
+ });
307
+
308
+ it("should increment count when button clicked", () => {
309
+ // Arrange
310
+ render(<Counter />);
311
+ const button = screen.getByText("Increment");
312
+
313
+ // Act
314
+ fireEvent.click(button);
315
+
316
+ // Assert
317
+ expect(screen.getByText("Count: 1")).toBeInTheDocument();
318
+ });
319
+
320
+ it("should increment multiple times", () => {
321
+ // Arrange
322
+ render(<Counter />);
323
+ const button = screen.getByText("Increment");
324
+
325
+ // Act
326
+ fireEvent.click(button);
327
+ fireEvent.click(button);
328
+ fireEvent.click(button);
329
+
330
+ // Assert
331
+ expect(screen.getByText("Count: 3")).toBeInTheDocument();
332
+ });
333
+
334
+ it("should reset count to 0", () => {
335
+ // Arrange
336
+ render(<Counter />);
337
+ fireEvent.click(screen.getByText("Increment"));
338
+
339
+ // Act
340
+ fireEvent.click(screen.getByText("Reset"));
341
+
342
+ // Assert
343
+ expect(screen.getByText("Count: 0")).toBeInTheDocument();
344
+ });
345
+ });
346
+ ```
347
+
348
+ ## Edge Case Categories
349
+
350
+ ```typescript
351
+ // Test case generation template
352
+ interface TestCase {
353
+ category: "happy-path" | "edge-case" | "error-case";
354
+ description: string;
355
+ input: any;
356
+ expectedOutput: any;
357
+ }
358
+
359
+ const testCases: TestCase[] = [
360
+ // Happy path
361
+ {
362
+ category: "happy-path",
363
+ description: "typical valid input",
364
+ input: "user@example.com",
365
+ expectedOutput: true,
366
+ },
367
+
368
+ // Edge cases
369
+ {
370
+ category: "edge-case",
371
+ description: "empty string",
372
+ input: "",
373
+ expectedOutput: false,
374
+ },
375
+ {
376
+ category: "edge-case",
377
+ description: "null input",
378
+ input: null,
379
+ expectedOutput: false,
380
+ },
381
+ {
382
+ category: "edge-case",
383
+ description: "undefined input",
384
+ input: undefined,
385
+ expectedOutput: false,
386
+ },
387
+ {
388
+ category: "edge-case",
389
+ description: "whitespace only",
390
+ input: " ",
391
+ expectedOutput: false,
392
+ },
393
+ {
394
+ category: "edge-case",
395
+ description: "very long email",
396
+ input: "a".repeat(1000) + "@example.com",
397
+ expectedOutput: false,
398
+ },
399
+
400
+ // Error cases
401
+ {
402
+ category: "error-case",
403
+ description: "invalid format - no @",
404
+ input: "userexample.com",
405
+ expectedOutput: false,
406
+ },
407
+ {
408
+ category: "error-case",
409
+ description: "invalid format - multiple @",
410
+ input: "user@@example.com",
411
+ expectedOutput: false,
412
+ },
413
+ ];
414
+ ```
415
+
416
+ ## Coverage Notes
417
+
418
+ ```typescript
419
+ /**
420
+ * Coverage targets for this module:
421
+ *
422
+ * - Line coverage: 100% (all lines executed)
423
+ * - Branch coverage: 100% (all if/else paths tested)
424
+ * - Function coverage: 100% (all functions called)
425
+ * - Statement coverage: 100% (all statements executed)
426
+ *
427
+ * Untested scenarios (intentionally):
428
+ * - None - module is fully covered
429
+ *
430
+ * High-risk areas requiring extra attention:
431
+ * - Division by zero handling
432
+ * - Null/undefined input handling
433
+ * - Type coercion edge cases
434
+ */
435
+ ```
436
+
437
+ ## Test File Structure
438
+
439
+ ```
440
+ src/
441
+ utils/
442
+ validator.ts
443
+ calculator.ts
444
+ services/
445
+ userService.ts
446
+ models/
447
+ ShoppingCart.ts
448
+ components/
449
+ Counter.tsx
450
+
451
+ tests/
452
+ utils/
453
+ validator.test.ts
454
+ calculator.test.ts
455
+ services/
456
+ userService.test.ts
457
+ models/
458
+ ShoppingCart.test.ts
459
+ components/
460
+ Counter.test.tsx
461
+ ```
462
+
463
+ ## Test Generation Script
464
+
465
+ ```typescript
466
+ // scripts/generate-tests.ts
467
+ import * as fs from "fs";
468
+ import * as path from "path";
469
+
470
+ function generateTestTemplate(filePath: string): string {
471
+ const fileName = path.basename(filePath, path.extname(filePath));
472
+ const className = fileName.charAt(0).toUpperCase() + fileName.slice(1);
473
+
474
+ return `
475
+ import { describe, it, expect } from 'vitest';
476
+ import { ${className} } from '@/${filePath}';
477
+
478
+ describe('${className}', () => {
479
+ describe('happy path', () => {
480
+ it('should handle typical case', () => {
481
+ // Arrange
482
+ const input = /* TODO */;
483
+
484
+ // Act
485
+ const result = ${className}(input);
486
+
487
+ // Assert
488
+ expect(result).toBe(/* TODO */);
489
+ });
490
+ });
491
+
492
+ describe('edge cases', () => {
493
+ it('should handle null input', () => {
494
+ // Arrange
495
+ const input = null;
496
+
497
+ // Act & Assert
498
+ expect(() => ${className}(input)).toThrow();
499
+ });
500
+
501
+ it('should handle empty input', () => {
502
+ // Arrange
503
+ const input = '';
504
+
505
+ // Act
506
+ const result = ${className}(input);
507
+
508
+ // Assert
509
+ expect(result).toBe(/* TODO */);
510
+ });
511
+ });
512
+
513
+ describe('error cases', () => {
514
+ it('should throw error for invalid input', () => {
515
+ // Arrange
516
+ const input = /* TODO */;
517
+
518
+ // Act & Assert
519
+ expect(() => ${className}(input)).toThrow('Invalid input');
520
+ });
521
+ });
522
+ });
523
+ `.trim();
524
+ }
525
+ ```
526
+
527
+ ## Best Practices
528
+
529
+ 1. **AAA pattern**: Arrange-Act-Assert structure
530
+ 2. **One assertion per test**: Keep tests focused
531
+ 3. **Descriptive names**: "should [expected behavior] when [condition]"
532
+ 4. **Test edge cases**: null, undefined, empty, max values
533
+ 5. **Test errors**: Verify error handling
534
+ 6. **Isolated tests**: No shared state between tests
535
+ 7. **Fast tests**: Unit tests should run in milliseconds
536
+
537
+ ## Output Checklist
538
+
539
+ - [ ] Test file created matching source structure
540
+ - [ ] AAA pattern used consistently
541
+ - [ ] Happy path cases covered
542
+ - [ ] Edge cases identified and tested
543
+ - [ ] Error cases tested
544
+ - [ ] Async functions tested with proper awaits
545
+ - [ ] Mocks used for dependencies
546
+ - [ ] Coverage notes documented
547
+ - [ ] Descriptive test names
548
+ - [ ] Setup/teardown hooks used appropriately