Files
factorio-clusterio/test/lib/plugin.js
T
Hornwitser 29f066a191 Fix missing semicolons
Ensure all statements end with a semicolon.
2020-06-17 20:53:18 +02:00

150 lines
5.2 KiB
JavaScript

const assert = require("assert").strict;
const fs = require("fs-extra");
const path = require("path");
const mock = require("../mock");
const link = require("lib/link");
const plugin = require("lib/plugin");
const errors = require("lib/errors");
describe("lib/plugin", function() {
describe("class BaseInstancePlugin", function() {
let instancePlugin;
it("should be constructible", async function() {
instancePlugin = new plugin.BaseInstancePlugin();
await instancePlugin.init();
});
it("should define defaults for hooks", async function() {
await instancePlugin.onMetrics();
await instancePlugin.onStart();
await instancePlugin.onStop();
instancePlugin.onExit();
await instancePlugin.onOutput({});
instancePlugin.onMasterConnectionEvent("connect");
await instancePlugin.onPrepareMasterDisconnect();
});
});
describe("class BaseMasterPlugin", function() {
let masterPlugin;
it("should be constructible", async function() {
masterPlugin = new plugin.BaseMasterPlugin();
await masterPlugin.init();
});
it("should define defaults for hooks", async function() {
await masterPlugin.onInstanceStatusChanged({}, "running", "initialized");
await masterPlugin.onMetrics();
await masterPlugin.onShutdown();
masterPlugin.onSlaveConnectionEvent({}, "connect");
await masterPlugin.onPrepareSlaveDisconnect({});
});
});
describe("loadPluginInfos()", function() {
let baseDir = path.join("temp", "test", "plugin");
let emptyDir = path.join(baseDir, "emptyDir");
let emptyPlugin = path.join(baseDir, "emptyPlugin");
let testPlugin = path.join(baseDir, "testPlugin");
let brokenPlugin = path.join(baseDir, "brokenPlugin");
let invalidPlugin = path.join(baseDir, "invalidPlugin");
before(async function() {
await fs.ensureDir(emptyDir);
await fs.ensureDir(path.join(emptyPlugin, "empty"));
async function writePlugin(pluginPath, name, infoName = name) {
await fs.outputFile(
path.join(pluginPath, name, "info.js"),
`module.exports = { name: "${infoName}" };`
);
}
await writePlugin(testPlugin, "test");
await writePlugin(brokenPlugin, "broken");
await fs.outputFile(path.join(brokenPlugin, "broken", "info.js"), "Syntax Error");
await writePlugin(invalidPlugin, "invalid", "wrong");
});
it("should return an empty array for an empty directory", async function() {
assert.deepEqual(await plugin.loadPluginInfos(emptyDir), []);
});
it("should ignore plugin dirs without info module", async function() {
assert.deepEqual(await plugin.loadPluginInfos(emptyPlugin), []);
});
it("should discover test plugin", async function() {
assert.deepEqual(
await plugin.loadPluginInfos(testPlugin),
[{ name: "test" }]
);
});
it("should reject on broken plugin", async function() {
await assert.rejects(
plugin.loadPluginInfos(brokenPlugin),
{ message: "PluginError: Unexpected identifier" }
);
});
it("should reject on invalid plugin", async function() {
await assert.rejects(
plugin.loadPluginInfos(invalidPlugin),
{ message: `Plugin dir ${invalidPlugin}/invalid does not match the name of the plugin (wrong)` }
);
});
after(async function() {
await fs.unlink(path.join(brokenPlugin, "broken", "info.js"));
});
});
describe("attachPluginMessages()", function() {
let mockLink = new link.Link("source", "target", new mock.MockConnector());
let mockEvent = new link.Event({ type: "test:test", links: ["target-source"] });
it("should accept pluginInfo without messages", function() {
plugin.attachPluginMessages(mockLink, {}, null);
});
it("should attach handler for the given message", function() {
let mockEventEventHandler = function() {};
plugin.attachPluginMessages(mockLink, { name: "test", messages: { mockEvent }}, { mockEventEventHandler });
assert(mockLink._handlers.get("test:test_event"), "handler was not registered");
});
it("should throw if missing handler for the given message", function() {
assert.throws(
() => plugin.attachPluginMessages(mockLink, { name: "test", messages: { mockEvent }}, {}),
new Error("Missing handler for test:test_event on source-target link")
);
});
it("should throw if message starts with the wrong prefix", function() {
assert.throws(
() => plugin.attachPluginMessages(mockLink, { name: "foo", messages: { mockEvent }}, {}),
new Error('Type of mockEvent message must start with "foo:"')
);
});
});
describe("invokeHook()", function() {
let betaTestCalled = false;
let plugins = new Map([
["alpha", {
test: async function() { },
pass: async function(arg) { return arg; },
error: async function() { throw new Error("Test"); },
}],
["beta", {
test: async function() { betaTestCalled = true; },
pass: async function() { },
error: async function() { },
}],
]);
it("should invoke the hook on the plugin", async function() {
await plugin.invokeHook(plugins, "test");
assert(betaTestCalled, "Hook was not called");
});
it("should pass and return args", async function() {
let result = await plugin.invokeHook(plugins, "pass", 1234);
assert.deepEqual(result, [1234]);
});
it("should ignore errors", async function() {
await plugin.invokeHook(plugins, "error");
});
});
});