Files
Hornwitser 5dcaca4d0b Migrate to ECMAScript Modules
Migrate the usage of CommonJS specific code and imports to ESM.  Roughly
summarised this:
- Changes all require() calls to import statement or expressions.
- Changes usage of module.exports to export statements.
- Replaces require.resolve with import.meta.resolve.
- Replaces conditional imports with conditional subpath imports.
- Replaces module === require.main with import.meta.main.
- Adds the full filename with extention to all relative imports.
- Changes all usage of __dirname and __filename to their import.meta
  equivalents.
- Sets "type": "module" in package.json files.
- Removes usage of "use strict".
- Adds .ts an an alias of .js for the webpack build.

Due to differences in how require and import resolves files the plugin
entrypoints will have to include the filename and extension after this
migration in order to work.
2026-09-11 22:43:57 +02:00

532 lines
21 KiB
JavaScript

import assert from "node:assert/strict";
import * as lib from "@clusterio/lib";
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
describe("lib/data/version", function() {
describe("isVersionEquality()", function() {
it("should correctly validate input strings", function() {
const valid = ["<", "<=", "=", ">=", ">"];
for (const test of valid) {
assert.equal(lib.isVersionEquality(test), true, test);
}
const invalid = ["==", "!=", "<>", ""];
for (const test of invalid) {
assert.equal(lib.isVersionEquality(test), false, test);
}
});
});
describe("normaliseSourceVersion()", function() {
it("should normalise lenient version strings the way the game reads them", function() {
// Major and minor required, patch optional and defaulting to 0.
assert.equal(lib.normaliseSourceVersion("1.1"), "1.1.0");
assert.equal(lib.normaliseSourceVersion("1.1.50"), "1.1.50");
assert.equal(lib.normaliseSourceVersion("0.18"), "0.18.0");
// Leading whitespace and zeros are dropped.
assert.equal(lib.normaliseSourceVersion(" 1.1"), "1.1.0");
assert.equal(lib.normaliseSourceVersion("01.02.03"), "1.2.3");
assert.equal(lib.normaliseSourceVersion("1. 1. 50"), "1.1.50");
// Anything after the patch (or a non-numeric patch) is ignored.
assert.equal(lib.normaliseSourceVersion("1.1.50-beta"), "1.1.50");
assert.equal(lib.normaliseSourceVersion("1.1.x"), "1.1.0");
assert.equal(lib.normaliseSourceVersion("1.1.50.60"), "1.1.50");
});
it("should return undefined when no major.minor can be read", function() {
const invalid = ["1", "", "latest", "abc", ".1.1", "x.y"];
for (const test of invalid) {
assert.equal(lib.normaliseSourceVersion(test), undefined, test);
}
});
});
describe("normaliseMajorMinorVersion()", function() {
it("should return the major.minor", function() {
assert.equal(lib.normaliseMajorMinorVersion("1.1"), "1.1");
assert.equal(lib.normaliseMajorMinorVersion("1.1.50"), "1.1");
assert.equal(lib.normaliseMajorMinorVersion("0.18.0"), "0.18");
});
});
describe("isMajorMinorVersion()", function() {
it("should correctly validate input strings", function() {
const valid = ["1.1", "0.18", "2.0", "10.20"];
const invalid = ["1", "1.1.0", "1.1.50", "latest", "1.", ".1", ""];
for (const version of valid) {
assert(lib.isMajorMinorVersion(version), `${version} should be valid`);
}
for (const version of invalid) {
assert(!lib.isMajorMinorVersion(version), `${version} should be invalid`);
}
});
});
describe("integerMajorMinorVersion()", function() {
it("should sort versions lexicographically", function() {
let unsortedVersions = ["1.0", "1.1", "0.1", "3.0", "1.2", "0.3", "2.1"];
let sortedVersions = ["0.1", "0.3", "1.0", "1.1", "1.2", "2.1", "3.0"];
unsortedVersions.sort((a, b) => lib.integerMajorMinorVersion(a) - lib.integerMajorMinorVersion(b));
assert.deepEqual(unsortedVersions, sortedVersions);
});
});
describe("isFullVersion()", function() {
it("should correctly validate input strings", function() {
const valid = ["0.12.0", "0.13.1", "0.17.99", "00.000.0001", "1.1.110"];
for (const test of valid) {
assert.equal(lib.isFullVersion(test), true, test);
}
const invalid = ["0.12", "0.19", "1.0", "1.0.0.0", "0", "", "latest"];
for (const test of invalid) {
assert.equal(lib.isFullVersion(test), false, test);
}
});
});
describe("integerFullVersion()", function() {
it("should sort versions lexicographically", function() {
let unsortedVersions = ["1.0.0", "1.1.0", "0.1.0", "3.0.0", "1.2.0", "0.3.1", "0.3.3", "2.1.1", "0.0.1"];
let sortedVersions = ["0.0.1", "0.1.0", "0.3.1", "0.3.3", "1.0.0", "1.1.0", "1.2.0", "2.1.1", "3.0.0"];
unsortedVersions.sort((a, b) => lib.integerFullVersion(a) - lib.integerFullVersion(b));
assert.deepEqual(unsortedVersions, sortedVersions);
});
});
describe("normaliseFullVersion()", function() {
it("should normalise accepted versions", function() {
assert.equal(lib.normaliseFullVersion("0.13"), "0.13.0");
assert.equal(lib.normaliseFullVersion("0.13.0"), "0.13.0");
assert.equal(lib.normaliseFullVersion("0.13.1"), "0.13.1");
assert.equal(lib.normaliseFullVersion("1.1"), "1.1.0");
assert.equal(lib.normaliseFullVersion("1.1.0"), "1.1.0");
assert.equal(lib.normaliseFullVersion("1.1.1"), "1.1.1");
assert.equal(lib.normaliseFullVersion("2.0"), "2.0.0");
assert.equal(lib.normaliseFullVersion("2.0.0"), "2.0.0");
assert.equal(lib.normaliseFullVersion("2.0.1"), "2.0.1");
});
});
describe("isPartialVersion()", function() {
it("should correctly validate input strings", function() {
const valid = [
"0.13", "0.14", "0.15", "0.16", "0.17", "0.18", "1.0", "1.1", "2.0",
"0.12.0", "0.13.1", "0.17.99", "00.000.0001", "1.1.110",
];
for (const test of valid) {
assert.equal(lib.isPartialVersion(test), true, test);
}
const invalid = ["1.0.0.0", "0", "", "latest"];
for (const test of invalid) {
assert.equal(lib.isPartialVersion(test), false, test);
}
});
});
describe("integerPartialVersion()", function() {
it("should sort versions lexicographically", function() {
let unsortedVersions = ["1.0", "1.1", "0.1", "3.0", "1.2", "0.3", "2.1"];
let sortedVersions = ["0.1", "0.3", "1.0", "1.1", "1.2", "2.1", "3.0"];
unsortedVersions.sort((a, b) => lib.integerPartialVersion(a) - lib.integerPartialVersion(b));
assert.deepEqual(unsortedVersions, sortedVersions);
});
});
describe("isTargetVersion()", function() {
it("should correctly validate input strings", function() {
const valid = [
"0.13", "0.14", "0.15", "0.16", "0.17", "0.18", "1.0", "1.1", "2.0",
"0.12.0", "0.13.1", "0.17.99", "00.000.0001", "1.1.110", "latest",
];
for (const test of valid) {
assert.equal(lib.isTargetVersion(test), true, test);
}
const invalid = ["1.0.0.0", "0", ""];
for (const test of invalid) {
assert.equal(lib.isTargetVersion(test), false, test);
}
});
});
describe("class ModVersionEquality", function() {
const tests = testMatrix(
["<", "<=", "=", ">=", ">"],
["0.18", "1.0", "1.0.0", "1.1.1"],
);
describe("constructor", function() {
it("should be round trip json serialisable", function() {
testRoundTripJsonSerialisable(lib.ModVersionEquality, tests);
});
it("should be constructible", function() {
for (const [eq, ver] of tests) {
const test = `${eq} ${ver}`;
const version = new lib.ModVersionEquality(eq, ver);
assert.equal(version.equality, eq, test);
assert.equal(version.version, ver, test);
assert.equal(version.integerVersion, lib.integerPartialVersion(ver), test);
}
});
it("should throw when given an invalid equality", function() {
assert.throws(() => new lib.ModVersionEquality("==", "1.0.0"));
});
it("should throw when given an invalid version", function() {
assert.throws(() => new lib.ModVersionEquality("=", "1.0.0.0"));
});
});
describe("testIntegerVersion()", function() {
it("should test for less than", function() {
const version = new lib.ModVersionEquality("<", "0.0.100");
assert.equal(version.testIntegerVersion(90), true);
assert.equal(version.testIntegerVersion(100), false);
assert.equal(version.testIntegerVersion(110), false);
});
it("should test for less than equal", function() {
const version = new lib.ModVersionEquality("<=", "0.0.100");
assert.equal(version.testIntegerVersion(90), true);
assert.equal(version.testIntegerVersion(100), true);
assert.equal(version.testIntegerVersion(110), false);
});
it("should test for equal", function() {
const version = new lib.ModVersionEquality("=", "0.0.100");
assert.equal(version.testIntegerVersion(90), false);
assert.equal(version.testIntegerVersion(100), true);
assert.equal(version.testIntegerVersion(110), false);
});
it("should test for greater than equal", function() {
const version = new lib.ModVersionEquality(">=", "0.0.100");
assert.equal(version.testIntegerVersion(90), false);
assert.equal(version.testIntegerVersion(100), true);
assert.equal(version.testIntegerVersion(110), true);
});
it("should test for greater than", function() {
const version = new lib.ModVersionEquality(">", "0.0.100");
assert.equal(version.testIntegerVersion(90), false);
assert.equal(version.testIntegerVersion(100), false);
assert.equal(version.testIntegerVersion(110), true);
});
it("should throw if the equality is invalid (unreachable)", function() {
const version = new lib.ModVersionEquality(">", "0.0.100");
version.equality = "==";
assert.throws(() => version.testIntegerVersion(100));
});
});
describe("testVersion()", function() {
it("should test for less than", function() {
const version = new lib.ModVersionEquality("<", "1.1.1");
assert.equal(version.testVersion("1.0"), true);
assert.equal(version.testVersion("1.1"), true);
assert.equal(version.testVersion("1.1.1"), false);
assert.equal(version.testVersion("1.1.2"), false);
assert.equal(version.testVersion("1.2"), false);
});
it("should test for less than equal", function() {
const version = new lib.ModVersionEquality("<=", "1.1.1");
assert.equal(version.testVersion("1.0"), true);
assert.equal(version.testVersion("1.1"), true);
assert.equal(version.testVersion("1.1.1"), true);
assert.equal(version.testVersion("1.1.2"), false);
assert.equal(version.testVersion("1.2"), false);
});
it("should test for equal", function() {
const version = new lib.ModVersionEquality("=", "1.1.1");
assert.equal(version.testVersion("1.0"), false);
assert.equal(version.testVersion("1.1"), false);
assert.equal(version.testVersion("1.1.1"), true);
assert.equal(version.testVersion("1.1.2"), false);
assert.equal(version.testVersion("1.2"), false);
});
it("should test for greater than equal", function() {
const version = new lib.ModVersionEquality(">=", "1.1.1");
assert.equal(version.testVersion("1.0"), false);
assert.equal(version.testVersion("1.1"), false);
assert.equal(version.testVersion("1.1.1"), true);
assert.equal(version.testVersion("1.1.2"), true);
assert.equal(version.testVersion("1.2"), true);
});
it("should test for greater than", function() {
const version = new lib.ModVersionEquality(">", "1.1.1");
assert.equal(version.testVersion("1.0"), false);
assert.equal(version.testVersion("1.1"), false);
assert.equal(version.testVersion("1.1.1"), false);
assert.equal(version.testVersion("1.1.2"), true);
assert.equal(version.testVersion("1.2"), true);
});
it("should throw if the equality is invalid (unreachable)", function() {
const version = new lib.ModVersionEquality(">", "1.1.1");
version.equality = "==";
assert.throws(() => version.testInteger("1.0.0"));
});
});
describe("toString()", function() {
it("should be convertible to string", function() {
for (const [eq, ver] of tests) {
const expected = `${eq} ${ver}`;
const version = new lib.ModVersionEquality(eq, ver);
assert.equal(version.toString(), expected);
}
});
});
describe("fromString()", function() {
it("should be constructable from string", function() {
for (const [eq, ver] of tests) {
const test = `${eq} ${ver}`;
const version = lib.ModVersionEquality.fromString(test);
assert.equal(version.equality, eq, test);
assert.equal(version.version, ver, test);
assert.equal(version.integerVersion, lib.integerPartialVersion(ver), test);
}
});
it("should error for invalid equalities", function() {
const equalities = ["==", "!=", "<>", ""];
for (const eq of equalities) {
const test = `${eq} 1.0.0`;
assert.throws(() => lib.ModVersionEquality.fromString(test), undefined, test);
}
});
it("should error for invalid versions", function() {
const versions = ["1.0.0.0", "0", "", "latest"];
for (const ver of versions) {
const test = `= ${ver}`;
assert.throws(() => lib.ModVersionEquality.fromString(test), undefined, test);
}
});
});
describe("fromParts()", function() {
it("should be constructable from parts", function() {
for (const [eq, ver] of tests) {
const test = `${eq} ${ver}`;
const version = lib.ModVersionEquality.fromParts(eq, ver);
assert.equal(version.equality, eq, test);
assert.equal(version.version, ver, test);
assert.equal(version.integerVersion, lib.integerPartialVersion(ver), test);
}
});
it("should error for invalid equalities", function() {
const equalities = ["==", "!=", "<>", ""];
for (const eq of equalities) {
assert.throws(() => lib.ModVersionEquality.fromParts(eq, "1.0.0"), undefined, eq);
}
});
it("should error for invalid versions", function() {
const versions = ["1.0.0.0", "0", "", "latest"];
for (const ver of versions) {
assert.throws(() => lib.ModVersionEquality.fromParts("=", ver), undefined, ver);
}
});
});
});
describe("class ModVersionRange", function() {
describe("constructor", function() {
it("should be constructable", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.minVersion.equality, ">=");
assert.equal(range.minVersion.version, "1.0.0");
assert.equal(range.maxVersion.equality, "<");
assert.equal(range.maxVersion.version, "2.0.0");
});
it("should be default constructable", function() {
const range = new lib.ModVersionRange();
assert.equal(range.minVersion.equality, ">=");
assert.equal(range.minVersion.version, "0.0.0");
assert.equal(range.maxVersion.equality, "<=");
assert.equal(range.maxVersion.version, "65535.65535.65535");
});
it("should throw if invalid equality is given for min version", function() {
assert.throws(() => new lib.ModVersionRange(
new lib.ModVersionEquality("<", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
));
assert.throws(() => new lib.ModVersionRange(
new lib.ModVersionEquality("<=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
));
});
it("should throw if invalid equality is given for max version", function() {
assert.throws(() => new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality(">", "2.0.0"),
));
assert.throws(() => new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality(">=", "2.0.0"),
));
});
});
describe("valid", function() {
it("should be true for valid ranges", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.valid, true);
const defaultRange = new lib.ModVersionRange();
assert.equal(defaultRange.valid, true);
});
it("should be false for invalid ranges", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "2.0.0"),
new lib.ModVersionEquality("<", "1.0.0"),
);
assert.equal(range.valid, false);
const rangeImpossible = new lib.ModVersionRange(
new lib.ModVersionEquality("=", "1.0.0"),
new lib.ModVersionEquality("=", "2.0.0"),
);
assert.equal(rangeImpossible.valid, false);
});
});
describe("invalidate()", function() {
it("should result in the range becoming invalid", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
range.invalidate();
assert.equal(range.valid, false);
const defaultRange = new lib.ModVersionRange();
defaultRange.invalidate();
assert.equal(defaultRange.valid, false);
});
});
describe("testIntegerVersion()", function() {
it("should return true when in range", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "0.0.100"),
new lib.ModVersionEquality("<", "0.0.200"),
);
assert.equal(range.testIntegerVersion(100), true);
assert.equal(range.testIntegerVersion(199), true);
});
it("should return false when out of range", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "0.0.100"),
new lib.ModVersionEquality("<", "0.0.200"),
);
assert.equal(range.testIntegerVersion(99), false);
assert.equal(range.testIntegerVersion(200), false);
});
it("should handle exact matches", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality("=", "0.0.100"),
new lib.ModVersionEquality("=", "0.0.100"),
);
assert.equal(range.testIntegerVersion(99), false);
assert.equal(range.testIntegerVersion(100), true);
assert.equal(range.testIntegerVersion(101), false);
});
});
describe("testVersion()", function() {
it("should return true when in range", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.0.0"), true);
assert.equal(range.testVersion("1.9.9"), true);
});
it("should return false when out of range", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("0.9.9"), false);
assert.equal(range.testVersion("2.0.0"), false);
});
it("should handle exact matches", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality("=", "1.0.0"),
new lib.ModVersionEquality("=", "1.0.0"),
);
assert.equal(range.testVersion("0.9.9"), false);
assert.equal(range.testVersion("1.0.0"), true);
assert.equal(range.testVersion("1.0.1"), false);
});
});
describe("combineVersion()", function() {
it("should handle merge with less than", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.1"), true);
assert.equal(range.testVersion("1.5"), true);
range.combineVersion(new lib.ModVersionEquality("<", "1.2"));
assert.equal(range.testVersion("1.1"), true);
assert.equal(range.testVersion("1.5"), false);
assert.equal(range.valid, true);
range.combineVersion(new lib.ModVersionEquality("<", "0.5"));
assert.equal(range.valid, false);
});
it("should handle merge with less than equal", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.2"), true);
assert.equal(range.testVersion("1.5"), true);
range.combineVersion(new lib.ModVersionEquality("<=", "1.2"));
assert.equal(range.testVersion("1.2"), true);
assert.equal(range.testVersion("1.5"), false);
assert.equal(range.valid, true);
range.combineVersion(new lib.ModVersionEquality("<=", "0.5"));
assert.equal(range.valid, false);
});
it("should handle merge with equal", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.2"), true);
assert.equal(range.testVersion("1.5"), true);
range.combineVersion(new lib.ModVersionEquality("=", "1.2"));
assert.equal(range.testVersion("1.2"), true);
assert.equal(range.testVersion("1.5"), false);
assert.equal(range.valid, true);
range.combineVersion(new lib.ModVersionEquality("=", "0.5"));
assert.equal(range.valid, false);
});
it("should handle merge with greater than equal", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.1"), true);
assert.equal(range.testVersion("1.5"), true);
range.combineVersion(new lib.ModVersionEquality(">=", "1.2"));
assert.equal(range.testVersion("1.1"), false);
assert.equal(range.testVersion("1.5"), true);
assert.equal(range.valid, true);
range.combineVersion(new lib.ModVersionEquality(">=", "2.5"));
assert.equal(range.valid, false);
});
it("should handle merge with greater than", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
assert.equal(range.testVersion("1.2"), true);
assert.equal(range.testVersion("1.5"), true);
range.combineVersion(new lib.ModVersionEquality(">", "1.2"));
assert.equal(range.testVersion("1.2"), false);
assert.equal(range.testVersion("1.5"), true);
assert.equal(range.valid, true);
range.combineVersion(new lib.ModVersionEquality(">", "2.5"));
assert.equal(range.valid, false);
});
it("should throw if the equality is invalid (unreachable)", function() {
const range = new lib.ModVersionRange(
new lib.ModVersionEquality(">=", "1.0.0"),
new lib.ModVersionEquality("<", "2.0.0"),
);
const version = new lib.ModVersionEquality(">", "1.2");
version.equality = "==";
assert.throws(() => range.combineVersion(version));
});
});
});
});