leerness 1.27.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/README.md +4 -4
- package/bin/leerness.js +38 -6
- package/lib/audit.js +5 -0
- package/lib/diagnostics.js +44 -41
- package/lib/drift.js +343 -341
- package/package.json +1 -1
- package/scripts/e2e.js +45 -2
package/package.json
CHANGED
package/scripts/e2e.js
CHANGED
|
@@ -6230,10 +6230,18 @@ total++;
|
|
|
6230
6230
|
const hEn = out(cp.spawnSync(process.execPath, [CLI, 'health', '--language', 'en', '--path', d], { encoding: 'utf8', timeout: 20000 }));
|
|
6231
6231
|
const hKo = out(cp.spawnSync(process.execPath, [CLI, 'health', '--path', d], { encoding: 'utf8', timeout: 20000 }));
|
|
6232
6232
|
const healthOk = /## Security/.test(hEn) && !H.test(hEn) && /## 보안/.test(hKo);
|
|
6233
|
+
// ⑥ (1.27.2 Phase 10) drift check 출력: en 영어(한글 0, --auto-fix 제외) + ko 기본 한글 보존
|
|
6234
|
+
const drEn = out(cp.spawnSync(process.execPath, [CLI, 'drift', 'check', d, '--language', 'en'], { encoding: 'utf8', timeout: 20000 }));
|
|
6235
|
+
const drKo = out(cp.spawnSync(process.execPath, [CLI, 'drift', 'check', d], { encoding: 'utf8', timeout: 20000 }));
|
|
6236
|
+
const driftOk = /signal \| age \| threshold/.test(drEn) && !H.test(drEn) && /신호 \| age \| 임계/.test(drKo);
|
|
6237
|
+
// ⑦ (1.28.2 Phase 10c) doctor: en 영어(한글 0) + ko 기본 한글 보존
|
|
6238
|
+
const docEn = out(cp.spawnSync(process.execPath, [CLI, 'doctor', '--language', 'en'], { encoding: 'utf8', timeout: 20000, cwd: d }));
|
|
6239
|
+
const docKo = out(cp.spawnSync(process.execPath, [CLI, 'doctor'], { encoding: 'utf8', timeout: 20000, cwd: d }));
|
|
6240
|
+
const doctorOk = /install\/environment diagnosis/.test(docEn) && !H.test(docEn) && /설치\/환경 진단/.test(docKo);
|
|
6233
6241
|
fs.rmSync(d, { recursive: true, force: true });
|
|
6234
|
-
ok = lensKoOk && lensEnOk && noLeak && stOk && healthOk;
|
|
6242
|
+
ok = lensKoOk && lensEnOk && noLeak && stOk && healthOk && driftOk && doctorOk;
|
|
6235
6243
|
} catch {}
|
|
6236
|
-
console.log(ok ? '✓ B(1.25.1/1.25.2) i18n 행위: --language en 런타임 영어(lens/health) + ko 기본 보존 + --language positional 무누출 + status 에러 en/ko (UR-0010)' : '✗ i18n 행위 회귀 가드 실패');
|
|
6244
|
+
console.log(ok ? '✓ B(1.25.1/1.25.2/1.27.2/1.28.2) i18n 행위: --language en 런타임 영어(lens/health/drift/doctor) + ko 기본 보존 + --language positional 무누출 + status 에러 en/ko (UR-0010)' : '✗ i18n 행위 회귀 가드 실패');
|
|
6237
6245
|
if (!ok) failed++;
|
|
6238
6246
|
}
|
|
6239
6247
|
|
|
@@ -6270,5 +6278,40 @@ total++;
|
|
|
6270
6278
|
if (!ok) failed++;
|
|
6271
6279
|
}
|
|
6272
6280
|
|
|
6281
|
+
// 1.27.1 (13번째 외부리뷰 정직성 후속 회귀가드): audit 미초기화 모순출력 차단 + verify-claim no-parse 정직표기 (양방향 무회귀).
|
|
6282
|
+
total++;
|
|
6283
|
+
{
|
|
6284
|
+
let ok = false;
|
|
6285
|
+
try {
|
|
6286
|
+
const d = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-rev13b-'));
|
|
6287
|
+
const out = (r) => (r.stdout || '') + (r.stderr || '');
|
|
6288
|
+
// #2 audit 미초기화: design/reuse 모순 출력 없이 요약 직행 + exit 1 + --json not_initialized
|
|
6289
|
+
fs.mkdirSync(path.join(d, 'uninit'));
|
|
6290
|
+
const au = cp.spawnSync(process.execPath, [CLI, 'audit', path.join(d, 'uninit')], { encoding: 'utf8', timeout: 15000 });
|
|
6291
|
+
const auClean = au.status === 1 && !/design guide|reuse-map/.test(out(au)) && /Audit summary/.test(out(au));
|
|
6292
|
+
const auj = cp.spawnSync(process.execPath, [CLI, 'audit', path.join(d, 'uninit'), '--json'], { encoding: 'utf8', timeout: 15000 });
|
|
6293
|
+
let aujOk = false; try { const j = JSON.parse(auj.stdout); aujOk = j.healthy === false && (j.findings || []).some(f => f.kind === ('not_' + 'initialized')); } catch {}
|
|
6294
|
+
// #2 회귀: 정상 프로젝트 audit 는 체크 계속 수행
|
|
6295
|
+
cp.spawnSync(process.execPath, [CLI, 'init', d, '--yes'], { encoding: 'utf8', timeout: 30000 });
|
|
6296
|
+
const auReal = out(cp.spawnSync(process.execPath, [CLI, 'audit', d], { encoding: 'utf8', timeout: 15000 }));
|
|
6297
|
+
const auRealOk = /Audit summary/.test(auReal) && /gitignore|design|reuse/.test(auReal);
|
|
6298
|
+
// #3 verify-claim 비-테스트 --test-cmd → 거짓 'all passed' 아님(정직 표기)
|
|
6299
|
+
fs.mkdirSync(path.join(d, 'src'), { recursive: true });
|
|
6300
|
+
fs.writeFileSync(path.join(d, 'src', 'x.js'), 'module.exports={};\n');
|
|
6301
|
+
fs.writeFileSync(path.join(d, 'x.test.js'), 'test();\n');
|
|
6302
|
+
cp.spawnSync(process.execPath, [CLI, 'task', 'add', 'x', '--path', d], { encoding: 'utf8', timeout: 15000 });
|
|
6303
|
+
cp.spawnSync(process.execPath, [CLI, 'task', 'update', 'T-0002', '--status', 'done', '--evidence', 'src/x.js implemented, x.test.js added', '--path', d], { encoding: 'utf8', timeout: 15000 });
|
|
6304
|
+
const vcNon = out(cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo hi', '--path', d], { encoding: 'utf8', timeout: 20000 }));
|
|
6305
|
+
const vcNonOk = /미확인|unconfirmed/.test(vcNon) && !/echo hi.*all passed/.test(vcNon);
|
|
6306
|
+
// #3 회귀: 진짜 N/N 테스트 → all passed 유지
|
|
6307
|
+
const vcReal = out(cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo Tests: 2 passed, 2 total', '--path', d], { encoding: 'utf8', timeout: 20000 }));
|
|
6308
|
+
const vcRealOk = /all passed/.test(vcReal);
|
|
6309
|
+
fs.rmSync(d, { recursive: true, force: true });
|
|
6310
|
+
ok = auClean && aujOk && auRealOk && vcNonOk && vcRealOk;
|
|
6311
|
+
} catch {}
|
|
6312
|
+
console.log(ok ? '✓ B(1.27.1) 13th 리뷰 정직성: audit 미초기화 모순출력 차단(+정상 무회귀) + verify-claim no-parse 정직표기(+진짜테스트 무회귀)' : '✗ 13th 리뷰 정직성 후속 회귀가드 실패');
|
|
6313
|
+
if (!ok) failed++;
|
|
6314
|
+
}
|
|
6315
|
+
|
|
6273
6316
|
console.log(`\nE2E result: ${total - failed}/${total} passed · ${((Date.now() - _e2eStart) / 1000).toFixed(0)}s`);
|
|
6274
6317
|
if (failed > 0) process.exit(1);
|