mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
fix(ci): align smoke stderr expectations
This commit is contained in:
parent
009558be7e
commit
6a1fded5ce
2 changed files with 51 additions and 28 deletions
|
|
@ -146,6 +146,10 @@ function parseJsonOutput<T>(stdout: string): T {
|
|||
return JSON.parse(stdout) as T;
|
||||
}
|
||||
|
||||
function expectProjectStderr(result: CliResult, projectDir: string): void {
|
||||
expect(result).toMatchObject({ code: 0, stderr: `Project: ${projectDir}\n` });
|
||||
}
|
||||
|
||||
async function runSetupNewProject(projectDir: string): Promise<CliResult> {
|
||||
return await runBuiltCli([
|
||||
'setup',
|
||||
|
|
@ -178,7 +182,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const sourceDir = join(tempDir, 'source');
|
||||
|
||||
const init = await runSetupNewProject(projectDir);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
expect(init.stdout).toContain(`Project: ${projectDir}`);
|
||||
|
||||
await writeWarehouseConfig(projectDir);
|
||||
|
|
@ -204,14 +208,15 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
});
|
||||
|
||||
it('runs the default pre-seeded demo without credentials', async () => {
|
||||
const projectDir = join(tempDir, 'demo-project');
|
||||
const result = await runBuiltCli(
|
||||
['setup', 'demo', '--project-dir', join(tempDir, 'demo-project'), '--plain', '--no-input'],
|
||||
['setup', 'demo', '--project-dir', projectDir, '--plain', '--no-input'],
|
||||
{
|
||||
env: { ...process.env, ANTHROPIC_API_KEY: '' },
|
||||
},
|
||||
);
|
||||
|
||||
expect(result).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(result, projectDir);
|
||||
expect(result.stdout).toContain('Mode: seeded');
|
||||
expect(result.stdout).toContain('Source: packaged demo project');
|
||||
expect(result.stdout).toContain('LLM calls: none');
|
||||
|
|
@ -231,7 +236,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const seeded = await runBuiltCli(['setup', 'demo', '--project-dir', projectDir, '--plain', '--no-input'], {
|
||||
env: { ...process.env, ANTHROPIC_API_KEY: '' },
|
||||
});
|
||||
expect(seeded).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(seeded, projectDir);
|
||||
expect(seeded.stdout).toContain('Mode: seeded');
|
||||
|
||||
const wikiSearch = await runBuiltCli([
|
||||
|
|
@ -319,7 +324,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
expect(seeded.stdout).toContain('Knowledge pages:');
|
||||
|
||||
const inspect = await runBuiltCli(['setup', 'demo', 'inspect', '--project-dir', projectDir, '--no-input']);
|
||||
expect(inspect).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(inspect, projectDir);
|
||||
expect(inspect.stdout).toContain('Mode: seeded');
|
||||
expect(inspect.stdout).toContain('Status: ready');
|
||||
expect(inspect.stdout).toContain('Warehouse: 8 tables, 11,234 rows');
|
||||
|
|
@ -348,7 +353,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
env: { ...process.env, ANTHROPIC_API_KEY: '' },
|
||||
},
|
||||
);
|
||||
expect(seeded).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(seeded, projectDir);
|
||||
expect(seeded.stdout).toContain('Mode: seeded');
|
||||
|
||||
const client = new Client({ name: 'ktx-seeded-demo-smoke-client', version: '0.0.0' });
|
||||
|
|
@ -413,7 +418,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
expect(result.stdout).toContain('KTX setup doctor');
|
||||
expect(result.stdout).toContain('Node 22+');
|
||||
expect(result.stdout).toContain('Workspace-local CLI');
|
||||
expect(result.stderr).toBe('');
|
||||
expect(result.stderr).toBe(`Project: ${process.cwd()}\n`);
|
||||
expect([0, 1]).toContain(result.code);
|
||||
});
|
||||
|
||||
|
|
@ -433,7 +438,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const projectDir = join(tempDir, 'reset-demo-project');
|
||||
|
||||
const init = await runBuiltCli(['setup', 'demo', 'init', '--project-dir', projectDir, '--no-input']);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
|
||||
const withoutForce = await runBuiltCli(['setup', 'demo', 'reset', '--project-dir', projectDir, '--no-input']);
|
||||
expect(withoutForce.code).toBe(1);
|
||||
|
|
@ -450,7 +455,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
'--force',
|
||||
'--no-input',
|
||||
]);
|
||||
expect(withForce).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(withForce, projectDir);
|
||||
expect(withForce.stdout).toContain(`Demo project reset: ${projectDir}`);
|
||||
});
|
||||
|
||||
|
|
@ -458,7 +463,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const projectDir = join(tempDir, 'corrupt-demo-project');
|
||||
|
||||
const init = await runBuiltCli(['setup', 'demo', 'init', '--project-dir', projectDir, '--no-input']);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
await rm(join(projectDir, 'demo.db'), { force: true });
|
||||
|
||||
const replay = await runBuiltCli(['setup', 'demo', '--mode', 'replay', '--project-dir', projectDir, '--no-input']);
|
||||
|
|
@ -471,14 +476,14 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const projectDir = join(tempDir, 'doctor-demo-project');
|
||||
|
||||
const init = await runBuiltCli(['setup', 'demo', 'init', '--project-dir', projectDir, '--no-input']);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
|
||||
const result = await runBuiltCli(['setup', 'demo', 'doctor', '--project-dir', projectDir, '--no-input']);
|
||||
expect(result.stdout).toContain('KTX demo doctor');
|
||||
expect(result.stdout).toContain('Demo dataset');
|
||||
expect(result.stdout).toContain('Demo replay');
|
||||
expect(result.stdout).toContain('Demo LLM provider');
|
||||
expect(result.stderr).toBe('');
|
||||
expect(result.stderr).toBe(`Project: ${projectDir}\n`);
|
||||
expect([0, 1]).toContain(result.code);
|
||||
});
|
||||
|
||||
|
|
@ -504,20 +509,20 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
it('runs structural and enriched scans through the built binary with manifest artifacts', async () => {
|
||||
const projectDir = join(tempDir, 'scan-project');
|
||||
const init = await runSetupNewProject(projectDir);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
|
||||
const dbPath = join(projectDir, 'warehouse.db');
|
||||
createSqliteWarehouse(dbPath);
|
||||
await writeSqliteScanConfig(projectDir, dbPath);
|
||||
|
||||
const connectionTest = await runBuiltCli(['connection', 'test', 'warehouse', '--project-dir', projectDir]);
|
||||
expect(connectionTest).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(connectionTest, projectDir);
|
||||
expect(connectionTest.stdout).toContain('Connection test passed: warehouse');
|
||||
expect(connectionTest.stdout).toContain('Driver: sqlite');
|
||||
expect(connectionTest.stdout).toContain('Tables: 2');
|
||||
|
||||
const structural = await runBuiltCli(['dev', 'scan', 'warehouse', '--project-dir', projectDir]);
|
||||
expect(structural).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(structural, projectDir);
|
||||
expect(structural.stdout).toContain('Status: done');
|
||||
expect(structural.stdout).toContain('Mode: structural');
|
||||
const structuralRunId = getRunId(structural.stdout);
|
||||
|
|
@ -560,7 +565,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
'--mode',
|
||||
'enriched',
|
||||
]);
|
||||
expect(providerlessEnriched).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(providerlessEnriched, projectDir);
|
||||
expect(providerlessEnriched.stdout).toContain('Mode: enriched');
|
||||
expect(providerlessEnriched.stdout).toContain('Relationships');
|
||||
expect(providerlessEnriched.stdout).toContain('Accepted: 1');
|
||||
|
|
@ -614,7 +619,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
|
||||
await writeSqliteScanConfig(projectDir, dbPath, true);
|
||||
const enriched = await runBuiltCli(['dev', 'scan', 'warehouse', '--project-dir', projectDir, '--mode', 'enriched']);
|
||||
expect(enriched).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(enriched, projectDir);
|
||||
expect(enriched.stdout).toContain('Mode: enriched');
|
||||
const enrichedRunId = getRunId(enriched.stdout);
|
||||
|
||||
|
|
@ -706,7 +711,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
it('adds a redacted Notion connection through the built binary', async () => {
|
||||
const projectDir = join(tempDir, 'notion-project');
|
||||
const init = await runSetupNewProject(projectDir);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
|
||||
const add = await runBuiltCli([
|
||||
'connection',
|
||||
|
|
@ -723,7 +728,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
'5',
|
||||
]);
|
||||
|
||||
expect(add).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(add, projectDir);
|
||||
expect(add.stdout).toContain('Connection: notion-main');
|
||||
expect(add.stdout).toContain('Driver: notion');
|
||||
|
||||
|
|
@ -746,7 +751,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
const projectDir = join(tempDir, 'project');
|
||||
|
||||
const init = await runSetupNewProject(projectDir);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
await writeWarehouseConfig(projectDir);
|
||||
|
||||
const client = new Client({ name: 'ktx-smoke-client', version: '0.0.0' });
|
||||
|
|
@ -812,7 +817,7 @@ describe('standalone built ktx CLI smoke', () => {
|
|||
it('serves scan execution and artifact inspection tools over stdio from the built binary', async () => {
|
||||
const projectDir = join(tempDir, 'scan-mcp-project');
|
||||
const init = await runSetupNewProject(projectDir);
|
||||
expect(init).toMatchObject({ code: 0, stderr: '' });
|
||||
expectProjectStderr(init, projectDir);
|
||||
|
||||
const dbPath = join(projectDir, 'warehouse.db');
|
||||
createSqliteWarehouse(dbPath);
|
||||
|
|
|
|||
|
|
@ -520,6 +520,15 @@ function requireSuccess(label, result) {
|
|||
assert.equal(result.stderr, '', label + ' wrote unexpected stderr');
|
||||
}
|
||||
|
||||
function requireProjectStderr(label, result, projectDir) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
0,
|
||||
label + ' failed with code ' + result.code + '\\nstdout:\\n' + result.stdout + '\\nstderr:\\n' + result.stderr,
|
||||
);
|
||||
assert.equal(result.stderr, 'Project: ' + projectDir + '\\n', label + ' wrote unexpected stderr');
|
||||
}
|
||||
|
||||
function requireSuccessWithStderr(label, result, stderrPattern) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
|
|
@ -631,7 +640,7 @@ try {
|
|||
'--skip-sources',
|
||||
'--skip-agents',
|
||||
]);
|
||||
requireSuccess('ktx setup', init);
|
||||
requireProjectStderr('ktx setup', init, projectDir);
|
||||
requireOutput('ktx setup', init, /Project: /);
|
||||
|
||||
const emptyProjectDir = join(root, 'empty-project');
|
||||
|
|
@ -650,7 +659,7 @@ try {
|
|||
'--skip-sources',
|
||||
'--skip-agents',
|
||||
]);
|
||||
requireSuccess('ktx setup empty project', emptyInit);
|
||||
requireProjectStderr('ktx setup empty project', emptyInit, emptyProjectDir);
|
||||
const emptySearch = await run('pnpm', [
|
||||
'exec',
|
||||
'ktx',
|
||||
|
|
@ -905,7 +914,7 @@ try {
|
|||
'--project-dir',
|
||||
projectDir,
|
||||
]);
|
||||
requireSuccess('ktx scan structural', structuralScan);
|
||||
requireProjectStderr('ktx scan structural', structuralScan, projectDir);
|
||||
requireOutput('ktx scan structural', structuralScan, /Status: done/);
|
||||
requireOutput('ktx scan structural', structuralScan, /Mode: structural/);
|
||||
requireOutput('ktx scan structural', structuralScan, /Needs attention\\s+None/);
|
||||
|
|
@ -916,7 +925,7 @@ try {
|
|||
projectDir,
|
||||
structuralScanRunId,
|
||||
]);
|
||||
requireSuccess('ktx scan status', scanStatus);
|
||||
requireProjectStderr('ktx scan status', scanStatus, projectDir);
|
||||
requireOutput('ktx scan status', scanStatus, new RegExp('Run: ' + structuralScanRunId));
|
||||
requireOutput('ktx scan status', scanStatus, /Status: done/);
|
||||
requireOutput('ktx scan status', scanStatus, /Mode: structural/);
|
||||
|
|
@ -943,7 +952,7 @@ try {
|
|||
'--mode',
|
||||
'enriched',
|
||||
]);
|
||||
requireSuccess('ktx scan enriched', enrichedScan);
|
||||
requireProjectStderr('ktx scan enriched', enrichedScan, projectDir);
|
||||
requireOutput('ktx scan enriched', enrichedScan, /Status: done/);
|
||||
requireOutput('ktx scan enriched', enrichedScan, /Mode: enriched/);
|
||||
const enrichedScanRunId = getRunId(enrichedScan.stdout);
|
||||
|
|
@ -1037,6 +1046,15 @@ function requireStdout(label, result, pattern) {
|
|||
assert.match(result.stdout, pattern, label + ' stdout did not match ' + pattern);
|
||||
}
|
||||
|
||||
function requireProjectStderr(label, result, projectDir) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
0,
|
||||
label + ' failed with code ' + result.code + '\\nstdout:\\n' + result.stdout + '\\nstderr:\\n' + result.stderr,
|
||||
);
|
||||
assert.equal(result.stderr, 'Project: ' + projectDir + '\\n', label + ' wrote unexpected stderr');
|
||||
}
|
||||
|
||||
const root = await mkdtemp(join(tmpdir(), 'ktx-packed-demo-smoke-'));
|
||||
try {
|
||||
const projectDir = join(root, 'demo-project');
|
||||
|
|
@ -1059,7 +1077,7 @@ try {
|
|||
requireStdout('ktx setup demo seeded', seeded, /ktx serve --mcp stdio/);
|
||||
assert.doesNotMatch(seeded.stdout, new RegExp(['--mode', 'deterministic'].join(' ')));
|
||||
assert.doesNotMatch(seeded.stdout, /KTX memory flow/);
|
||||
assert.equal(seeded.stderr, '', 'ktx setup demo seeded wrote unexpected stderr');
|
||||
requireProjectStderr('ktx setup demo seeded', seeded, projectDir);
|
||||
|
||||
const demoWikiSearch = await run('pnpm', [
|
||||
'exec',
|
||||
|
|
@ -1108,7 +1126,7 @@ try {
|
|||
assert.ok([0, 1].includes(doctor.code), 'ktx dev doctor setup exit code must be 0 or 1');
|
||||
requireStdout('ktx dev doctor setup', doctor, /KTX setup doctor/);
|
||||
requireStdout('ktx dev doctor setup', doctor, /Node 22\\+/);
|
||||
assert.equal(doctor.stderr, '', 'ktx dev doctor setup wrote unexpected stderr');
|
||||
assert.equal(doctor.stderr, 'Project: ' + process.cwd() + '\\n', 'ktx dev doctor setup wrote unexpected stderr');
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue