397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
144 lines
5.0 KiB
JavaScript
144 lines
5.0 KiB
JavaScript
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 });
|
|
});
|