/** * 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); }