@claudetree/core 0.4.4 → 0.4.5
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/dist/infra/ai/AIReviewGenerator.test.d.ts +2 -0
- package/dist/infra/ai/AIReviewGenerator.test.d.ts.map +1 -0
- package/dist/infra/ai/AIReviewGenerator.test.js +231 -0
- package/dist/infra/ai/AIReviewGenerator.test.js.map +1 -0
- package/dist/infra/ci/ci-workflow.test.d.ts +2 -0
- package/dist/infra/ci/ci-workflow.test.d.ts.map +1 -0
- package/dist/infra/ci/ci-workflow.test.js +98 -0
- package/dist/infra/ci/ci-workflow.test.js.map +1 -0
- package/dist/infra/logger/Logger.test.d.ts +2 -0
- package/dist/infra/logger/Logger.test.d.ts.map +1 -0
- package/dist/infra/logger/Logger.test.js +55 -0
- package/dist/infra/logger/Logger.test.js.map +1 -0
- package/dist/infra/validation/ValidationGateRunner.test.d.ts +2 -0
- package/dist/infra/validation/ValidationGateRunner.test.d.ts.map +1 -0
- package/dist/infra/validation/ValidationGateRunner.test.js +279 -0
- package/dist/infra/validation/ValidationGateRunner.test.js.map +1 -0
- package/package.json +10 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIReviewGenerator.test.d.ts","sourceRoot":"","sources":["../../../src/infra/ai/AIReviewGenerator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { generateAIReviewSummary } from './AIReviewGenerator.js';
|
|
3
|
+
import * as childProcess from 'node:child_process';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
// Mock child_process.spawn
|
|
6
|
+
vi.mock('node:child_process', () => ({
|
|
7
|
+
spawn: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
describe('AIReviewGenerator', () => {
|
|
10
|
+
let spawnMock;
|
|
11
|
+
const createMockProcess = (stdout, stderr, exitCode, options) => {
|
|
12
|
+
const stdoutEmitter = new EventEmitter();
|
|
13
|
+
const stderrEmitter = new EventEmitter();
|
|
14
|
+
const proc = new EventEmitter();
|
|
15
|
+
// Cast to unknown first, then to the required type
|
|
16
|
+
proc.stdout = stdoutEmitter;
|
|
17
|
+
proc.stderr = stderrEmitter;
|
|
18
|
+
proc.kill = vi.fn();
|
|
19
|
+
// Schedule data and close events
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
if (options?.shouldError) {
|
|
22
|
+
proc.emit('error', new Error(options.errorMessage || 'Process error'));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
stdoutEmitter.emit('data', Buffer.from(stdout));
|
|
26
|
+
stderrEmitter.emit('data', Buffer.from(stderr));
|
|
27
|
+
proc.emit('close', exitCode);
|
|
28
|
+
}
|
|
29
|
+
}, 0);
|
|
30
|
+
return proc;
|
|
31
|
+
};
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
spawnMock = vi.mocked(childProcess.spawn);
|
|
34
|
+
spawnMock.mockReset();
|
|
35
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
36
|
+
});
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
vi.clearAllMocks();
|
|
39
|
+
vi.restoreAllMocks();
|
|
40
|
+
});
|
|
41
|
+
describe('generateAIReviewSummary', () => {
|
|
42
|
+
const baseOptions = {
|
|
43
|
+
sessionId: 'test-session-123',
|
|
44
|
+
workingDir: '/test/project',
|
|
45
|
+
baseBranch: 'main',
|
|
46
|
+
};
|
|
47
|
+
it('should return null when there are no changes', async () => {
|
|
48
|
+
// First call: git diff --stat returns empty
|
|
49
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('', '', 0));
|
|
50
|
+
// Second call: git diff (detailed) - should not be reached if first is empty
|
|
51
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('', '', 0));
|
|
52
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
53
|
+
expect(result).toBeNull();
|
|
54
|
+
});
|
|
55
|
+
it('should generate review summary successfully', async () => {
|
|
56
|
+
const diffStat = ' src/test.ts | 10 +++++-----\n 1 file changed';
|
|
57
|
+
const detailedDiff = 'diff --git a/src/test.ts\n+added line\n-removed line';
|
|
58
|
+
const claudeResponse = JSON.stringify({
|
|
59
|
+
summary: 'Added new feature',
|
|
60
|
+
whatChanged: ['Added test file'],
|
|
61
|
+
whyChanged: 'To improve coverage',
|
|
62
|
+
potentialIssues: [],
|
|
63
|
+
suggestions: ['Add more tests'],
|
|
64
|
+
riskLevel: 'low',
|
|
65
|
+
});
|
|
66
|
+
// git diff --stat
|
|
67
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(diffStat, '', 0));
|
|
68
|
+
// git diff (detailed)
|
|
69
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(detailedDiff, '', 0));
|
|
70
|
+
// claude CLI
|
|
71
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(claudeResponse, '', 0));
|
|
72
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
73
|
+
expect(result).not.toBeNull();
|
|
74
|
+
expect(result?.sessionId).toBe('test-session-123');
|
|
75
|
+
expect(result?.summary).toBe('Added new feature');
|
|
76
|
+
expect(result?.whatChanged).toContain('Added test file');
|
|
77
|
+
expect(result?.whyChanged).toBe('To improve coverage');
|
|
78
|
+
expect(result?.suggestions).toContain('Add more tests');
|
|
79
|
+
expect(result?.riskLevel).toBe('low');
|
|
80
|
+
expect(result?.generatedAt).toBeInstanceOf(Date);
|
|
81
|
+
});
|
|
82
|
+
it('should use develop as default base branch', async () => {
|
|
83
|
+
const optionsWithoutBranch = {
|
|
84
|
+
sessionId: 'test-session',
|
|
85
|
+
workingDir: '/test',
|
|
86
|
+
};
|
|
87
|
+
spawnMock.mockImplementation((cmd, args) => {
|
|
88
|
+
if (cmd === 'git' && args.includes('diff')) {
|
|
89
|
+
// Check that develop is used
|
|
90
|
+
expect(args).toContain('develop');
|
|
91
|
+
}
|
|
92
|
+
return createMockProcess('', '', 0);
|
|
93
|
+
});
|
|
94
|
+
await generateAIReviewSummary(optionsWithoutBranch);
|
|
95
|
+
expect(spawnMock).toHaveBeenCalledWith('git', expect.arrayContaining(['develop']), expect.any(Object));
|
|
96
|
+
});
|
|
97
|
+
it('should handle git command failure', async () => {
|
|
98
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('', 'fatal: not a git repository', 1));
|
|
99
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
100
|
+
expect(result).toBeNull();
|
|
101
|
+
});
|
|
102
|
+
it('should handle claude CLI failure', async () => {
|
|
103
|
+
// git diff --stat
|
|
104
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
105
|
+
// git diff detailed
|
|
106
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('+line', '', 0));
|
|
107
|
+
// claude CLI fails
|
|
108
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('', 'API error', 1));
|
|
109
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
110
|
+
expect(result).toBeNull();
|
|
111
|
+
});
|
|
112
|
+
it('should handle invalid JSON response from Claude', async () => {
|
|
113
|
+
// git diff --stat
|
|
114
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
115
|
+
// git diff detailed
|
|
116
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('+line', '', 0));
|
|
117
|
+
// claude returns invalid JSON
|
|
118
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('This is not JSON', '', 0));
|
|
119
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
120
|
+
expect(result).toBeNull();
|
|
121
|
+
});
|
|
122
|
+
it('should extract JSON from Claude response with extra text', async () => {
|
|
123
|
+
// git diff --stat
|
|
124
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
125
|
+
// git diff detailed
|
|
126
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('+line', '', 0));
|
|
127
|
+
// claude returns JSON with surrounding text
|
|
128
|
+
const responseWithExtra = `Here's my analysis:
|
|
129
|
+
${JSON.stringify({
|
|
130
|
+
summary: 'Test summary',
|
|
131
|
+
whatChanged: ['change 1'],
|
|
132
|
+
whyChanged: 'reason',
|
|
133
|
+
potentialIssues: [],
|
|
134
|
+
suggestions: [],
|
|
135
|
+
riskLevel: 'low',
|
|
136
|
+
})}
|
|
137
|
+
Let me know if you need more details.`;
|
|
138
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(responseWithExtra, '', 0));
|
|
139
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
140
|
+
expect(result).not.toBeNull();
|
|
141
|
+
expect(result?.summary).toBe('Test summary');
|
|
142
|
+
});
|
|
143
|
+
it('should handle missing fields in Claude response with defaults', async () => {
|
|
144
|
+
// git diff --stat
|
|
145
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
146
|
+
// git diff detailed
|
|
147
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('+line', '', 0));
|
|
148
|
+
// claude returns partial JSON
|
|
149
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('{}', '', 0));
|
|
150
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
151
|
+
expect(result).not.toBeNull();
|
|
152
|
+
expect(result?.summary).toBe('No summary available');
|
|
153
|
+
expect(result?.whatChanged).toEqual([]);
|
|
154
|
+
expect(result?.whyChanged).toBe('Unknown');
|
|
155
|
+
expect(result?.potentialIssues).toEqual([]);
|
|
156
|
+
expect(result?.suggestions).toEqual([]);
|
|
157
|
+
expect(result?.riskLevel).toBe('low');
|
|
158
|
+
});
|
|
159
|
+
it('should parse potential issues correctly', async () => {
|
|
160
|
+
// git diff --stat
|
|
161
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
162
|
+
// git diff detailed
|
|
163
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('+line', '', 0));
|
|
164
|
+
// claude returns response with issues
|
|
165
|
+
const responseWithIssues = JSON.stringify({
|
|
166
|
+
summary: 'Test',
|
|
167
|
+
whatChanged: [],
|
|
168
|
+
whyChanged: 'test',
|
|
169
|
+
potentialIssues: [
|
|
170
|
+
{
|
|
171
|
+
severity: 'warning',
|
|
172
|
+
title: 'Security issue',
|
|
173
|
+
description: 'Potential XSS vulnerability',
|
|
174
|
+
file: 'src/component.tsx',
|
|
175
|
+
line: 42,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
severity: 'info',
|
|
179
|
+
title: 'Style suggestion',
|
|
180
|
+
description: 'Consider using const',
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
suggestions: [],
|
|
184
|
+
riskLevel: 'medium',
|
|
185
|
+
});
|
|
186
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(responseWithIssues, '', 0));
|
|
187
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
188
|
+
expect(result?.potentialIssues).toHaveLength(2);
|
|
189
|
+
expect(result?.potentialIssues[0]).toEqual({
|
|
190
|
+
severity: 'warning',
|
|
191
|
+
title: 'Security issue',
|
|
192
|
+
description: 'Potential XSS vulnerability',
|
|
193
|
+
file: 'src/component.tsx',
|
|
194
|
+
line: 42,
|
|
195
|
+
});
|
|
196
|
+
expect(result?.potentialIssues[1]?.file).toBeUndefined();
|
|
197
|
+
});
|
|
198
|
+
it('should handle process spawn error', async () => {
|
|
199
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('', '', 0, { shouldError: true, errorMessage: 'spawn failed' }));
|
|
200
|
+
const result = await generateAIReviewSummary(baseOptions);
|
|
201
|
+
expect(result).toBeNull();
|
|
202
|
+
});
|
|
203
|
+
it('should truncate very long diffs in prompt', async () => {
|
|
204
|
+
const longDiff = 'A'.repeat(20000); // Longer than maxDiffLength (15000)
|
|
205
|
+
// git diff --stat
|
|
206
|
+
spawnMock.mockImplementationOnce(() => createMockProcess('file.ts | 5 +++++', '', 0));
|
|
207
|
+
// git diff detailed - very long
|
|
208
|
+
spawnMock.mockImplementationOnce(() => createMockProcess(longDiff, '', 0));
|
|
209
|
+
// claude CLI
|
|
210
|
+
spawnMock.mockImplementationOnce((cmd, args) => {
|
|
211
|
+
// Verify the prompt contains truncation marker
|
|
212
|
+
if (cmd === 'claude') {
|
|
213
|
+
const prompt = args[1]; // -p <prompt>
|
|
214
|
+
expect(prompt).toContain('... (truncated)');
|
|
215
|
+
}
|
|
216
|
+
return createMockProcess(JSON.stringify({
|
|
217
|
+
summary: 'test',
|
|
218
|
+
whatChanged: [],
|
|
219
|
+
whyChanged: 'test',
|
|
220
|
+
potentialIssues: [],
|
|
221
|
+
suggestions: [],
|
|
222
|
+
riskLevel: 'low',
|
|
223
|
+
}), '', 0);
|
|
224
|
+
});
|
|
225
|
+
await generateAIReviewSummary(baseOptions);
|
|
226
|
+
// The test passes if no errors and the mock verifications pass
|
|
227
|
+
expect(spawnMock).toHaveBeenCalledTimes(3);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=AIReviewGenerator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIReviewGenerator.test.js","sourceRoot":"","sources":["../../../src/infra/ai/AIReviewGenerator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-workflow.test.d.ts","sourceRoot":"","sources":["../../../src/infra/ci/ci-workflow.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { parse } from 'yaml';
|
|
6
|
+
describe('CI Workflow Configuration', () => {
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
// Navigate from packages/core/src/infra/ci to root
|
|
10
|
+
const rootDir = join(__dirname, '..', '..', '..', '..', '..');
|
|
11
|
+
const workflowPath = join(rootDir, '.github', 'workflows', 'ci.yml');
|
|
12
|
+
async function loadWorkflow() {
|
|
13
|
+
const content = await readFile(workflowPath, 'utf-8');
|
|
14
|
+
return parse(content);
|
|
15
|
+
}
|
|
16
|
+
describe('triggers', () => {
|
|
17
|
+
it('should trigger on push to main and develop branches', async () => {
|
|
18
|
+
const workflow = await loadWorkflow();
|
|
19
|
+
expect(workflow.on.push?.branches).toContain('main');
|
|
20
|
+
expect(workflow.on.push?.branches).toContain('develop');
|
|
21
|
+
});
|
|
22
|
+
it('should trigger on pull_request to main and develop branches', async () => {
|
|
23
|
+
const workflow = await loadWorkflow();
|
|
24
|
+
expect(workflow.on.pull_request?.branches).toContain('main');
|
|
25
|
+
expect(workflow.on.pull_request?.branches).toContain('develop');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe('test job', () => {
|
|
29
|
+
it('should run on ubuntu-latest', async () => {
|
|
30
|
+
const workflow = await loadWorkflow();
|
|
31
|
+
expect(workflow.jobs.test?.['runs-on']).toBe('ubuntu-latest');
|
|
32
|
+
});
|
|
33
|
+
it('should checkout code', async () => {
|
|
34
|
+
const workflow = await loadWorkflow();
|
|
35
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
36
|
+
const checkoutStep = steps.find((s) => s.uses?.startsWith('actions/checkout'));
|
|
37
|
+
expect(checkoutStep).toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
it('should setup pnpm', async () => {
|
|
40
|
+
const workflow = await loadWorkflow();
|
|
41
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
42
|
+
const pnpmStep = steps.find((s) => s.uses?.startsWith('pnpm/action-setup'));
|
|
43
|
+
expect(pnpmStep).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
it('should setup Node.js with version 22', async () => {
|
|
46
|
+
const workflow = await loadWorkflow();
|
|
47
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
48
|
+
const nodeStep = steps.find((s) => s.uses?.startsWith('actions/setup-node'));
|
|
49
|
+
expect(nodeStep).toBeDefined();
|
|
50
|
+
expect(nodeStep?.with?.['node-version']).toBe(22);
|
|
51
|
+
});
|
|
52
|
+
it('should install dependencies with frozen lockfile', async () => {
|
|
53
|
+
const workflow = await loadWorkflow();
|
|
54
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
55
|
+
const installStep = steps.find((s) => s.run?.includes('pnpm install') && s.run?.includes('--frozen-lockfile'));
|
|
56
|
+
expect(installStep).toBeDefined();
|
|
57
|
+
});
|
|
58
|
+
it('should run lint', async () => {
|
|
59
|
+
const workflow = await loadWorkflow();
|
|
60
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
61
|
+
const lintStep = steps.find((s) => s.run?.includes('pnpm lint'));
|
|
62
|
+
expect(lintStep).toBeDefined();
|
|
63
|
+
});
|
|
64
|
+
it('should run typecheck', async () => {
|
|
65
|
+
const workflow = await loadWorkflow();
|
|
66
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
67
|
+
const typecheckStep = steps.find((s) => s.run?.includes('tsc') && s.run?.includes('--noEmit'));
|
|
68
|
+
expect(typecheckStep).toBeDefined();
|
|
69
|
+
});
|
|
70
|
+
it('should build the project', async () => {
|
|
71
|
+
const workflow = await loadWorkflow();
|
|
72
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
73
|
+
const buildStep = steps.find((s) => s.run?.includes('pnpm build'));
|
|
74
|
+
expect(buildStep).toBeDefined();
|
|
75
|
+
});
|
|
76
|
+
it('should run tests', async () => {
|
|
77
|
+
const workflow = await loadWorkflow();
|
|
78
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
79
|
+
const testStep = steps.find((s) => s.run?.includes('pnpm test:run'));
|
|
80
|
+
expect(testStep).toBeDefined();
|
|
81
|
+
});
|
|
82
|
+
it('should run steps in correct order: install -> lint -> build -> typecheck -> test', async () => {
|
|
83
|
+
const workflow = await loadWorkflow();
|
|
84
|
+
const steps = workflow.jobs.test?.steps ?? [];
|
|
85
|
+
const installIndex = steps.findIndex((s) => s.run?.includes('pnpm install'));
|
|
86
|
+
const lintIndex = steps.findIndex((s) => s.run?.includes('pnpm lint'));
|
|
87
|
+
const buildIndex = steps.findIndex((s) => s.run?.includes('pnpm build'));
|
|
88
|
+
const typecheckIndex = steps.findIndex((s) => s.run?.includes('tsc'));
|
|
89
|
+
const testIndex = steps.findIndex((s) => s.run?.includes('pnpm test:run'));
|
|
90
|
+
// Build must come before typecheck so @claudetree/shared types are available
|
|
91
|
+
expect(installIndex).toBeLessThan(lintIndex);
|
|
92
|
+
expect(lintIndex).toBeLessThan(buildIndex);
|
|
93
|
+
expect(buildIndex).toBeLessThan(typecheckIndex);
|
|
94
|
+
expect(typecheckIndex).toBeLessThan(testIndex);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=ci-workflow.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-workflow.test.js","sourceRoot":"","sources":["../../../src/infra/ci/ci-workflow.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.test.d.ts","sourceRoot":"","sources":["../../../src/infra/logger/Logger.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { createLogger } from './Logger.js';
|
|
3
|
+
describe('Logger', () => {
|
|
4
|
+
describe('createLogger', () => {
|
|
5
|
+
it('should create logger with correct namespace', () => {
|
|
6
|
+
const logger = createLogger('test-module');
|
|
7
|
+
expect(logger).toBeDefined();
|
|
8
|
+
expect(logger.info).toBeDefined();
|
|
9
|
+
expect(logger.error).toBeDefined();
|
|
10
|
+
expect(logger.debug).toBeDefined();
|
|
11
|
+
});
|
|
12
|
+
it('should create logger with info, error, debug methods', () => {
|
|
13
|
+
const logger = createLogger('mymodule');
|
|
14
|
+
expect(typeof logger.info).toBe('function');
|
|
15
|
+
expect(typeof logger.error).toBe('function');
|
|
16
|
+
expect(typeof logger.debug).toBe('function');
|
|
17
|
+
});
|
|
18
|
+
it('should use claudetree namespace prefix', () => {
|
|
19
|
+
const logger = createLogger('session');
|
|
20
|
+
// debug module sets namespace on the function
|
|
21
|
+
expect(logger.info.namespace).toBe('claudetree:session:info');
|
|
22
|
+
expect(logger.error.namespace).toBe('claudetree:session:error');
|
|
23
|
+
expect(logger.debug.namespace).toBe('claudetree:session:debug');
|
|
24
|
+
});
|
|
25
|
+
it('should create independent loggers for different modules', () => {
|
|
26
|
+
const logger1 = createLogger('module1');
|
|
27
|
+
const logger2 = createLogger('module2');
|
|
28
|
+
expect(logger1.info.namespace).not.toBe(logger2.info.namespace);
|
|
29
|
+
expect(logger1.info.namespace).toBe('claudetree:module1:info');
|
|
30
|
+
expect(logger2.info.namespace).toBe('claudetree:module2:info');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('Logger interface', () => {
|
|
34
|
+
let logger;
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
logger = createLogger('test');
|
|
37
|
+
});
|
|
38
|
+
it('should have info method that is callable', () => {
|
|
39
|
+
// Should not throw
|
|
40
|
+
expect(() => logger.info('test message')).not.toThrow();
|
|
41
|
+
});
|
|
42
|
+
it('should have error method that is callable', () => {
|
|
43
|
+
expect(() => logger.error('error message')).not.toThrow();
|
|
44
|
+
});
|
|
45
|
+
it('should have debug method that is callable', () => {
|
|
46
|
+
expect(() => logger.debug('debug message')).not.toThrow();
|
|
47
|
+
});
|
|
48
|
+
it('should support format strings', () => {
|
|
49
|
+
expect(() => logger.info('User %s logged in', 'john')).not.toThrow();
|
|
50
|
+
expect(() => logger.error('Error code: %d', 500)).not.toThrow();
|
|
51
|
+
expect(() => logger.debug('Object: %O', { key: 'value' })).not.toThrow();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=Logger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.test.js","sourceRoot":"","sources":["../../../src/infra/logger/Logger.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationGateRunner.test.d.ts","sourceRoot":"","sources":["../../../src/infra/validation/ValidationGateRunner.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { ValidationGateRunner, DEFAULT_GATES, detectProjectGates, } from './ValidationGateRunner.js';
|
|
3
|
+
import * as childProcess from 'node:child_process';
|
|
4
|
+
vi.mock('node:child_process', () => ({
|
|
5
|
+
exec: vi.fn(),
|
|
6
|
+
}));
|
|
7
|
+
vi.mock('../logger/index.js', () => ({
|
|
8
|
+
createLogger: () => ({
|
|
9
|
+
info: vi.fn(),
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
debug: vi.fn(),
|
|
12
|
+
}),
|
|
13
|
+
}));
|
|
14
|
+
describe('ValidationGateRunner', () => {
|
|
15
|
+
let runner;
|
|
16
|
+
let execMock;
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
runner = new ValidationGateRunner();
|
|
19
|
+
execMock = vi.mocked(childProcess.exec);
|
|
20
|
+
execMock.mockReset();
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
vi.clearAllMocks();
|
|
24
|
+
});
|
|
25
|
+
describe('runGate', () => {
|
|
26
|
+
const gate = {
|
|
27
|
+
name: 'test',
|
|
28
|
+
command: 'npm test',
|
|
29
|
+
required: true,
|
|
30
|
+
};
|
|
31
|
+
const options = {
|
|
32
|
+
cwd: '/test/project',
|
|
33
|
+
maxRetries: 3,
|
|
34
|
+
timeout: 10000,
|
|
35
|
+
};
|
|
36
|
+
it('should run gate successfully on first attempt', async () => {
|
|
37
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
38
|
+
if (typeof callback === 'function') {
|
|
39
|
+
callback(null, { stdout: 'All tests passed', stderr: '' });
|
|
40
|
+
}
|
|
41
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
42
|
+
});
|
|
43
|
+
const result = await runner.runGate(gate, options);
|
|
44
|
+
expect(result.gateName).toBe('test');
|
|
45
|
+
expect(result.passed).toBe(true);
|
|
46
|
+
expect(result.attempts).toBe(1);
|
|
47
|
+
expect(result.output).toContain('All tests passed');
|
|
48
|
+
expect(result.completedAt).toBeInstanceOf(Date);
|
|
49
|
+
});
|
|
50
|
+
it('should retry on failure and eventually pass', async () => {
|
|
51
|
+
let callCount = 0;
|
|
52
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
53
|
+
callCount++;
|
|
54
|
+
if (typeof callback === 'function') {
|
|
55
|
+
if (callCount < 2) {
|
|
56
|
+
callback(new Error('Test failed'), { stdout: '', stderr: 'Error' });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
callback(null, { stdout: 'Tests passed', stderr: '' });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
63
|
+
});
|
|
64
|
+
const result = await runner.runGate(gate, options);
|
|
65
|
+
expect(result.passed).toBe(true);
|
|
66
|
+
expect(result.attempts).toBe(2);
|
|
67
|
+
});
|
|
68
|
+
it('should fail after max retries exceeded', async () => {
|
|
69
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
70
|
+
if (typeof callback === 'function') {
|
|
71
|
+
callback(new Error('Test failed'), { stdout: '', stderr: 'Error output' });
|
|
72
|
+
}
|
|
73
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
74
|
+
});
|
|
75
|
+
const result = await runner.runGate(gate, options);
|
|
76
|
+
expect(result.passed).toBe(false);
|
|
77
|
+
expect(result.attempts).toBe(3);
|
|
78
|
+
});
|
|
79
|
+
it('should truncate long output', async () => {
|
|
80
|
+
const longOutput = 'A'.repeat(2000);
|
|
81
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
82
|
+
if (typeof callback === 'function') {
|
|
83
|
+
callback(null, { stdout: longOutput, stderr: '' });
|
|
84
|
+
}
|
|
85
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
86
|
+
});
|
|
87
|
+
const result = await runner.runGate(gate, options);
|
|
88
|
+
expect(result.output?.length).toBeLessThan(longOutput.length);
|
|
89
|
+
expect(result.output).toContain('... (truncated)');
|
|
90
|
+
});
|
|
91
|
+
it('should use default timeout when not specified', async () => {
|
|
92
|
+
execMock.mockImplementation((_cmd, opts, callback) => {
|
|
93
|
+
// Check that timeout is set
|
|
94
|
+
expect(opts.timeout).toBe(5 * 60 * 1000);
|
|
95
|
+
if (typeof callback === 'function') {
|
|
96
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
97
|
+
}
|
|
98
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
99
|
+
});
|
|
100
|
+
const optionsWithoutTimeout = {
|
|
101
|
+
cwd: '/test',
|
|
102
|
+
maxRetries: 1,
|
|
103
|
+
};
|
|
104
|
+
await runner.runGate(gate, optionsWithoutTimeout);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('runAll', () => {
|
|
108
|
+
const gates = [
|
|
109
|
+
{ name: 'install', command: 'npm ci', required: true },
|
|
110
|
+
{ name: 'test', command: 'npm test', required: true },
|
|
111
|
+
{ name: 'lint', command: 'npm run lint', required: false },
|
|
112
|
+
];
|
|
113
|
+
const options = {
|
|
114
|
+
cwd: '/test',
|
|
115
|
+
maxRetries: 1,
|
|
116
|
+
};
|
|
117
|
+
it('should run all gates in sequence', async () => {
|
|
118
|
+
const executionOrder = [];
|
|
119
|
+
execMock.mockImplementation((cmd, _opts, callback) => {
|
|
120
|
+
executionOrder.push(cmd);
|
|
121
|
+
if (typeof callback === 'function') {
|
|
122
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
123
|
+
}
|
|
124
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
125
|
+
});
|
|
126
|
+
const result = await runner.runAll(gates, options);
|
|
127
|
+
expect(result.results).toHaveLength(3);
|
|
128
|
+
expect(result.allPassed).toBe(true);
|
|
129
|
+
expect(result.totalTime).toBeGreaterThanOrEqual(0);
|
|
130
|
+
expect(executionOrder).toEqual(['npm ci', 'npm test', 'npm run lint']);
|
|
131
|
+
});
|
|
132
|
+
it('should stop on required gate failure', async () => {
|
|
133
|
+
execMock.mockImplementation((cmd, _opts, callback) => {
|
|
134
|
+
if (typeof callback === 'function') {
|
|
135
|
+
if (cmd === 'npm test') {
|
|
136
|
+
callback(new Error('Failed'), { stdout: '', stderr: 'Error' });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
143
|
+
});
|
|
144
|
+
const result = await runner.runAll(gates, options);
|
|
145
|
+
expect(result.allPassed).toBe(false);
|
|
146
|
+
expect(result.results).toHaveLength(2); // Stops after failed required gate
|
|
147
|
+
expect(result.results[1]?.passed).toBe(false);
|
|
148
|
+
});
|
|
149
|
+
it('should continue on optional gate failure', async () => {
|
|
150
|
+
const gatesWithOptional = [
|
|
151
|
+
{ name: 'test', command: 'npm test', required: true },
|
|
152
|
+
{ name: 'lint', command: 'npm run lint', required: false },
|
|
153
|
+
{ name: 'build', command: 'npm run build', required: true },
|
|
154
|
+
];
|
|
155
|
+
execMock.mockImplementation((cmd, _opts, callback) => {
|
|
156
|
+
if (typeof callback === 'function') {
|
|
157
|
+
if (cmd === 'npm run lint') {
|
|
158
|
+
callback(new Error('Lint failed'), { stdout: '', stderr: '' });
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
165
|
+
});
|
|
166
|
+
const result = await runner.runAll(gatesWithOptional, options);
|
|
167
|
+
expect(result.allPassed).toBe(true);
|
|
168
|
+
expect(result.results).toHaveLength(3);
|
|
169
|
+
expect(result.results[1]?.passed).toBe(false);
|
|
170
|
+
expect(result.results[2]?.passed).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('runWithAutoRetry', () => {
|
|
174
|
+
const gates = [
|
|
175
|
+
{ name: 'test', command: 'npm test', required: true },
|
|
176
|
+
];
|
|
177
|
+
it('should retry full validation on failure', async () => {
|
|
178
|
+
let overallCalls = 0;
|
|
179
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
180
|
+
overallCalls++;
|
|
181
|
+
if (typeof callback === 'function') {
|
|
182
|
+
if (overallCalls < 2) {
|
|
183
|
+
callback(new Error('Failed'), { stdout: '', stderr: '' });
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
190
|
+
});
|
|
191
|
+
const options = {
|
|
192
|
+
cwd: '/test',
|
|
193
|
+
maxRetries: 3,
|
|
194
|
+
};
|
|
195
|
+
const result = await runner.runWithAutoRetry(gates, options);
|
|
196
|
+
expect(result.allPassed).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
it('should call onRetry callback on failure', async () => {
|
|
199
|
+
// runWithAutoRetry calls runAll, which calls runGate
|
|
200
|
+
// runGate itself retries maxRetries times before failing
|
|
201
|
+
// Then runWithAutoRetry retries the whole runAll
|
|
202
|
+
// So we need to fail enough times to:
|
|
203
|
+
// 1. Fail runGate's retries (maxRetries times)
|
|
204
|
+
// 2. Then onRetry is called
|
|
205
|
+
// 3. Then succeed on next overall attempt
|
|
206
|
+
let callCount = 0;
|
|
207
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
208
|
+
callCount++;
|
|
209
|
+
if (typeof callback === 'function') {
|
|
210
|
+
// With maxRetries=2:
|
|
211
|
+
// - runGate tries 2 times (calls 1-2), fails
|
|
212
|
+
// - onRetry(1, 'test') is called
|
|
213
|
+
// - runGate tries 2 times (calls 3-4), succeeds on 3rd
|
|
214
|
+
if (callCount <= 2) {
|
|
215
|
+
callback(new Error('Failed'), { stdout: '', stderr: '' });
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
callback(null, { stdout: 'OK', stderr: '' });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
222
|
+
});
|
|
223
|
+
const onRetry = vi.fn();
|
|
224
|
+
const options = {
|
|
225
|
+
cwd: '/test',
|
|
226
|
+
maxRetries: 2,
|
|
227
|
+
onRetry,
|
|
228
|
+
};
|
|
229
|
+
const result = await runner.runWithAutoRetry(gates, options);
|
|
230
|
+
expect(onRetry).toHaveBeenCalledWith(1, 'test');
|
|
231
|
+
expect(result.allPassed).toBe(true);
|
|
232
|
+
});
|
|
233
|
+
it('should fail after overall max retries', async () => {
|
|
234
|
+
execMock.mockImplementation((_cmd, _opts, callback) => {
|
|
235
|
+
if (typeof callback === 'function') {
|
|
236
|
+
callback(new Error('Always fail'), { stdout: '', stderr: '' });
|
|
237
|
+
}
|
|
238
|
+
return { on: vi.fn(), stdout: null, stderr: null };
|
|
239
|
+
});
|
|
240
|
+
const options = {
|
|
241
|
+
cwd: '/test',
|
|
242
|
+
maxRetries: 2,
|
|
243
|
+
};
|
|
244
|
+
const result = await runner.runWithAutoRetry(gates, options);
|
|
245
|
+
expect(result.allPassed).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('DEFAULT_GATES', () => {
|
|
249
|
+
it('should have node gates defined', () => {
|
|
250
|
+
expect(DEFAULT_GATES.node).toBeDefined();
|
|
251
|
+
expect(DEFAULT_GATES.node).toHaveLength(4);
|
|
252
|
+
expect(DEFAULT_GATES.node[0]?.name).toBe('install');
|
|
253
|
+
expect(DEFAULT_GATES.node[1]?.name).toBe('test');
|
|
254
|
+
expect(DEFAULT_GATES.node[2]?.name).toBe('type');
|
|
255
|
+
expect(DEFAULT_GATES.node[3]?.name).toBe('lint');
|
|
256
|
+
});
|
|
257
|
+
it('should have pnpm gates defined', () => {
|
|
258
|
+
expect(DEFAULT_GATES.pnpm).toBeDefined();
|
|
259
|
+
expect(DEFAULT_GATES.pnpm).toHaveLength(4);
|
|
260
|
+
expect(DEFAULT_GATES.pnpm[0]?.command).toContain('pnpm install');
|
|
261
|
+
});
|
|
262
|
+
it('should have python gates defined', () => {
|
|
263
|
+
expect(DEFAULT_GATES.python).toBeDefined();
|
|
264
|
+
expect(DEFAULT_GATES.python[0]?.name).toBe('test');
|
|
265
|
+
expect(DEFAULT_GATES.python[0]?.command).toBe('pytest');
|
|
266
|
+
});
|
|
267
|
+
it('should mark required gates correctly', () => {
|
|
268
|
+
expect(DEFAULT_GATES.node[0]?.required).toBe(true);
|
|
269
|
+
expect(DEFAULT_GATES.node[3]?.required).toBe(false);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
describe('detectProjectGates', () => {
|
|
273
|
+
it('should return pnpm gates by default', () => {
|
|
274
|
+
const gates = detectProjectGates('/some/path');
|
|
275
|
+
expect(gates).toEqual(DEFAULT_GATES.pnpm);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
//# sourceMappingURL=ValidationGateRunner.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationGateRunner.test.js","sourceRoot":"","sources":["../../../src/infra/validation/ValidationGateRunner.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudetree/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Core domain and infrastructure for claudetree",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,17 +23,18 @@
|
|
|
23
23
|
"homepage": "https://github.com/wonjangcloud9/claude-tree#readme",
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"debug": "^4.4.
|
|
27
|
-
"execa": "^9.
|
|
28
|
-
"octokit": "^
|
|
29
|
-
"ws": "^8.
|
|
30
|
-
"@claudetree/shared": "0.4.
|
|
26
|
+
"debug": "^4.4.3",
|
|
27
|
+
"execa": "^9.6.1",
|
|
28
|
+
"octokit": "^5.0.5",
|
|
29
|
+
"ws": "^8.19.0",
|
|
30
|
+
"@claudetree/shared": "0.4.5"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/debug": "^4.1.12",
|
|
34
|
-
"@types/ws": "^8.
|
|
35
|
-
"typescript": "^5.
|
|
36
|
-
"vitest": "^3.
|
|
34
|
+
"@types/ws": "^8.18.1",
|
|
35
|
+
"typescript": "^5.9.3",
|
|
36
|
+
"vitest": "^3.2.4",
|
|
37
|
+
"yaml": "^2.8.2"
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
|
39
40
|
"build": "tsc",
|