30 lines
2.4 KiB
JavaScript
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')));
|