Move Factorio server implementation to host

Move Factorio related code in lib that's only used by the host into the
host package.
This commit is contained in:
Hornwitser committed 2023-07-28 16:03:29 +02:00
1 parent bc574ee1cb
commit 6af25e085c
13 files changed
+95 -100

No files matched your search

@@ -2,20 +2,21 @@
const assert = require("assert").strict;
const path = require("path");
const lib = require("@clusterio/lib");
const { FactorioServer } = require("@clusterio/host/src/server");
const { _exportLocale } = require("@clusterio/host/src/export");
describe("lib/factorio/export", function() {
describe("host/src/export", function() {
describe("exportLocale()", function() {
let testServer;
before(async function() {
let writePath = path.join("temp", "test", "server");
testServer = new lib.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
testServer = new FactorioServer(path.join("test", "file", "factorio"), writePath, {});
await testServer.init();
});
it("returns a flattened mapping with locale definitions", async function() {
let locale = await lib._exportLocale(testServer, new Map(), ["base"], "en");
let locale = await _exportLocale(testServer, new Map(), ["base"], "en");
assert.deepEqual(locale, new Map([["test.key-a", "1"], ["test.key-b", "2"]]));
});
});
@@ -4,10 +4,10 @@ const fs = require("fs-extra");
const JSZip = require("jszip");
const path = require("path");
const lib = require("@clusterio/lib");
const patch = require("@clusterio/host/src/patch");
describe("lib/factorio", function() {
describe("host/patch", function() {
describe("generateLoader()", function() {
let reference = [
"-- Auto generated scenario module loader created by Clusterio",
@@ -38,7 +38,7 @@ describe("lib/factorio", function() {
};
it("should produce output matching the reference", function() {
assert.equal(lib._generateLoader(patchInfo), reference);
assert.equal(patch._generateLoader(patchInfo), reference);
});
});
@@ -48,7 +48,7 @@ describe("lib/factorio", function() {
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "b", version: "1.0.0", dependencies: {} },
];
lib._reorderDependencies(modules);
patch._reorderDependencies(modules);
assert(modules[0].name === "b", "Dependency was not reorederd");
});
it("should throw on invalid version", function() {
@@ -56,7 +56,7 @@ describe("lib/factorio", function() {
{ name: "a", version: "foo", dependencies: {} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Invalid version 'foo' for module a")
);
});
@@ -65,7 +65,7 @@ describe("lib/factorio", function() {
{ name: "a", version: "1.0.0", dependencies: {"b": "invalid"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Invalid version range 'invalid' for dependency b on module a")
);
});
@@ -74,7 +74,7 @@ describe("lib/factorio", function() {
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Missing dependency b for module a")
);
modules = [
@@ -83,7 +83,7 @@ describe("lib/factorio", function() {
{ name: "c", version: "1.0.0", dependencies: {"d": "*"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Missing dependency d for module c")
);
});
@@ -93,7 +93,7 @@ describe("lib/factorio", function() {
{ name: "b", version: "1.0.0", dependencies: {"a": ">=2"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Module b requires a >=2")
);
});
@@ -103,7 +103,7 @@ describe("lib/factorio", function() {
{ name: "b", version: "1.0.0", dependencies: {"a": "*"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Module dependency loop detected: a -> b -> a")
);
modules = [
@@ -113,7 +113,7 @@ describe("lib/factorio", function() {
{ name: "c", version: "1.0.0", dependencies: {"a": "*"} },
];
assert.throws(
() => lib._reorderDependencies(modules),
() => patch._reorderDependencies(modules),
new Error("Module dependency loop detected: b -> c -> a -> b")
);
});
@@ -153,7 +153,7 @@ describe("lib/factorio", function() {
}
let success = false;
try {
lib._reorderDependencies(modules);
patch._reorderDependencies(modules);
success = true;
} catch (err) { }
if (success) {
@@ -176,7 +176,7 @@ describe("lib/factorio", function() {
await fs.outputFile(zipPath, await zip.generateAsync({ type: "nodebuffer" }));
await assert.rejects(
lib.patch(zipPath, []),
patch.patch(zipPath, []),
new Error("Unable to patch save, unknown scenario (3acc3be3861144e55604f5ac2f2555071885ebc4)")
);
});
@@ -4,23 +4,24 @@ const events = require("events");
const fs = require("fs-extra");
const path = require("path");
const hostServer = require("@clusterio/host/src/server");
const lib = require("@clusterio/lib");
const { wait } = lib;
const { testLines } = require("./lines");
const { testLines } = require("../lib/factorio/lines");
describe("lib/factorio/server", function() {
describe("host/server", function() {
describe("_getVersion()", function() {
it("should get the version from a changelog", async function() {
let version = await lib._getVersion(path.join("test", "file", "changelog-test.txt"));
let version = await hostServer._getVersion(path.join("test", "file", "changelog-test.txt"));
assert.equal(version, "0.1.1");
});
it("should return null if unable to find the version", async function() {
let version = await lib._getVersion(path.join("test", "file", "changelog-bad.txt"));
let version = await hostServer._getVersion(path.join("test", "file", "changelog-bad.txt"));
assert.equal(version, null);
});
it("should return null if file does not exist", async function() {
let version = await lib._getVersion(path.join("test", "file", "does-not-exist.txt"));
let version = await hostServer._getVersion(path.join("test", "file", "does-not-exist.txt"));
assert.equal(version, null);
});
});
@@ -28,7 +29,7 @@ describe("lib/factorio/server", function() {
describe("_versionOrder()", function() {
it("should sort an array of versions", function() {
let versions = ["1.2.3", "0.1.4", "0.1.2", "1.2.3", "0.1.5", "1.10.2"];
versions.sort(lib._versionOrder);
versions.sort(hostServer._versionOrder);
assert.deepEqual(
versions,
["1.10.2", "1.2.3", "1.2.3", "0.1.5", "0.1.4", "0.1.2"]
@@ -39,46 +40,46 @@ describe("lib/factorio/server", function() {
describe("_findVersion()", function() {
it("should find a given install dir with latest as target", async function() {
let installDir = path.join("test", "file", "factorio");
let [dir, version] = await lib._findVersion(installDir, "latest");
let [dir, version] = await hostServer._findVersion(installDir, "latest");
assert.equal(dir, path.join(installDir, "data"));
assert.equal(version, "0.1.1");
});
it("should find a given install dir with correct version as target", async function() {
let installDir = path.join("test", "file", "factorio");
let [dir, version] = await lib._findVersion(installDir, "0.1.1");
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
assert.equal(dir, path.join(installDir, "data"));
assert.equal(version, "0.1.1");
});
it("should reject if the install dir version does not match target version", async function() {
let installDir = path.join("test", "file", "factorio");
await assert.rejects(
lib._findVersion(installDir, "0.1.2"),
hostServer._findVersion(installDir, "0.1.2"),
new Error("Factorio version 0.1.2 was requested, but install directory contains 0.1.1")
);
});
it("should search given directory for latest Factorio install", async function() {
let installDir = path.join("test", "file");
let [dir, version] = await lib._findVersion(installDir, "latest");
let [dir, version] = await hostServer._findVersion(installDir, "latest");
assert.equal(dir, path.join(installDir, "factorio", "data"));
assert.equal(version, "0.1.1");
});
it("should search given directory for given Factorio install", async function() {
let installDir = path.join("test", "file");
let [dir, version] = await lib._findVersion(installDir, "0.1.1");
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
assert.equal(dir, path.join(installDir, "factorio", "data"));
assert.equal(version, "0.1.1");
});
it("should reject if no factorio install with the given version was found", async function() {
let installDir = path.join("test", "file");
await assert.rejects(
lib._findVersion(installDir, "0.1.2"),
hostServer._findVersion(installDir, "0.1.2"),
new Error("Unable to find Factorio version 0.1.2")
);
});
it("should reject if no factorio install was found", async function() {
let installDir = path.join("test", "file", "instances");
await assert.rejects(
lib._findVersion(installDir, "latest"),
hostServer._findVersion(installDir, "latest"),
new Error(`Unable to find any Factorio install in ${installDir}`)
);
});
@@ -86,7 +87,7 @@ describe("lib/factorio/server", function() {
describe("randomDynamicPort()", function() {
it("should return a port number", function() {
let port = lib._randomDynamicPort();
let port = hostServer._randomDynamicPort();
assert.equal(typeof port, "number");
assert(Number.isInteger(port));
assert(0 <= port && port < 2**16);
@@ -97,24 +98,24 @@ describe("lib/factorio/server", function() {
return (49152 <= port && port <= 65535);
}
for (let i=0; i < 20; i++) {
assert(validate(lib._randomDynamicPort()));
assert(validate(hostServer._randomDynamicPort()));
}
});
});
describe("generatePassword()", function() {
it("should return a string", async function() {
let password = await lib._generatePassword(1);
let password = await hostServer._generatePassword(1);
assert.equal(typeof password, "string");
});
it("should return a string of the given length", async function() {
let password = await lib._generatePassword(10);
let password = await hostServer._generatePassword(10);
assert.equal(password.length, 10);
});
it("should contain only a-z, A-Z, 0-9", async function() {
let password = await lib._generatePassword(10);
let password = await hostServer._generatePassword(10);
assert(/^[a-zA-Z0-9]+$/.test(password), `${password} failed test`);
});
});
@@ -123,7 +124,7 @@ describe("lib/factorio/server", function() {
it("should parse the test lines", function() {
for (let [line, reference] of testLines) {
reference.source = "test";
let output = lib._parseOutput(line, "test");
let output = hostServer._parseOutput(line, "test");
assert.deepEqual(output, reference);
}
});
@@ -131,12 +132,12 @@ describe("lib/factorio/server", function() {
describe("class FactorioServer", function() {
let writePath = path.join("temp", "test", "server");
let server = new lib.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
let server = new hostServer.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
describe("constructor()", function() {
it("should handle dashes in write path with strapPaths enabled", function() {
// eslint-disable-next-line no-new
new lib.FactorioServer(
new hostServer.FactorioServer(
path.join("test", "file", "factorio"),
path.join("temp", "test", "server-1"),
{ stripPaths: true }
+4 -3
View File
@@ -2,17 +2,18 @@
const assert = require("assert").strict;
const path = require("path");
const lib = require("@clusterio/lib");
const { _exportLocale } = require("@clusterio/host/src/export");
const { FactorioServer } = require("@clusterio/host/src/server");
describe("Integration of lib/factorio/export", function() {
describe("exportLocale()", function() {
it("returns a nested Map with base game locale information", async function() {
let writePath = path.join("temp", "test", "server");
let testServer = new lib.FactorioServer("factorio", writePath, {});
let testServer = new FactorioServer("factorio", writePath, {});
await testServer.init();
let locale = await lib._exportLocale(testServer, new Map(), ["base"], "en");
let locale = await _exportLocale(testServer, new Map(), ["base"], "en");
assert(locale instanceof Map, "locale is not a map");
assert.equal(locale.get("entity-name.fish"), "Fish");
+3 -3
View File
@@ -4,7 +4,7 @@ const fs = require("fs-extra");
const JSZip = require("jszip");
const path = require("path");
const lib = require("@clusterio/lib");
const { patch } = require("@clusterio/host/src/patch");
const { slowTest } = require("./index");
@@ -17,7 +17,7 @@ describe("Integration of lib/factorio/patch", function() {
let savePath = path.join("temp", "test", "integration", "saves", "test.zip");
it("should patch a freeplay game", async function() {
slowTest(this);
await lib.patch(savePath, [{
await patch(savePath, [{
name: "test",
version: "1.0.0",
dependencies: {},
@@ -39,7 +39,7 @@ describe("Integration of lib/factorio/patch", function() {
});
it("should remove old modules in a save", async function() {
slowTest(this);
await lib.patch(savePath, []);
await patch(savePath, []);
let zip = await JSZip.loadAsync(await fs.readFile(savePath));
assert.equal(zip.file("test/modules/test/test.lua"), null);
});
+4 -3
View File
@@ -5,15 +5,16 @@ const fs = require("fs-extra");
const path = require("path");
const lib = require("@clusterio/lib");
const { FactorioServer, _getVersion } = require("@clusterio/host/src/server");
const { logger } = lib;
const { slowTest } = require("./index");
describe("Integration of lib/factorio/server", function() {
describe("Integration of host/src/server", function() {
describe("_getVersion()", function() {
it("should get a version from factorio's changelog.txt", async function() {
let version = await lib._getVersion(path.join("factorio", "data", "changelog.txt"));
let version = await _getVersion(path.join("factorio", "data", "changelog.txt"));
if (!/^\d+\.\d+\.\d+$/.test(version)) {
assert.fail(`Detected version '${version}' does not followed the format x.y.z`);
}
@@ -22,7 +23,7 @@ describe("Integration of lib/factorio/server", function() {
describe("class FactorioServer", function() {
let writePath = path.join("temp", "test", "integration");
let server = new lib.FactorioServer("factorio", writePath, {});
let server = new FactorioServer("factorio", writePath, {});
let logFile;
before(async function() {