ktg-plugin-marketplace/plugins/voyage/tests/validators/review-validator-annotation-fields.test.mjs
Kjell Tore Guttormsen ff7a5c63da test(voyage): pin forward-compat for revision/source_annotations/annotation_digest/revision_reason — v4.2 Step 2
3 new test files, 24 cases (8 per validator):
- baseline (no annotation fields) still valid
- revision: 0 / revision: 5 accepted
- source_annotations list-of-dict accepted
- annotation_digest string accepted
- revision_reason accepted
- all 4 fields together accepted
- unrecognized future field tolerated (forward-compat policy)

Pin against future strict-key refactors. No production code change — pure regression pin.
2026-05-09 12:50:22 +02:00

89 lines
3.8 KiB
JavaScript

// tests/validators/review-validator-annotation-fields.test.mjs
// Pin forward-compat for v4.2 annotation frontmatter fields on review.md.
// Adding revision/source_annotations/annotation_digest/revision_reason must NOT
// trigger REVIEW_UNKNOWN_FIELD or similar — validator is purely additive-tolerant
// per source_findings precedent. No code change required; this test pins the policy.
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { validateReviewContent } from '../../lib/validators/review-validator.mjs';
const BASE_REVIEW = `---
type: trekreview
review_version: "1.0"
created: 2026-05-09
task: "Annotated revision forward-compat"
slug: ann-fwd-compat
project_dir: .claude/projects/2026-05-09-ann-fwd-compat/
brief_path: .claude/projects/2026-05-09-ann-fwd-compat/brief.md
scope_sha_start: abc123
scope_sha_end: def456
reviewed_files_count: 1
findings: []
---
# Review
## Executive Summary
Verdict: ALLOW.
## Coverage
| File | Treatment | Reason |
|------|-----------|--------|
| lib/foo.mjs | deep-review | risk |
## Remediation Summary
None.
`;
test('review-validator forward-compat — baseline (no annotation fields) still valid', () => {
const r = validateReviewContent(BASE_REVIEW, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — accepts revision: 0', () => {
const t = BASE_REVIEW.replace('findings: []', 'findings: []\nrevision: 0');
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — accepts revision: 5', () => {
const t = BASE_REVIEW.replace('findings: []', 'findings: []\nrevision: 5');
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — accepts source_annotations alongside source-style findings', () => {
const inject = `\nrevision: 1\nsource_annotations:\n - id: ANN-0001\n target_artifact: review.md\n target_anchor: executive-summary\n intent: question\n comment: "wording is ambiguous"\n timestamp: "2026-05-09T10:00:00Z"`;
const t = BASE_REVIEW.replace('findings: []', 'findings: []' + inject);
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — accepts annotation_digest string', () => {
const t = BASE_REVIEW.replace('findings: []', 'findings: []\nrevision: 1\nannotation_digest: 0123456789abcdef');
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — accepts revision_reason for non-additive revision', () => {
const t = BASE_REVIEW.replace('findings: []', 'findings: []\nrevision: 2\nrevision_reason: "removed coverage section"');
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — all 4 annotation fields together still valid', () => {
const inject = `\nrevision: 3\nrevision_reason: "applied 2 annotations"\nannotation_digest: 0123456789abcdef\nsource_annotations:\n - id: ANN-0001\n target_artifact: review.md\n target_anchor: coverage\n intent: change`;
const t = BASE_REVIEW.replace('findings: []', 'findings: []' + inject);
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});
test('review-validator forward-compat — unrecognized future field tolerated', () => {
const t = BASE_REVIEW.replace('findings: []', 'findings: []\nfuture_v4_3_key: "any"');
const r = validateReviewContent(t, { strict: true });
assert.equal(r.valid, true, JSON.stringify(r.errors));
});