import test from 'node:test'; import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { mkdtempSync, mkdirSync, rmSync, existsSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { isPatched, applyPatch, revertPatch, resolveTargetPath, PATCH_MARKER, } from './ruflo-h7-patch.mjs'; import { resolveDedupePaths, dedupeStatus, applyDedupe, revertDedupe } from './ruflo-h7-patch.mjs'; // Фикстура — фактический getBridge() из memory-initializer.js:70-84. const FIXTURE = `let _bridge; async function getBridge() { if (_bridge === null) return null; if (_bridge) return _bridge; try { _bridge = await import('./memory-bridge.js'); return _bridge; } catch { _bridge = null; return null; } } `; test('isPatched: false on clean content', () => { assert.equal(isPatched(FIXTURE), false); }); test('applyPatch: inserts patch line right after the anchor', () => { const { content, changed } = applyPatch(FIXTURE); assert.equal(changed, true); assert.ok(content.includes(PATCH_MARKER)); const lines = content.split('\n'); const anchorIdx = lines.findIndex((l) => l.includes('async function getBridge()')); assert.ok(lines[anchorIdx + 1].includes(PATCH_MARKER)); }); test('applyPatch: idempotent — second apply is a no-op', () => { const once = applyPatch(FIXTURE).content; const twice = applyPatch(once); assert.equal(twice.changed, false); assert.equal(twice.content, once); }); test('isPatched: true after applyPatch', () => { assert.equal(isPatched(applyPatch(FIXTURE).content), true); }); test('applyPatch: throws when the anchor is absent', () => { assert.throws(() => applyPatch('function other() {}\n'), /anchor .* not found/); }); test('revertPatch: removes the patch line and restores the original', () => { const patched = applyPatch(FIXTURE).content; const { content, changed } = revertPatch(patched); assert.equal(changed, true); assert.equal(isPatched(content), false); assert.equal(content, FIXTURE); }); test('revertPatch: no-op on unpatched content', () => { assert.equal(revertPatch(FIXTURE).changed, false); }); test('resolveTargetPath: null when no candidate file exists', () => { assert.equal(resolveTargetPath('/nonexistent/npm/root/zzz'), null); }); test('main: rejects an unknown flag with exit code 2', () => { assert.throws( () => execFileSync(process.execPath, ['tools/ruflo-h7-patch.mjs', '--bogus'], { stdio: 'pipe' }), (err) => err.status === 2, ); }); test('resolveDedupePaths: active dir + .h7disabled sibling', () => { const { active, disabled } = resolveDedupePaths('/npm/root'); assert.ok(active.includes('onnxruntime-node')); assert.ok(active.includes('xenova')); assert.equal(disabled, active + '.h7disabled'); }); test('dedupeStatus: absent / not-deduped / deduped / inconsistent', () => { const tmp = mkdtempSync(join(tmpdir(), 'h7d-')); const active = join(tmp, 'onnxruntime-node'); const disabled = join(tmp, 'onnxruntime-node.h7disabled'); assert.equal(dedupeStatus(active, disabled), 'absent'); mkdirSync(active); assert.equal(dedupeStatus(active, disabled), 'not-deduped'); rmSync(active, { recursive: true }); mkdirSync(disabled); assert.equal(dedupeStatus(active, disabled), 'deduped'); mkdirSync(active); assert.equal(dedupeStatus(active, disabled), 'inconsistent'); rmSync(tmp, { recursive: true }); }); test('applyDedupe: renames active -> disabled, idempotent', () => { const tmp = mkdtempSync(join(tmpdir(), 'h7d-')); const active = join(tmp, 'onnxruntime-node'); const disabled = join(tmp, 'onnxruntime-node.h7disabled'); mkdirSync(active); const r1 = applyDedupe(active, disabled); assert.equal(r1.changed, true); assert.ok(existsSync(disabled) && !existsSync(active)); const r2 = applyDedupe(active, disabled); assert.equal(r2.changed, false); rmSync(tmp, { recursive: true }); }); test('applyDedupe: no-op when neither dir exists (absent)', () => { const tmp = mkdtempSync(join(tmpdir(), 'h7d-')); const r = applyDedupe(join(tmp, 'onnxruntime-node'), join(tmp, 'onnxruntime-node.h7disabled')); assert.equal(r.changed, false); assert.equal(r.status, 'absent'); rmSync(tmp, { recursive: true }); }); test('revertDedupe: renames disabled -> active', () => { const tmp = mkdtempSync(join(tmpdir(), 'h7d-')); const active = join(tmp, 'onnxruntime-node'); const disabled = join(tmp, 'onnxruntime-node.h7disabled'); mkdirSync(disabled); const r = revertDedupe(active, disabled); assert.equal(r.changed, true); assert.ok(existsSync(active) && !existsSync(disabled)); rmSync(tmp, { recursive: true }); }); test('applyDedupe: throws on inconsistent state (both dirs exist)', () => { const tmp = mkdtempSync(join(tmpdir(), 'h7d-')); const active = join(tmp, 'onnxruntime-node'); const disabled = join(tmp, 'onnxruntime-node.h7disabled'); mkdirSync(active); mkdirSync(disabled); assert.throws(() => applyDedupe(active, disabled), /inconsistent/); rmSync(tmp, { recursive: true }); });