mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 15:24:52 +09:00
Cover the create-scenario command handler and module loading
Adds tests for handleCreateScenarioCommand using a fake Factorio install with the test scenario as freeplay, for loadModules skipping plugins without a module and rejecting a name clash with a bundled module, and an integration test running clusteriohost create-scenario. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
c419f3e9b2
commit
1072e5f1de
3 files changed
+128
-1
No files matched your search
@@ -5,7 +5,9 @@ const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { createScenario } = require("@clusterio/host/dist/node/src/create_scenario");
|
||||
const {
|
||||
createScenario, createScenarioCommand, handleCreateScenarioCommand,
|
||||
} = require("@clusterio/host/dist/node/src/create_scenario");
|
||||
const { SaveModule, PatchInfo } = require("@clusterio/host/dist/node/src/patch");
|
||||
|
||||
|
||||
@@ -90,4 +92,87 @@ describe("host/create_scenario", function() {
|
||||
new Error("Unable to patch save, unknown scenario (3acc3be3861144e55604f5ac2f2555071885ebc4)")
|
||||
);
|
||||
});
|
||||
|
||||
describe("createScenarioCommand()", function() {
|
||||
it("should define the output positional and options", function() {
|
||||
const positionals = [];
|
||||
const options = [];
|
||||
const yargs = {
|
||||
positional(name) { positionals.push(name); return yargs; },
|
||||
option(name) { options.push(name); return yargs; },
|
||||
};
|
||||
createScenarioCommand(yargs);
|
||||
assert.deepEqual(positionals, ["output"]);
|
||||
assert.deepEqual(options, ["scenario", "factorio-version", "plugins"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleCreateScenarioCommand()", function() {
|
||||
const factorioDir = path.join(tempDir, "factorio");
|
||||
const scenario = path.join(tempDir, "scenario");
|
||||
let hostConfig;
|
||||
let pluginInfos;
|
||||
before(async function() {
|
||||
// Fake install with the test scenario as freeplay
|
||||
await fs.cp(path.join("test", "file", "factorio", "0.1.2"), factorioDir, { recursive: true });
|
||||
const freeplay = path.join(factorioDir, "data", "base", "scenarios", "freeplay");
|
||||
await fs.cp(scenario, freeplay, { recursive: true });
|
||||
pluginInfos = await lib.loadPluginInfos(new Map([
|
||||
["research_sync", path.resolve("plugins/research_sync")],
|
||||
["test_plugin", path.resolve("test/file/test_plugin")],
|
||||
]));
|
||||
lib.addPluginConfigFields(pluginInfos);
|
||||
hostConfig = new lib.HostConfig("host", { "host.factorio_directory": factorioDir });
|
||||
});
|
||||
|
||||
it("should patch freeplay with the enabled plugins by default", async function() {
|
||||
const output = path.join(tempDir, "default");
|
||||
await handleCreateScenarioCommand({ output, factorioVersion: "latest" }, hostConfig, pluginInfos);
|
||||
const files = await readDir(output);
|
||||
assert.equal(files.get("scenario.lua"), scenarioFiles.get("scenario.lua"));
|
||||
const info = JSON.parse(files.get("clusterio.json"));
|
||||
assert.deepEqual(info.modules.map(m => m.name), ["clusterio", "research_sync"]);
|
||||
});
|
||||
|
||||
it("should skip plugins disabled in the host config", async function() {
|
||||
const output = path.join(tempDir, "disabled");
|
||||
hostConfig.set("research_sync.load_plugin", false);
|
||||
try {
|
||||
await handleCreateScenarioCommand({ output, factorioVersion: "latest" }, hostConfig, pluginInfos);
|
||||
} finally {
|
||||
hostConfig.set("research_sync.load_plugin", true);
|
||||
}
|
||||
const info = JSON.parse((await readDir(output)).get("clusterio.json"));
|
||||
assert.deepEqual(info.modules.map(m => m.name), ["clusterio"]);
|
||||
});
|
||||
|
||||
it("should use the given scenario and plugins", async function() {
|
||||
const output = path.join(tempDir, "selected");
|
||||
await handleCreateScenarioCommand(
|
||||
{ output, scenario, plugins: ["research_sync"] }, hostConfig, pluginInfos
|
||||
);
|
||||
const info = JSON.parse((await readDir(output)).get("clusterio.json"));
|
||||
assert.deepEqual(info.modules.map(m => m.name), ["clusterio", "research_sync"]);
|
||||
});
|
||||
|
||||
it("should throw on unknown plugin", async function() {
|
||||
await assert.rejects(
|
||||
handleCreateScenarioCommand(
|
||||
{ output: path.join(tempDir, "unknown_plugin"), scenario, plugins: ["nope"] },
|
||||
hostConfig,
|
||||
pluginInfos,
|
||||
),
|
||||
new Error("Plugin nope is not in the plugin list")
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw on invalid Factorio version", async function() {
|
||||
await assert.rejects(
|
||||
handleCreateScenarioCommand(
|
||||
{ output: path.join(tempDir, "bad_version"), factorioVersion: "1..2" }, hostConfig, pluginInfos
|
||||
),
|
||||
new Error("Invalid Factorio version 1..2")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -240,6 +240,35 @@ describe("host/patch", function() {
|
||||
assert.deepEqual([...modules.keys()], ["research_sync", "clusterio"]);
|
||||
assert(modules.get("research_sync").files.has("modules/research_sync/sync.lua"));
|
||||
});
|
||||
it("should skip plugins without a module", async function() {
|
||||
const pluginInfos = await lib.loadPluginInfos(
|
||||
new Map([["test_plugin", path.resolve("test/file/test_plugin")]])
|
||||
);
|
||||
const modules = await patch.loadModules(pluginInfos);
|
||||
assert.deepEqual([...modules.keys()], ["clusterio"]);
|
||||
});
|
||||
it("should throw on a plugin module named like a bundled module", async function() {
|
||||
const pluginDir = path.join("temp", "test", "clusterio_plugin");
|
||||
await fs.mkdir(path.join(pluginDir, "module"), { recursive: true });
|
||||
await fs.writeFile(path.join(pluginDir, "package.json"), "{}");
|
||||
await fs.writeFile(path.join(pluginDir, "module", "module.json"), "{}");
|
||||
await assert.rejects(
|
||||
patch.loadModules([{ name: "clusterio", version: "1.0.0", requirePath: path.resolve(pluginDir) }]),
|
||||
new Error("Module with name clusterio already exists in a plugin")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("class SaveModule", function() {
|
||||
describe("static fromPlugin()", function() {
|
||||
it("should load the module of the plugin", async function() {
|
||||
const [info] = await lib.loadPluginInfos(
|
||||
new Map([["research_sync", path.resolve("plugins/research_sync")]])
|
||||
);
|
||||
const pluginModule = await patch.SaveModule.fromPlugin({ info });
|
||||
assert.equal(pluginModule.info.name, "research_sync");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("patch()", function() {
|
||||
|
||||
@@ -257,6 +257,19 @@ describe("Integration of Clusterio", function() {
|
||||
});
|
||||
|
||||
describe("clusteriohost", function() {
|
||||
describe("create-scenario", function() {
|
||||
it("should create a patched scenario", async function() {
|
||||
slowTest(this);
|
||||
requiresFactorio(this);
|
||||
const output = path.join("temp", "test", "patched-scenario");
|
||||
await fs.rm(output, { recursive: true, force: true });
|
||||
await execHost("create-scenario patched-scenario --plugins research_sync");
|
||||
const control = await fs.readFile(path.join(output, "control.lua"), "utf8");
|
||||
assert(control.includes('require("modules/research_sync/sync")'));
|
||||
await fs.access(path.join(output, "scenario.lua"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("hostUpdateEventHandler()", function() {
|
||||
it("should trigger when a new host is added", async function() {
|
||||
slowTest(this);
|
||||
|
||||
Reference in new issue
Block a user