- Record user evidence for directory fallback to complete GC1 (10/10 checks passed) - Expand Format Specification 0.1 to Revision 0.2 with normative shared contracts - Author JSON Schema Draft-07 at schema/xzbt-0.1.schema.json - Implement zero-dependency semantic validator at tools/validate-exhibit.mjs - Create 12-case conformance fixture suite and automated test runner (12/12 passing) - Update implementation status, verification gates, and gap closure decisions - Add devlog entry covering stall recovery and Phase 0 current state
121 lines
3.3 KiB
JavaScript
121 lines
3.3 KiB
JavaScript
/**
|
|
* GC2 Automated Conformance Test Suite
|
|
* Tests valid and invalid fixtures against the XZBT 0.1 Semantic Validator.
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
import { ExhibitValidator } from '../tools/validate-exhibit.mjs';
|
|
|
|
const testMatrix = [
|
|
// Valid Fixtures
|
|
{
|
|
file: 'test/fixtures/gc2/valid-minimal.xzbt',
|
|
expectedValid: true,
|
|
expectedError: null
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/valid-full-feature.xzbt',
|
|
expectedValid: true,
|
|
expectedError: null
|
|
},
|
|
{
|
|
file: 'prototypes/phase0/fixtures/amber-study.xzbt',
|
|
expectedValid: true,
|
|
expectedError: null
|
|
},
|
|
{
|
|
file: 'prototypes/phase0/fixtures/blue-study.xzbt',
|
|
expectedValid: true,
|
|
expectedError: null
|
|
},
|
|
|
|
// Invalid Fixtures with Expected Diagnostic Codes
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-unknown-field.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_UNKNOWN_FIELD'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-unsupported-version.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_UNSUPPORTED_VERSION'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-id-syntax.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_INVALID_ID'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-reference-missing.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_INVALID_REFERENCE'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-type-mismatch.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_TYPE_MISMATCH'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-cyclic-bindings.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_CYCLIC_DEPENDENCY'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-out-of-bounds.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_OUT_OF_BOUNDS'
|
|
},
|
|
{
|
|
file: 'test/fixtures/gc2/invalid-operator-arity.xzbt',
|
|
expectedValid: false,
|
|
expectedError: 'ERR_INVALID_ARITY'
|
|
}
|
|
];
|
|
|
|
console.log('--- Running GC2 Format Contract Conformance Suite ---\n');
|
|
|
|
let passedTests = 0;
|
|
let failedTests = 0;
|
|
|
|
for (const testCase of testMatrix) {
|
|
const fullPath = resolve(testCase.file);
|
|
const content = readFileSync(fullPath, 'utf-8');
|
|
const doc = JSON.parse(content);
|
|
const validator = new ExhibitValidator(doc, testCase.file);
|
|
const result = validator.validate();
|
|
|
|
if (testCase.expectedValid) {
|
|
if (result.valid) {
|
|
console.log(`PASS: ${testCase.file} (valid as expected)`);
|
|
passedTests++;
|
|
} else {
|
|
console.error(`FAIL: ${testCase.file} expected valid, but got errors:`);
|
|
for (const err of result.errors) {
|
|
console.error(` - [${err.code}] ${err.path}: ${err.message}`);
|
|
}
|
|
failedTests++;
|
|
}
|
|
} else {
|
|
if (!result.valid && result.errors.some((e) => e.code === testCase.expectedError)) {
|
|
console.log(`PASS: ${testCase.file} (correctly rejected with ${testCase.expectedError})`);
|
|
passedTests++;
|
|
} else {
|
|
console.error(
|
|
`FAIL: ${testCase.file} expected rejection with ${testCase.expectedError}, but got valid=${result.valid} errors:`,
|
|
result.errors
|
|
);
|
|
failedTests++;
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`\nResults: ${passedTests} passed, ${failedTests} failed out of ${testMatrix.length} total tests.`);
|
|
|
|
if (failedTests > 0) {
|
|
process.exit(1);
|
|
} else {
|
|
console.log('GC2 Contract Completeness Conformance: ALL TESTS PASSED.\n');
|
|
process.exit(0);
|
|
}
|