Add regression tests for #704 and #705 (#1060)

Covers the icon_size default of 64 in the export icon loaders and the
host recreating saves and script-output when an instance is assigned.
Both tests fail when the original fix is reverted.

Closes #710

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
BastiaanandClaude Opus 5.5 authored and GitHub committed 2026-10-08 20:57:00 +01:00
1 parent 839f9eb56c
commit ae6e25d1b9
4 files changed
+78 -10

No files matched your search

+4 -2
View File
@@ -160,7 +160,7 @@ async function loadSimpleIcon(
item: SimpleIconSpecification,
size: number,
iconCache: IconCache,
) {
): Promise<Image | null> {
let icon = await loadIcon(server, modVersions, item.icon, item.icon_size ?? 64, 0, iconCache);
if (icon) {
let iconScale = size / (item.icon_size ?? 64);
@@ -178,7 +178,7 @@ async function loadLayeredIcon(
item: LayeredIconSpecification,
size: number,
iconCache: IconCache,
) {
): Promise<Image> {
let baseLayerSize = (item.icons[0].icon_size || item.icon_size) ?? 64;
let icon = new Jimp({ width: size, height: size });
@@ -590,3 +590,5 @@ export async function exportData(server: FactorioServer) {
// For testing only
export const _exportLocale = exportLocale;
export const _loadSimpleIcon = loadSimpleIcon;
export const _loadLayeredIcon = loadLayeredIcon;
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

+42
View File
@@ -1,4 +1,5 @@
import assert from "node:assert/strict";
import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
@@ -236,6 +237,47 @@ describe("host/src/Host", function() {
});
});
});
describe(".handleInstanceAssignInternalRequest()", function() {
const instancesDir = path.join("temp", "test", "host_assign");
let host;
beforeEach(async function() {
await fs.rm(instancesDir, { recursive: true, force: true });
await fs.mkdir(instancesDir, { recursive: true });
const hostConfig = new lib.HostConfig("host", { "host.instances_directory": instancesDir });
const hostConnector = new HostConnector(hostConfig, []);
host = new Host(hostConnector, hostConfig, []);
host.send = () => {};
});
function assignRequest(id, name) {
const config = new lib.InstanceConfig("controller", { "instance.id": id, "instance.name": name });
return new lib.InstanceAssignInternalRequest(id, config.toRemote("host"));
}
it("creates the folders for a new instance", async function() {
await host.handleInstanceAssignInternalRequest(assignRequest(1, "new"));
const instancePath = path.join(instancesDir, "new");
assert.equal(host.discoveredInstances.get(1).path, instancePath);
await fs.access(path.join(instancePath, "saves"));
await fs.access(path.join(instancePath, "script-output"));
});
it("recreates missing folders for a discovered instance", async function() {
const instancePath = path.join(instancesDir, "existing");
await fs.mkdir(instancePath);
const configPath = path.join(instancePath, "instance.json");
host.discoveredInstances.set(2, {
path: instancePath,
config: new lib.InstanceConfig("host", {
...Host.instanceConfigWarning,
"instance.id": 2,
"instance.name": "existing",
}, configPath),
});
await host.handleInstanceAssignInternalRequest(assignRequest(2, "existing"));
await fs.access(path.join(instancePath, "saves"));
await fs.access(path.join(instancePath, "script-output"));
});
});
describe(".handleHostRestartRequest()", function() {
let mockHost;
beforeEach(function() {
+32 -8
View File
@@ -2,18 +2,18 @@ import assert from "node:assert/strict";
import path from "node:path";
import { FactorioServer } from "@clusterio/host/dist/node/src/server.js";
import { _exportLocale } from "@clusterio/host/dist/node/src/export.js";
import { _exportLocale, _loadLayeredIcon, _loadSimpleIcon } from "@clusterio/host/dist/node/src/export.js";
describe("host/src/export", function() {
describe("exportLocale()", function() {
let testServer;
before(async function() {
let writePath = path.join("temp", "test", "server");
testServer = new FactorioServer(path.join("test", "file", "factorio"), writePath, {});
await testServer.init();
});
let testServer;
before(async function() {
let writePath = path.join("temp", "test", "server");
testServer = new FactorioServer(path.join("test", "file", "factorio"), writePath, {});
await testServer.init();
});
describe("exportLocale()", function() {
it("returns a flattened mapping with locale definitions", async function() {
let locale = await _exportLocale(testServer, new Map(), ["base"], "en");
assert.deepEqual(locale, new Map([
@@ -28,4 +28,28 @@ describe("host/src/export", function() {
]));
});
});
// test-icon.png is a red 64px icon followed by a blue 32px mipmap
const red = 0xff0000ff;
describe("loadSimpleIcon()", function() {
it("defaults icon_size to 64", async function() {
const icon = await _loadSimpleIcon(
testServer, new Map(), { icon: "__base__/graphics/icons/test-icon.png" }, 32, new Map()
);
assert.equal(icon.bitmap.width, 32);
assert.equal(icon.bitmap.height, 32);
assert.equal(icon.getPixelColor(31, 16), red);
});
});
describe("loadLayeredIcon()", function() {
it("defaults icon_size to 64", async function() {
const icon = await _loadLayeredIcon(
testServer, new Map(), { icons: [{ icon: "__base__/graphics/icons/test-icon.png" }] }, 32, new Map()
);
assert.equal(icon.bitmap.width, 32);
assert.equal(icon.bitmap.height, 32);
assert.equal(icon.getPixelColor(0, 0), red);
assert.equal(icon.getPixelColor(31, 31), red);
});
});
});