Files
HMDesign/scripts/guard-requirements.test.mjs

30 lines
2.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { sourceFingerprint } from './guard-evidence.mjs';
import { reviewActions } from './guard-requirements.mjs';
function fixture(source, fn) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'hm-action-review-'));
try {
fs.writeFileSync(path.join(dir, 'App.tsx'), source);
const guard = { status: 'NOT VERIFIED', scope: 'FULL_SCREEN', target: dir, contractSource: dir, fingerprintFiles: ['App.tsx'], contractFiles: ['App.tsx'], checkedFiles: ['App.tsx'], issues: [{ code: 'RENDER-002' }] };
guard.sourceFingerprint = guard.contractFingerprint = sourceFingerprint(dir, ['App.tsx']);
fn(guard, { schemaVersion: 1, actionPolicy: { allowedLabels: ['조회', '초기화'] } });
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
}
test('explicit authorized actions pass without changing raw Guard', () => fixture('import {Button as Action} from "@hm-design/ui"; const App=()=> <><Action>조회</Action><button aria-label="초기화"/></>;', (g, r) => {
const original = JSON.stringify(g); assert.equal(reviewActions(g, r).status, 'PASS'); assert.equal(JSON.stringify(g), original);
}));
test('unrequested CSV and download links fail independently', () => fixture('const App=()=> <><button>CSV 다운로드</button><a download href="local.csv">내보내기</a></>;', (g, r) => {
const result = reviewActions(g, r); assert.equal(result.status, 'FAIL'); assert.equal(result.findings.filter(f => f.code === 'REQ-003').length, 2);
}));
test('dynamic action names and spread props remain unverified', () => fixture('const App=()=> <><button>{caption}</button><button {...props}>조회</button></>;', (g, r) => assert.equal(reviewActions(g, r).status, 'NOT VERIFIED')));
test('stale source, absent policy and partial coverage cannot pass', () => fixture('const App=()=> <button>조회</button>;', (g, r) => {
assert.equal(reviewActions(g, {}).status, 'NOT VERIFIED'); assert.equal(reviewActions({ ...g, scope: 'PARTIAL' }, r).status, 'NOT VERIFIED');
fs.appendFileSync(path.join(g.target, 'App.tsx'), '\n// changed'); assert.equal(reviewActions(g, r).status, 'NOT VERIFIED');
}));
test('layout HTML is permitted; no observed actions is not proof of compliance', () => fixture('const App=()=> <section><p>CSV guide</p></section>;', (g, r) => assert.equal(reviewActions(g, r).status, 'NOT VERIFIED')));