mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Move BaseControllerPlugin to controller/src/BaseControllerPlugin.ts Move BaseInstancePlugin to host/src/BaseInstancePlugin.ts Move BaseControlPlugin to ctl/src/BaseCtlPlugin.ts Move BaseWebPlugin to web_ui/src/BaseWebPlugin.ts This solves the circular package dependency problem of the base plugins needing types that are available only in the dependencies to lib.
116 lines
3.8 KiB
JavaScript
116 lines
3.8 KiB
JavaScript
"use strict";
|
|
const assert = require("assert").strict;
|
|
const fs = require("fs-extra");
|
|
const path = require("path");
|
|
|
|
const lib = require("@clusterio/lib");
|
|
const { BaseControllerPlugin } = require("@clusterio/controller");
|
|
const { escapeRegExp } = lib;
|
|
|
|
|
|
describe("lib/plugin_loader", function() {
|
|
describe("loadPluginInfos()", function() {
|
|
let baseDir = path.join("temp", "test", "plugin");
|
|
let missingPlugin = path.join(baseDir, "missing_plugin");
|
|
let testPlugin = path.join(baseDir, "test_plugin");
|
|
let brokenPlugin = path.join(baseDir, "broken_plugin");
|
|
let invalidPlugin = path.join(baseDir, "invalid_plugin");
|
|
before(async function() {
|
|
async function writePlugin(pluginPath, infoName) {
|
|
await fs.outputFile(
|
|
path.join(pluginPath, "info.js"),
|
|
`module.exports.default = { name: "${infoName}" };`
|
|
);
|
|
await fs.outputFile(
|
|
path.join(pluginPath, "package.json"),
|
|
'{ "version": "0.0.1", "main":"info.js" }'
|
|
);
|
|
}
|
|
|
|
await writePlugin(testPlugin, "test");
|
|
await writePlugin(brokenPlugin, "broken");
|
|
await fs.outputFile(path.join(brokenPlugin, "info.js"), "Syntax Error");
|
|
await writePlugin(invalidPlugin, "wrong");
|
|
});
|
|
|
|
it("should throw on missing plugin", async function() {
|
|
await assert.rejects(
|
|
lib.loadPluginInfos(new Map([["missing", missingPlugin]]), []),
|
|
new RegExp(`^Error: PluginError: Cannot find module '${escapeRegExp(missingPlugin)}'`)
|
|
);
|
|
});
|
|
it("should load test plugin", async function() {
|
|
assert.deepEqual(
|
|
await lib.loadPluginInfos(new Map([["test", path.resolve(testPlugin)]])),
|
|
[{ name: "test", version: "0.0.1", requirePath: path.resolve(testPlugin) }]
|
|
);
|
|
});
|
|
it("should reject on broken plugin", async function() {
|
|
let brokenMessage;
|
|
try {
|
|
// eslint-disable-next-line node/global-require
|
|
require(path.resolve(brokenPlugin, "info.js"));
|
|
} catch (err) {
|
|
brokenMessage = err.message;
|
|
}
|
|
await assert.rejects(
|
|
lib.loadPluginInfos(new Map([["broken", path.resolve(brokenPlugin)]])),
|
|
{ message: `PluginError: ${brokenMessage}` }
|
|
);
|
|
});
|
|
it("should reject on invalid plugin", async function() {
|
|
await assert.rejects(
|
|
lib.loadPluginInfos(new Map([["invalid", path.resolve(invalidPlugin)]])),
|
|
{ message: `Expected plugin at ${path.resolve(invalidPlugin)} to be named invalid but got wrong` }
|
|
);
|
|
});
|
|
});
|
|
describe("loadPluginClass()", function() {
|
|
let baseDir = path.join("temp", "test", "plugin");
|
|
let missingClass = path.join(baseDir, "missing_class_plugin");
|
|
let wrongParentClass = path.join(baseDir, "wrong_parent_class_plugin");
|
|
before(async function() {
|
|
async function writeEntrypoint(pluginPath, content) {
|
|
await fs.outputFile(path.join(pluginPath, "controller.js"), content);
|
|
}
|
|
|
|
await writeEntrypoint(missingClass, "");
|
|
await writeEntrypoint(
|
|
wrongParentClass, "class ControllerPlugin {}\n module.exports = { ControllerPlugin };\n"
|
|
);
|
|
});
|
|
it("should throw if class is missing from entrypoint", async function() {
|
|
const requirePath = path.resolve(missingClass);
|
|
await assert.rejects(
|
|
lib.loadPluginClass(
|
|
"test",
|
|
path.posix.join(requirePath, "controller"),
|
|
"ControllerPlugin",
|
|
BaseControllerPlugin,
|
|
),
|
|
{
|
|
message:
|
|
`PluginError: Expected ${path.posix.join(requirePath, "controller")} ` +
|
|
"to export a class named ControllerPlugin",
|
|
}
|
|
);
|
|
});
|
|
it("should throw if class is not a subclass of BaseControllerPlugin", async function() {
|
|
const requirePath = path.resolve(wrongParentClass);
|
|
await assert.rejects(
|
|
lib.loadPluginClass(
|
|
"test",
|
|
path.posix.join(requirePath, "controller"),
|
|
"ControllerPlugin",
|
|
BaseControllerPlugin,
|
|
),
|
|
{
|
|
message:
|
|
"PluginError: Expected ControllerPlugin exported from " +
|
|
`${path.posix.join(requirePath, "controller")} to be a subclass of BaseControllerPlugin`,
|
|
}
|
|
);
|
|
});
|
|
});
|
|
});
|