Files
2026-09-09 11:21:33 -04:00

126 lines
4.3 KiB
JavaScript

import assert from "node:assert/strict";
import { EventEmitter } from "node:events";
import path from "node:path";
import test from "node:test";
import {
defaultWowExportExecutable,
resolveWowExportExecutable,
runWowExporter,
WOW_EXPORT_REQUIRED_FLAGS,
} from "./wow-export-tool.mjs";
const projectRoot = path.resolve("fixture/HealerMan");
const fileInfo = { isFile: () => true };
test("resolveWowExportExecutable uses the versioned portable path by default", async () => {
const expected = defaultWowExportExecutable(projectRoot);
const inspected = [];
const resolved = await resolveWowExportExecutable({
projectRoot,
environment: {},
statFile: async (file) => {
inspected.push(file);
return fileInfo;
},
});
assert.equal(resolved, expected);
assert.deepEqual(inspected, [expected]);
});
test("resolveWowExportExecutable honors an explicit relative WOW_EXPORT_BIN", async () => {
const expected = path.resolve(projectRoot, "tools/patched/wow.export.exe");
const resolved = await resolveWowExportExecutable({
projectRoot,
environment: { WOW_EXPORT_BIN: "tools/patched/wow.export.exe" },
statFile: async (file) => {
assert.equal(file, expected);
return fileInfo;
},
});
assert.equal(resolved, expected);
});
test("resolveWowExportExecutable rejects a directory with actionable diagnostics", async () => {
const configured = path.resolve(projectRoot, "tools/not-an-executable");
await assert.rejects(
resolveWowExportExecutable({
projectRoot,
environment: { WOW_EXPORT_BIN: configured },
statFile: async () => ({ isFile: () => false }),
}),
(error) => {
assert.equal(error.code, "WOW_EXPORT_AUTOMATION_UNAVAILABLE");
assert.match(error.message, /path exists but is not a file/);
assert.match(error.message, /Correct or unset that variable/);
assert.match(error.message, /No export was started and no placeholder assets were created/);
for (const flag of WOW_EXPORT_REQUIRED_FLAGS) assert.ok(error.message.includes(flag));
return true;
},
);
});
test("resolveWowExportExecutable reports the exact missing default path", async () => {
const expected = defaultWowExportExecutable(projectRoot);
await assert.rejects(
resolveWowExportExecutable({
projectRoot,
environment: {},
statFile: async () => {
const error = new Error("missing");
error.code = "ENOENT";
throw error;
},
}),
(error) => {
assert.ok(error.message.includes(expected));
assert.match(error.message, /set WOW_EXPORT_BIN/);
assert.match(error.message, /stock GUI-only wow\.export executable is not a drop-in replacement/);
return true;
},
);
});
test("runWowExporter supplies the non-updating automation invocation", async () => {
const executable = path.resolve(projectRoot, "tools/wow.export.exe");
let invocation;
const spawn = (file, args, options) => {
invocation = { file, args, options };
const child = new EventEmitter();
queueMicrotask(() => child.emit("exit", 0, null));
return child;
};
const result = await runWowExporter(["--export-dungeon", "--recipe", "fixture.json"], {
projectRoot,
environment: { WOW_EXPORT_BIN: executable },
statFile: async () => fileInfo,
spawn,
});
assert.equal(result, executable);
assert.deepEqual(invocation.args, ["--disable-auto-update", "--export-dungeon", "--recipe", "fixture.json"]);
assert.equal(invocation.options.cwd, path.dirname(executable));
assert.equal(invocation.options.windowsHide, true);
});
test("runWowExporter identifies an incompatible executable after a failed launch", async () => {
const executable = path.resolve(projectRoot, "tools/wow.export.exe");
const spawn = () => {
const child = new EventEmitter();
queueMicrotask(() => child.emit("exit", 2, null));
return child;
};
await assert.rejects(
runWowExporter(["--export-creatures"], {
projectRoot,
environment: { WOW_EXPORT_BIN: executable },
statFile: async () => fileInfo,
spawn,
}),
(error) => {
assert.match(error.message, /process exited with code 2/);
assert.match(error.message, /HealerMan-patched build/);
assert.match(error.message, /No placeholder assets were created/);
return true;
},
);
});