35 lines
1.7 KiB
JavaScript
35 lines
1.7 KiB
JavaScript
// tests/commands/trekresearch-engine.test.mjs
|
|
// Step 1 (deep-research-engine): pin the contract the `--engine deep-research`
|
|
// adapter must hit. The adapted in-context `/deep-research` report, reduced into
|
|
// the research-brief schema, must pass research-validator under the strict
|
|
// default; and a brief missing a required section must fail. This is the one
|
|
// genuinely automatable slice of SC2 (schema, not provenance).
|
|
|
|
import { test } from 'node:test';
|
|
import { strict as assert } from 'node:assert';
|
|
import { readFileSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { validateResearchContent } from '../../lib/validators/research-validator.mjs';
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = join(HERE, '..', '..');
|
|
const FIXTURE = join(ROOT, 'tests', 'fixtures', 'research-deep-research-adapted.md');
|
|
|
|
test('deep-research adapter output contract — valid brief passes, missing section fails', () => {
|
|
const text = readFileSync(FIXTURE, 'utf-8');
|
|
|
|
// (a) positive: the adapter's target output passes the validator (default = strict).
|
|
const okResult = validateResearchContent(text);
|
|
assert.equal(okResult.valid, true, JSON.stringify(okResult.errors));
|
|
|
|
// (b) negative: stripping a required section makes it fail with RESEARCH_MISSING_SECTION,
|
|
// giving the contract teeth (a fixture that always passes proves nothing).
|
|
const mutated = text.replace('## Dimensions', '## Removed');
|
|
const badResult = validateResearchContent(mutated);
|
|
assert.equal(badResult.valid, false);
|
|
assert.ok(
|
|
badResult.errors.find(e => e.code === 'RESEARCH_MISSING_SECTION'),
|
|
'expected RESEARCH_MISSING_SECTION; got ' + JSON.stringify(badResult.errors),
|
|
);
|
|
});
|