@oalacea/daemon 0.5.0 → 0.6.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.
- package/LICENSE +23 -23
- package/README.md +147 -141
- package/bin/Dockerfile +75 -74
- package/dist/cli/cli.d.ts +42 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +89 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/detect.command.d.ts +39 -0
- package/dist/cli/commands/detect.command.d.ts.map +1 -0
- package/dist/cli/commands/detect.command.js +111 -0
- package/dist/cli/commands/detect.command.js.map +1 -0
- package/dist/cli/commands/index.d.ts +14 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +11 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.command.d.ts +41 -0
- package/dist/cli/commands/init.command.d.ts.map +1 -0
- package/dist/cli/commands/init.command.js +111 -0
- package/dist/cli/commands/init.command.js.map +1 -0
- package/dist/cli/commands/test.command.d.ts +58 -0
- package/dist/cli/commands/test.command.d.ts.map +1 -0
- package/dist/cli/commands/test.command.js +180 -0
- package/dist/cli/commands/test.command.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config/daemon.config.d.ts +32 -0
- package/dist/core/config/daemon.config.d.ts.map +1 -0
- package/dist/core/config/daemon.config.js +83 -0
- package/dist/core/config/daemon.config.js.map +1 -0
- package/dist/core/config/index.d.ts +5 -0
- package/dist/core/config/index.d.ts.map +1 -0
- package/dist/core/config/index.js +5 -0
- package/dist/core/config/index.js.map +1 -0
- package/dist/core/constants.d.ts +36 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +56 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/types/common.types.d.ts +250 -0
- package/dist/core/types/common.types.d.ts.map +1 -0
- package/dist/core/types/common.types.js +7 -0
- package/dist/core/types/common.types.js.map +1 -0
- package/dist/core/types/detection.types.d.ts +232 -0
- package/dist/core/types/detection.types.d.ts.map +1 -0
- package/dist/core/types/detection.types.js +22 -0
- package/dist/core/types/detection.types.js.map +1 -0
- package/dist/core/types/docker.types.d.ts +322 -0
- package/dist/core/types/docker.types.d.ts.map +1 -0
- package/dist/core/types/docker.types.js +7 -0
- package/dist/core/types/docker.types.js.map +1 -0
- package/dist/core/types/index.d.ts +11 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +7 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/types/project.types.d.ts +74 -0
- package/dist/core/types/project.types.d.ts.map +1 -0
- package/dist/core/types/project.types.js +7 -0
- package/dist/core/types/project.types.js.map +1 -0
- package/dist/core/types/shared.types.d.ts +118 -0
- package/dist/core/types/shared.types.d.ts.map +1 -0
- package/dist/core/types/shared.types.js +7 -0
- package/dist/core/types/shared.types.js.map +1 -0
- package/dist/core/types/test.types.d.ts +230 -0
- package/dist/core/types/test.types.d.ts.map +1 -0
- package/dist/core/types/test.types.js +7 -0
- package/dist/core/types/test.types.js.map +1 -0
- package/dist/services/detection/__tests__/framework-detector.test.d.ts +5 -0
- package/dist/services/detection/__tests__/framework-detector.test.d.ts.map +1 -0
- package/dist/services/detection/__tests__/framework-detector.test.js +52 -0
- package/dist/services/detection/__tests__/framework-detector.test.js.map +1 -0
- package/dist/services/detection/framework-detector.d.ts +179 -0
- package/dist/services/detection/framework-detector.d.ts.map +1 -0
- package/dist/services/detection/framework-detector.js +636 -0
- package/dist/services/detection/framework-detector.js.map +1 -0
- package/dist/services/detection/index.d.ts +10 -0
- package/dist/services/detection/index.d.ts.map +1 -0
- package/dist/services/detection/index.js +7 -0
- package/dist/services/detection/index.js.map +1 -0
- package/dist/services/docker/__tests__/docker-manager.test.d.ts +5 -0
- package/dist/services/docker/__tests__/docker-manager.test.d.ts.map +1 -0
- package/dist/services/docker/__tests__/docker-manager.test.js +67 -0
- package/dist/services/docker/__tests__/docker-manager.test.js.map +1 -0
- package/dist/services/docker/docker-manager.d.ts +157 -0
- package/dist/services/docker/docker-manager.d.ts.map +1 -0
- package/dist/services/docker/docker-manager.js +516 -0
- package/dist/services/docker/docker-manager.js.map +1 -0
- package/dist/services/docker/index.d.ts +9 -0
- package/dist/services/docker/index.d.ts.map +1 -0
- package/dist/services/docker/index.js +9 -0
- package/dist/services/docker/index.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/index.js.map +1 -0
- package/dist/shared/errors/__tests__/base.error.test.d.ts +5 -0
- package/dist/shared/errors/__tests__/base.error.test.d.ts.map +1 -0
- package/dist/shared/errors/__tests__/base.error.test.js +61 -0
- package/dist/shared/errors/__tests__/base.error.test.js.map +1 -0
- package/dist/shared/errors/__tests__/command.error.test.d.ts +5 -0
- package/dist/shared/errors/__tests__/command.error.test.d.ts.map +1 -0
- package/dist/shared/errors/__tests__/command.error.test.js +62 -0
- package/dist/shared/errors/__tests__/command.error.test.js.map +1 -0
- package/dist/shared/errors/__tests__/file.error.test.d.ts +5 -0
- package/dist/shared/errors/__tests__/file.error.test.d.ts.map +1 -0
- package/dist/shared/errors/__tests__/file.error.test.js +75 -0
- package/dist/shared/errors/__tests__/file.error.test.js.map +1 -0
- package/dist/shared/errors/__tests__/index.test.d.ts +5 -0
- package/dist/shared/errors/__tests__/index.test.d.ts.map +1 -0
- package/dist/shared/errors/__tests__/index.test.js +62 -0
- package/dist/shared/errors/__tests__/index.test.js.map +1 -0
- package/dist/shared/errors/__tests__/validation.error.test.d.ts +5 -0
- package/dist/shared/errors/__tests__/validation.error.test.d.ts.map +1 -0
- package/dist/shared/errors/__tests__/validation.error.test.js +79 -0
- package/dist/shared/errors/__tests__/validation.error.test.js.map +1 -0
- package/dist/shared/errors/base.error.d.ts +54 -0
- package/dist/shared/errors/base.error.d.ts.map +1 -0
- package/dist/shared/errors/base.error.js +85 -0
- package/dist/shared/errors/base.error.js.map +1 -0
- package/dist/shared/errors/command.error.d.ts +58 -0
- package/dist/shared/errors/command.error.d.ts.map +1 -0
- package/dist/shared/errors/command.error.js +102 -0
- package/dist/shared/errors/command.error.js.map +1 -0
- package/dist/shared/errors/detection.error.d.ts +42 -0
- package/dist/shared/errors/detection.error.d.ts.map +1 -0
- package/dist/shared/errors/detection.error.js +82 -0
- package/dist/shared/errors/detection.error.js.map +1 -0
- package/dist/shared/errors/docker.error.d.ts +142 -0
- package/dist/shared/errors/docker.error.d.ts.map +1 -0
- package/dist/shared/errors/docker.error.js +172 -0
- package/dist/shared/errors/docker.error.js.map +1 -0
- package/dist/shared/errors/file.error.d.ts +66 -0
- package/dist/shared/errors/file.error.d.ts.map +1 -0
- package/dist/shared/errors/file.error.js +93 -0
- package/dist/shared/errors/file.error.js.map +1 -0
- package/dist/shared/errors/index.d.ts +56 -0
- package/dist/shared/errors/index.d.ts.map +1 -0
- package/dist/shared/errors/index.js +86 -0
- package/dist/shared/errors/index.js.map +1 -0
- package/dist/shared/errors/validation.error.d.ts +67 -0
- package/dist/shared/errors/validation.error.d.ts.map +1 -0
- package/dist/shared/errors/validation.error.js +97 -0
- package/dist/shared/errors/validation.error.js.map +1 -0
- package/dist/shared/templates/index.d.ts +2 -0
- package/dist/shared/templates/index.d.ts.map +1 -0
- package/dist/shared/templates/index.js +2 -0
- package/dist/shared/templates/index.js.map +1 -0
- package/dist/shared/templates/prompt-builder.d.ts +2 -0
- package/dist/shared/templates/prompt-builder.d.ts.map +1 -0
- package/dist/shared/templates/prompt-builder.js +2 -0
- package/dist/shared/templates/prompt-builder.js.map +1 -0
- package/dist/shared/templates/template-engine.d.ts +2 -0
- package/dist/shared/templates/template-engine.d.ts.map +1 -0
- package/dist/shared/templates/template-engine.js +2 -0
- package/dist/shared/templates/template-engine.js.map +1 -0
- package/dist/shared/utils/__tests__/command-executor.test.d.ts +5 -0
- package/dist/shared/utils/__tests__/command-executor.test.d.ts.map +1 -0
- package/dist/shared/utils/__tests__/command-executor.test.js +45 -0
- package/dist/shared/utils/__tests__/command-executor.test.js.map +1 -0
- package/dist/shared/utils/__tests__/file-helper.test.d.ts +5 -0
- package/dist/shared/utils/__tests__/file-helper.test.d.ts.map +1 -0
- package/dist/shared/utils/__tests__/file-helper.test.js +71 -0
- package/dist/shared/utils/__tests__/file-helper.test.js.map +1 -0
- package/dist/shared/utils/__tests__/logger.test.d.ts +5 -0
- package/dist/shared/utils/__tests__/logger.test.d.ts.map +1 -0
- package/dist/shared/utils/__tests__/logger.test.js +83 -0
- package/dist/shared/utils/__tests__/logger.test.js.map +1 -0
- package/dist/shared/utils/command-executer.d.ts +2 -0
- package/dist/shared/utils/command-executer.d.ts.map +1 -0
- package/dist/shared/utils/command-executer.js +2 -0
- package/dist/shared/utils/command-executer.js.map +1 -0
- package/dist/shared/utils/command-executor.d.ts +255 -0
- package/dist/shared/utils/command-executor.d.ts.map +1 -0
- package/dist/shared/utils/command-executor.js +287 -0
- package/dist/shared/utils/command-executor.js.map +1 -0
- package/dist/shared/utils/file-helper.d.ts +86 -0
- package/dist/shared/utils/file-helper.d.ts.map +1 -0
- package/dist/shared/utils/file-helper.js +323 -0
- package/dist/shared/utils/file-helper.js.map +1 -0
- package/dist/shared/utils/index.d.ts +9 -0
- package/dist/shared/utils/index.d.ts.map +1 -0
- package/dist/shared/utils/index.js +9 -0
- package/dist/shared/utils/index.js.map +1 -0
- package/dist/shared/utils/logger.d.ts +163 -0
- package/dist/shared/utils/logger.d.ts.map +1 -0
- package/dist/shared/utils/logger.js +389 -0
- package/dist/shared/utils/logger.js.map +1 -0
- package/package.json +53 -34
- package/prompts/DEPS_EFFICIENCY.md +558 -558
- package/prompts/E2E.md +491 -491
- package/prompts/EXECUTE.md +1060 -1060
- package/prompts/INTEGRATION_API.md +484 -484
- package/prompts/INTEGRATION_DB.md +425 -425
- package/prompts/PERF_API.md +433 -433
- package/prompts/PERF_DB.md +430 -430
- package/prompts/PERF_FRONT.md +357 -357
- package/prompts/REMEDIATION.md +482 -482
- package/prompts/UNIT.md +260 -260
- package/templates/README.md +38 -38
- package/templates/k6/load-test.js +54 -54
- package/templates/playwright/e2e.spec.ts +61 -61
- package/templates/vitest/angular-component.test.ts +38 -38
- package/templates/vitest/api.test.ts +51 -51
- package/templates/vitest/component.test.ts +27 -27
- package/templates/vitest/hook.test.ts +36 -36
- package/templates/vitest/solid-component.test.ts +34 -34
- package/templates/vitest/svelte-component.test.ts +33 -33
- package/templates/vitest/vue-component.test.ts +39 -39
- package/CHANGELOG.md +0 -38
- package/agents/deps-analyzer.js +0 -366
- package/agents/detector.js +0 -570
- package/agents/fix-engine.js +0 -305
- package/agents/lighthouse-scanner.js +0 -405
- package/agents/perf-analyzer.js +0 -294
- package/agents/perf-front-analyzer.js +0 -229
- package/agents/test-generator.js +0 -387
- package/agents/test-runner.js +0 -318
- package/bin/cli.js +0 -449
- package/lib/config.js +0 -250
- package/lib/docker.js +0 -207
- package/lib/reporter.js +0 -297
- package/scripts/dev.js +0 -106
package/prompts/UNIT.md
CHANGED
|
@@ -1,260 +1,260 @@
|
|
|
1
|
-
# Unit Test Generation Guide
|
|
2
|
-
|
|
3
|
-
This prompt is included by EXECUTE.md. It provides detailed guidance for generating unit tests.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Component Test Patterns
|
|
8
|
-
|
|
9
|
-
### Presentational Components
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
// Button component test
|
|
13
|
-
describe('Button', () => {
|
|
14
|
-
it('should render with default props', () => {
|
|
15
|
-
render(<Button>Click me</Button>);
|
|
16
|
-
expect(screen.getByRole('button')).toHaveTextContent('Click me');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should apply variant classes', () => {
|
|
20
|
-
render(<Button variant="danger">Delete</Button>);
|
|
21
|
-
expect(screen.getByRole('button')).toHaveClass('btn-danger');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should be disabled when loading', () => {
|
|
25
|
-
render(<Button loading>Submit</Button>);
|
|
26
|
-
expect(screen.getByRole('button')).toBeDisabled();
|
|
27
|
-
expect(screen.getByTestId('spinner')).toBeInTheDocument();
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Container Components
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
// UserList component test
|
|
36
|
-
describe('UserList', () => {
|
|
37
|
-
it('should show loading state', () => {
|
|
38
|
-
vi.mocked(useUsers).mockReturnValue({ data: null, loading: true });
|
|
39
|
-
render(<UserList />);
|
|
40
|
-
expect(screen.getByTestId('skeleton')).toBeInTheDocument();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should show error state', () => {
|
|
44
|
-
vi.mocked(useUsers).mockReturnValue({
|
|
45
|
-
data: null,
|
|
46
|
-
loading: false,
|
|
47
|
-
error: new Error('Failed to fetch')
|
|
48
|
-
});
|
|
49
|
-
render(<UserList />);
|
|
50
|
-
expect(screen.getByText('Failed to fetch')).toBeInTheDocument();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should render users', () => {
|
|
54
|
-
vi.mocked(useUsers).mockReturnValue({
|
|
55
|
-
data: [{ id: '1', name: 'John' }],
|
|
56
|
-
loading: false,
|
|
57
|
-
error: null
|
|
58
|
-
});
|
|
59
|
-
render(<UserList />);
|
|
60
|
-
expect(screen.getByText('John')).toBeInTheDocument();
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Hook Test Patterns
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
import { renderHook, act, waitFor } from '@testing-library/react';
|
|
71
|
-
|
|
72
|
-
describe('useDebounce', () => {
|
|
73
|
-
vi.useFakeTimers();
|
|
74
|
-
|
|
75
|
-
it('should debounce value changes', async () => {
|
|
76
|
-
const { result } = renderHook(() => useDebounce('test', 500));
|
|
77
|
-
|
|
78
|
-
// Immediate value
|
|
79
|
-
expect(result.current).toBe('test');
|
|
80
|
-
|
|
81
|
-
// Change value immediately
|
|
82
|
-
act(() => {
|
|
83
|
-
result.current.setValue('test2');
|
|
84
|
-
});
|
|
85
|
-
expect(result.current.value).toBe('test'); // Not debounced yet
|
|
86
|
-
|
|
87
|
-
// Fast-forward
|
|
88
|
-
act(() => {
|
|
89
|
-
vi.advanceTimersByTime(500);
|
|
90
|
-
});
|
|
91
|
-
expect(result.current.value).toBe('test2');
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Utility Function Patterns
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
describe('formatCurrency', () => {
|
|
102
|
-
it('should format positive numbers', () => {
|
|
103
|
-
expect(formatCurrency(1234.56)).toBe('$1,234.56');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should format zero', () => {
|
|
107
|
-
expect(formatCurrency(0)).toBe('$0.00');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should handle negative numbers', () => {
|
|
111
|
-
expect(formatCurrency(-100)).toBe('-$100.00');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should round to 2 decimal places', () => {
|
|
115
|
-
expect(formatCurrency(1.999)).toBe('$2.00');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Validator Test Patterns (Zod)
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
import { z } from 'zod';
|
|
126
|
-
import { userSchema } from './schema';
|
|
127
|
-
|
|
128
|
-
describe('userSchema', () => {
|
|
129
|
-
const validData = {
|
|
130
|
-
email: 'test@example.com',
|
|
131
|
-
age: 25,
|
|
132
|
-
name: 'John Doe'
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
it('should accept valid data', () => {
|
|
136
|
-
expect(() => userSchema.parse(validData)).not.toThrow();
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should reject invalid email', () => {
|
|
140
|
-
expect(() =>
|
|
141
|
-
userSchema.parse({ ...validData, email: 'invalid' })
|
|
142
|
-
).toThrow(z.ZodError);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should reject negative age', () => {
|
|
146
|
-
expect(() =>
|
|
147
|
-
userSchema.parse({ ...validData, age: -1 })
|
|
148
|
-
).toThrow(z.ZodError);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('should reject missing required fields', () => {
|
|
152
|
-
expect(() => userSchema.parse({})).toThrow(z.ZodError);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## Store Test Patterns (Zustand)
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import { create } from 'zustand';
|
|
163
|
-
import { useAuthStore } from './authStore';
|
|
164
|
-
|
|
165
|
-
describe('useAuthStore', () => {
|
|
166
|
-
beforeEach(() => {
|
|
167
|
-
useAuthStore.getState().reset();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should set user on login', () => {
|
|
171
|
-
const user = { id: '1', name: 'John' };
|
|
172
|
-
useAuthStore.getState().login(user);
|
|
173
|
-
expect(useAuthStore.getState().user).toEqual(user);
|
|
174
|
-
expect(useAuthStore.getState().isAuthenticated).toBe(true);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('should clear user on logout', () => {
|
|
178
|
-
useAuthStore.getState().login({ id: '1', name: 'John' });
|
|
179
|
-
useAuthStore.getState().logout();
|
|
180
|
-
expect(useAuthStore.getState().user).toBeNull();
|
|
181
|
-
expect(useAuthStore.getState().isAuthenticated).toBe(false);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## Mock Patterns
|
|
189
|
-
|
|
190
|
-
### Mocking React Query
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
194
|
-
|
|
195
|
-
function createTestQueryClient() {
|
|
196
|
-
return new QueryClient({
|
|
197
|
-
defaultOptions: {
|
|
198
|
-
queries: { retry: false },
|
|
199
|
-
mutations: { retry: false }
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function Wrapper({ children }) {
|
|
205
|
-
return (
|
|
206
|
-
<QueryClientProvider client={createTestQueryClient()}>
|
|
207
|
-
{children}
|
|
208
|
-
</QueryClientProvider>
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
describe('MyComponent', () => {
|
|
213
|
-
it('should work with React Query', () => {
|
|
214
|
-
render(<MyComponent />, { wrapper: Wrapper });
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Mocking Next.js Router
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
import { useRouter } from 'next/navigation';
|
|
223
|
-
|
|
224
|
-
vi.mock('next/navigation', () => ({
|
|
225
|
-
useRouter: () => ({
|
|
226
|
-
push: vi.fn(),
|
|
227
|
-
replace: vi.fn(),
|
|
228
|
-
prefetch: vi.fn(),
|
|
229
|
-
back: vi.fn(),
|
|
230
|
-
pathname: '/test'
|
|
231
|
-
}),
|
|
232
|
-
useSearchParams: () => new URLSearchParams('foo=bar'),
|
|
233
|
-
usePathname: () => '/test'
|
|
234
|
-
}));
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Mocking Fetch
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
global.fetch = vi.fn(() =>
|
|
241
|
-
Promise.resolve({
|
|
242
|
-
ok: true,
|
|
243
|
-
json: () => Promise.resolve({ data: 'test' })
|
|
244
|
-
})
|
|
245
|
-
) as ReturnType<typeof vi.fn>;
|
|
246
|
-
|
|
247
|
-
// Or use MSW for more complex scenarios
|
|
248
|
-
import { http, HttpResponse } from 'msw';
|
|
249
|
-
import { setupServer } from 'msw/node';
|
|
250
|
-
|
|
251
|
-
const server = setupServer(
|
|
252
|
-
http.get('/api/users', () => {
|
|
253
|
-
return HttpResponse.json({ users: [] });
|
|
254
|
-
})
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
beforeAll(() => server.listen());
|
|
258
|
-
afterEach(() => server.resetHandlers());
|
|
259
|
-
afterAll(() => server.close());
|
|
260
|
-
```
|
|
1
|
+
# Unit Test Generation Guide
|
|
2
|
+
|
|
3
|
+
This prompt is included by EXECUTE.md. It provides detailed guidance for generating unit tests.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Component Test Patterns
|
|
8
|
+
|
|
9
|
+
### Presentational Components
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// Button component test
|
|
13
|
+
describe('Button', () => {
|
|
14
|
+
it('should render with default props', () => {
|
|
15
|
+
render(<Button>Click me</Button>);
|
|
16
|
+
expect(screen.getByRole('button')).toHaveTextContent('Click me');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should apply variant classes', () => {
|
|
20
|
+
render(<Button variant="danger">Delete</Button>);
|
|
21
|
+
expect(screen.getByRole('button')).toHaveClass('btn-danger');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should be disabled when loading', () => {
|
|
25
|
+
render(<Button loading>Submit</Button>);
|
|
26
|
+
expect(screen.getByRole('button')).toBeDisabled();
|
|
27
|
+
expect(screen.getByTestId('spinner')).toBeInTheDocument();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Container Components
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// UserList component test
|
|
36
|
+
describe('UserList', () => {
|
|
37
|
+
it('should show loading state', () => {
|
|
38
|
+
vi.mocked(useUsers).mockReturnValue({ data: null, loading: true });
|
|
39
|
+
render(<UserList />);
|
|
40
|
+
expect(screen.getByTestId('skeleton')).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should show error state', () => {
|
|
44
|
+
vi.mocked(useUsers).mockReturnValue({
|
|
45
|
+
data: null,
|
|
46
|
+
loading: false,
|
|
47
|
+
error: new Error('Failed to fetch')
|
|
48
|
+
});
|
|
49
|
+
render(<UserList />);
|
|
50
|
+
expect(screen.getByText('Failed to fetch')).toBeInTheDocument();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should render users', () => {
|
|
54
|
+
vi.mocked(useUsers).mockReturnValue({
|
|
55
|
+
data: [{ id: '1', name: 'John' }],
|
|
56
|
+
loading: false,
|
|
57
|
+
error: null
|
|
58
|
+
});
|
|
59
|
+
render(<UserList />);
|
|
60
|
+
expect(screen.getByText('John')).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Hook Test Patterns
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { renderHook, act, waitFor } from '@testing-library/react';
|
|
71
|
+
|
|
72
|
+
describe('useDebounce', () => {
|
|
73
|
+
vi.useFakeTimers();
|
|
74
|
+
|
|
75
|
+
it('should debounce value changes', async () => {
|
|
76
|
+
const { result } = renderHook(() => useDebounce('test', 500));
|
|
77
|
+
|
|
78
|
+
// Immediate value
|
|
79
|
+
expect(result.current).toBe('test');
|
|
80
|
+
|
|
81
|
+
// Change value immediately
|
|
82
|
+
act(() => {
|
|
83
|
+
result.current.setValue('test2');
|
|
84
|
+
});
|
|
85
|
+
expect(result.current.value).toBe('test'); // Not debounced yet
|
|
86
|
+
|
|
87
|
+
// Fast-forward
|
|
88
|
+
act(() => {
|
|
89
|
+
vi.advanceTimersByTime(500);
|
|
90
|
+
});
|
|
91
|
+
expect(result.current.value).toBe('test2');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Utility Function Patterns
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
describe('formatCurrency', () => {
|
|
102
|
+
it('should format positive numbers', () => {
|
|
103
|
+
expect(formatCurrency(1234.56)).toBe('$1,234.56');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should format zero', () => {
|
|
107
|
+
expect(formatCurrency(0)).toBe('$0.00');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should handle negative numbers', () => {
|
|
111
|
+
expect(formatCurrency(-100)).toBe('-$100.00');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should round to 2 decimal places', () => {
|
|
115
|
+
expect(formatCurrency(1.999)).toBe('$2.00');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Validator Test Patterns (Zod)
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { z } from 'zod';
|
|
126
|
+
import { userSchema } from './schema';
|
|
127
|
+
|
|
128
|
+
describe('userSchema', () => {
|
|
129
|
+
const validData = {
|
|
130
|
+
email: 'test@example.com',
|
|
131
|
+
age: 25,
|
|
132
|
+
name: 'John Doe'
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
it('should accept valid data', () => {
|
|
136
|
+
expect(() => userSchema.parse(validData)).not.toThrow();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should reject invalid email', () => {
|
|
140
|
+
expect(() =>
|
|
141
|
+
userSchema.parse({ ...validData, email: 'invalid' })
|
|
142
|
+
).toThrow(z.ZodError);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should reject negative age', () => {
|
|
146
|
+
expect(() =>
|
|
147
|
+
userSchema.parse({ ...validData, age: -1 })
|
|
148
|
+
).toThrow(z.ZodError);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should reject missing required fields', () => {
|
|
152
|
+
expect(() => userSchema.parse({})).toThrow(z.ZodError);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Store Test Patterns (Zustand)
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { create } from 'zustand';
|
|
163
|
+
import { useAuthStore } from './authStore';
|
|
164
|
+
|
|
165
|
+
describe('useAuthStore', () => {
|
|
166
|
+
beforeEach(() => {
|
|
167
|
+
useAuthStore.getState().reset();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('should set user on login', () => {
|
|
171
|
+
const user = { id: '1', name: 'John' };
|
|
172
|
+
useAuthStore.getState().login(user);
|
|
173
|
+
expect(useAuthStore.getState().user).toEqual(user);
|
|
174
|
+
expect(useAuthStore.getState().isAuthenticated).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should clear user on logout', () => {
|
|
178
|
+
useAuthStore.getState().login({ id: '1', name: 'John' });
|
|
179
|
+
useAuthStore.getState().logout();
|
|
180
|
+
expect(useAuthStore.getState().user).toBeNull();
|
|
181
|
+
expect(useAuthStore.getState().isAuthenticated).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Mock Patterns
|
|
189
|
+
|
|
190
|
+
### Mocking React Query
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
194
|
+
|
|
195
|
+
function createTestQueryClient() {
|
|
196
|
+
return new QueryClient({
|
|
197
|
+
defaultOptions: {
|
|
198
|
+
queries: { retry: false },
|
|
199
|
+
mutations: { retry: false }
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function Wrapper({ children }) {
|
|
205
|
+
return (
|
|
206
|
+
<QueryClientProvider client={createTestQueryClient()}>
|
|
207
|
+
{children}
|
|
208
|
+
</QueryClientProvider>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
describe('MyComponent', () => {
|
|
213
|
+
it('should work with React Query', () => {
|
|
214
|
+
render(<MyComponent />, { wrapper: Wrapper });
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Mocking Next.js Router
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { useRouter } from 'next/navigation';
|
|
223
|
+
|
|
224
|
+
vi.mock('next/navigation', () => ({
|
|
225
|
+
useRouter: () => ({
|
|
226
|
+
push: vi.fn(),
|
|
227
|
+
replace: vi.fn(),
|
|
228
|
+
prefetch: vi.fn(),
|
|
229
|
+
back: vi.fn(),
|
|
230
|
+
pathname: '/test'
|
|
231
|
+
}),
|
|
232
|
+
useSearchParams: () => new URLSearchParams('foo=bar'),
|
|
233
|
+
usePathname: () => '/test'
|
|
234
|
+
}));
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Mocking Fetch
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
global.fetch = vi.fn(() =>
|
|
241
|
+
Promise.resolve({
|
|
242
|
+
ok: true,
|
|
243
|
+
json: () => Promise.resolve({ data: 'test' })
|
|
244
|
+
})
|
|
245
|
+
) as ReturnType<typeof vi.fn>;
|
|
246
|
+
|
|
247
|
+
// Or use MSW for more complex scenarios
|
|
248
|
+
import { http, HttpResponse } from 'msw';
|
|
249
|
+
import { setupServer } from 'msw/node';
|
|
250
|
+
|
|
251
|
+
const server = setupServer(
|
|
252
|
+
http.get('/api/users', () => {
|
|
253
|
+
return HttpResponse.json({ users: [] });
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
beforeAll(() => server.listen());
|
|
258
|
+
afterEach(() => server.resetHandlers());
|
|
259
|
+
afterAll(() => server.close());
|
|
260
|
+
```
|
package/templates/README.md
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
# Daemon Templates
|
|
2
|
-
|
|
3
|
-
This directory contains test templates for different frameworks and tools.
|
|
4
|
-
|
|
5
|
-
## Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
templates/
|
|
9
|
-
├── vitest/ # Vitest test templates
|
|
10
|
-
│ ├── component.test.ts # React component template
|
|
11
|
-
│ ├── vue-component.test.ts # Vue component template
|
|
12
|
-
│ ├── solid-component.test.ts # Solid component template
|
|
13
|
-
│ ├── svelte-component.test.ts # Svelte component template
|
|
14
|
-
│ ├── angular-component.test.ts # Angular component template
|
|
15
|
-
│ ├── hook.test.ts # React hooks template
|
|
16
|
-
│ └── api.test.ts # API route template
|
|
17
|
-
├── playwright/ # Playwright E2E templates
|
|
18
|
-
│ ├── auth.spec.ts
|
|
19
|
-
│ └── crud.spec.ts
|
|
20
|
-
├── k6/ # k6 backend performance templates
|
|
21
|
-
│ └── load-test.js
|
|
22
|
-
└── lighthouse/ # Lighthouse frontend performance (via CLI)
|
|
23
|
-
└── (run directly with npx lighthouse)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Framework Support
|
|
27
|
-
|
|
28
|
-
| Framework | Template | Testing Library |
|
|
29
|
-
|-----------|----------|-----------------|
|
|
30
|
-
| React | `component.test.ts` | `@testing-library/react` |
|
|
31
|
-
| Vue | `vue-component.test.ts` | `@vue/test-utils` |
|
|
32
|
-
| Solid | `solid-component.test.ts` | `@solidjs/testing-library` |
|
|
33
|
-
| Svelte | `svelte-component.test.ts` | `@testing-library/svelte` |
|
|
34
|
-
| Angular | `angular-component.test.ts` | `@angular/core/testing` |
|
|
35
|
-
|
|
36
|
-
## Usage
|
|
37
|
-
|
|
38
|
-
Templates are used by the test generator agent to create new test files based on the detected framework and patterns.
|
|
1
|
+
# Daemon Templates
|
|
2
|
+
|
|
3
|
+
This directory contains test templates for different frameworks and tools.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
templates/
|
|
9
|
+
├── vitest/ # Vitest test templates
|
|
10
|
+
│ ├── component.test.ts # React component template
|
|
11
|
+
│ ├── vue-component.test.ts # Vue component template
|
|
12
|
+
│ ├── solid-component.test.ts # Solid component template
|
|
13
|
+
│ ├── svelte-component.test.ts # Svelte component template
|
|
14
|
+
│ ├── angular-component.test.ts # Angular component template
|
|
15
|
+
│ ├── hook.test.ts # React hooks template
|
|
16
|
+
│ └── api.test.ts # API route template
|
|
17
|
+
├── playwright/ # Playwright E2E templates
|
|
18
|
+
│ ├── auth.spec.ts
|
|
19
|
+
│ └── crud.spec.ts
|
|
20
|
+
├── k6/ # k6 backend performance templates
|
|
21
|
+
│ └── load-test.js
|
|
22
|
+
└── lighthouse/ # Lighthouse frontend performance (via CLI)
|
|
23
|
+
└── (run directly with npx lighthouse)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Framework Support
|
|
27
|
+
|
|
28
|
+
| Framework | Template | Testing Library |
|
|
29
|
+
|-----------|----------|-----------------|
|
|
30
|
+
| React | `component.test.ts` | `@testing-library/react` |
|
|
31
|
+
| Vue | `vue-component.test.ts` | `@vue/test-utils` |
|
|
32
|
+
| Solid | `solid-component.test.ts` | `@solidjs/testing-library` |
|
|
33
|
+
| Svelte | `svelte-component.test.ts` | `@testing-library/svelte` |
|
|
34
|
+
| Angular | `angular-component.test.ts` | `@angular/core/testing` |
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Templates are used by the test generator agent to create new test files based on the detected framework and patterns.
|