mirror of https://github.com/embarklabs/embark.git
chore(@embark/testing): Add testables to embark test objects
1. Add IPC mock and assertions. 2. Add console command registration assertion and console command mock. 3. Add event emission assertions
This commit is contained in:
parent
d5e0897231
commit
56d5b45bbb
|
@ -2,11 +2,13 @@ const sinon = require('sinon');
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
||||||
class Embark {
|
class Embark {
|
||||||
constructor(events, plugins, config) {
|
constructor(events, plugins, config = {}, ipc) {
|
||||||
this.events = events;
|
this.events = events;
|
||||||
this.plugins = plugins;
|
this.plugins = plugins;
|
||||||
this.config = config || {};
|
this.config = config || {};
|
||||||
this.config.plugins = plugins;
|
this.config.plugins = plugins;
|
||||||
|
this.ipc = ipc;
|
||||||
|
this.config.ipc = ipc;
|
||||||
this.assert = new EmbarkAssert(this);
|
this.assert = new EmbarkAssert(this);
|
||||||
this.fs = fs;
|
this.fs = fs;
|
||||||
|
|
||||||
|
@ -32,12 +34,14 @@ class Embark {
|
||||||
}
|
}
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
this.config = { plugins: this.plugins };
|
this.config = { plugins: this.plugins, ipc: this.ipc };
|
||||||
this.plugins.teardown();
|
this.plugins.teardown();
|
||||||
|
this.ipc.teardown();
|
||||||
|
this.events.teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
setConfig(config) {
|
setConfig(config) {
|
||||||
this.config = { ...config, plugins: this.plugins };
|
this.config = { ...config, plugins: this.plugins, ipc: this.ipc };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Events {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.commandHandlers = {};
|
this.commandHandlers = {};
|
||||||
this.handlers = {};
|
this.handlers = {};
|
||||||
|
this.emissions = {};
|
||||||
|
|
||||||
this.assert = new EventsAssert(this);
|
this.assert = new EventsAssert(this);
|
||||||
}
|
}
|
||||||
|
@ -18,14 +19,13 @@ class Events {
|
||||||
this.handlers[ev] = [];
|
this.handlers[ev] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handlers[ev].push(cb);
|
this.handlers[ev].push(sinon.spy(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit() {
|
emit(ev, ...args) {
|
||||||
|
|
||||||
}
|
this.emissions[ev] = args;
|
||||||
|
|
||||||
trigger(ev, ...args) {
|
|
||||||
if (!this.handlers[ev]) {
|
if (!this.handlers[ev]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,12 @@ class Events {
|
||||||
}
|
}
|
||||||
|
|
||||||
request(cmd, ...args) {
|
request(cmd, ...args) {
|
||||||
assert(this.commandHandlers[cmd], `command handler for ${cmd} not registered`);
|
assert(this.commandHandlers[cmd], `command handler for '${cmd}' not registered`);
|
||||||
Promise.resolve(this.commandHandlers[cmd](...args));
|
Promise.resolve(this.commandHandlers[cmd](...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
request2(cmd, ...args) {
|
request2(cmd, ...args) {
|
||||||
assert(this.commandHandlers[cmd], `command handler for ${cmd} not registered`);
|
assert(this.commandHandlers[cmd], `command handler for '${cmd}' not registered`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
args.push((err, ...res) => {
|
args.push((err, ...res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -53,6 +53,12 @@ class Events {
|
||||||
this.commandHandlers[cmd](...args);
|
this.commandHandlers[cmd](...args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
this.commandHandlers = {};
|
||||||
|
this.handlers = {};
|
||||||
|
this.emissions = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventsAssert {
|
class EventsAssert {
|
||||||
|
@ -61,19 +67,40 @@ class EventsAssert {
|
||||||
}
|
}
|
||||||
|
|
||||||
commandHandlerRegistered(cmd) {
|
commandHandlerRegistered(cmd) {
|
||||||
assert(this.events.commandHandlers[cmd], `command handler for ${cmd} wanted, but not registered`);
|
assert(this.events.commandHandlers[cmd], `command handler for '${cmd}' wanted, but not registered`);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandHandlerCalled(cmd) {
|
commandHandlerCalled(cmd) {
|
||||||
this.commandHandlerRegistered(cmd);
|
this.commandHandlerRegistered(cmd);
|
||||||
sinon.assert.called(this.events.commandHandlers[cmd]);
|
sinon.assert.called(this.events.commandHandlers[cmd]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commandHandlerNotCalled(cmd) {
|
||||||
|
this.commandHandlerRegistered(cmd);
|
||||||
|
assert(!this.events.commandHandlers[cmd].called);
|
||||||
|
}
|
||||||
|
|
||||||
commandHandlerCalledWith(cmd, ...args) {
|
commandHandlerCalledWith(cmd, ...args) {
|
||||||
this.commandHandlerRegistered(cmd);
|
this.commandHandlerRegistered(cmd);
|
||||||
sinon.assert.calledWith(this.events.commandHandlers[cmd], ...args);
|
sinon.assert.calledWith(this.events.commandHandlers[cmd], ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listenerRegistered(name) {
|
||||||
|
assert(this.events.handlers[name], `event listener for '${name}' wanted, but not registered`);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitted(name) {
|
||||||
|
assert(this.events.emissions[name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
notEmitted(name) {
|
||||||
|
assert(!Object.keys(this.events.emissions).includes(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
emittedWith(name, ...args) {
|
||||||
|
assert.equal(this.events.emissions[name], ...args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Events;
|
module.exports = Events;
|
||||||
|
|
|
@ -2,22 +2,14 @@ const Embark = require('./embark');
|
||||||
const Events = require('./events');
|
const Events = require('./events');
|
||||||
const Plugins = require('./plugin');
|
const Plugins = require('./plugin');
|
||||||
const HttpMockServer = require('./httpServer');
|
const HttpMockServer = require('./httpServer');
|
||||||
|
const Ipc = require('./ipc');
|
||||||
|
|
||||||
const fakeEmbark = (config) => {
|
const fakeEmbark = (config = {}) => {
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
const plugins = new Plugins();
|
const plugins = new Plugins();
|
||||||
|
const ipc = config.ipc ?? new Ipc();
|
||||||
|
|
||||||
const ipc = {
|
const embark = new Embark(events, plugins, config, ipc);
|
||||||
isServer: () => { return true; },
|
|
||||||
broadcast: () => {},
|
|
||||||
on: () => {},
|
|
||||||
isClient: () => { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
config = config || {};
|
|
||||||
config.ipc = config.ipc || ipc;
|
|
||||||
|
|
||||||
const embark = new Embark(events, plugins, config);
|
|
||||||
return {
|
return {
|
||||||
embark,
|
embark,
|
||||||
plugins
|
plugins
|
||||||
|
@ -29,6 +21,6 @@ module.exports = {
|
||||||
Events,
|
Events,
|
||||||
Plugins,
|
Plugins,
|
||||||
HttpMockServer,
|
HttpMockServer,
|
||||||
|
Ipc,
|
||||||
fakeEmbark
|
fakeEmbark
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
const sinon = require('sinon');
|
||||||
|
|
||||||
|
class Ipc {
|
||||||
|
constructor(isServer = true) {
|
||||||
|
this._isServer = isServer;
|
||||||
|
this.handlers = {};
|
||||||
|
this.assert = new IpcAssert(this);
|
||||||
|
this._client = null;
|
||||||
|
this.broadcasts = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get connected() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get client() {
|
||||||
|
if (this._client !== null) {
|
||||||
|
return this._client;
|
||||||
|
}
|
||||||
|
this._client = new Ipc(false);
|
||||||
|
return this._client;
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast(ev, ...args) {
|
||||||
|
this.broadcasts[ev] = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
isClient() {
|
||||||
|
return !this._isServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
isServer() {
|
||||||
|
return this._isServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
on(ev, cb) {
|
||||||
|
if (!this.handlers[ev]) {
|
||||||
|
this.handlers[ev] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handlers[ev].push(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
request(ev, ...args) {
|
||||||
|
if (!this.handlers[ev]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handlers[ev].forEach(h => h(...args));
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
this.handlers = {};
|
||||||
|
this._client = null;
|
||||||
|
this.broadcasts = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IpcAssert {
|
||||||
|
constructor(ipc) {
|
||||||
|
this.ipc = ipc;
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerRegistered(cmd) {
|
||||||
|
assert(this.ipc.handlers[cmd], `listener for '${cmd}' wanted, but not registered`);
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerNotRegistered(cmd) {
|
||||||
|
assert(!Object.keys(this.ipc.handlers).some(command => command === cmd), `listener for '${cmd}' registered, but expected to not be registered`);
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerRequested(cmd) {
|
||||||
|
this.listenerRegistered(cmd);
|
||||||
|
sinon.assert.called(this.events.handlers[cmd]);
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerRequestedWith(cmd, ...args) {
|
||||||
|
this.listenerRequested(cmd);
|
||||||
|
sinon.assert.calledWith(this.events.handlers[cmd], ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Ipc;
|
|
@ -46,7 +46,7 @@ class Plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
this.plugin.listeners = {};
|
this.plugin.teardown();
|
||||||
this.plugins.forEach(plugin => plugin.teardown());
|
this.plugins.forEach(plugin => plugin.teardown());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,10 @@ class Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
|
this.listeners = {};
|
||||||
|
this.apiCalls = {};
|
||||||
|
this.pluginTypes = [];
|
||||||
|
this.console = [];
|
||||||
this.compilers = [];
|
this.compilers = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +139,22 @@ class PluginsAssert {
|
||||||
const index = (method + endpoint).toLowerCase();
|
const index = (method + endpoint).toLowerCase();
|
||||||
assert(this.plugins.plugin.apiCalls[index], `API call for '${method} ${endpoint}' wanted, but not registered`);
|
assert(this.plugins.plugin.apiCalls[index], `API call for '${method} ${endpoint}' wanted, but not registered`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consoleCommandRegistered(command) {
|
||||||
|
const registered = this.plugins.plugin.console.some(cmd => {
|
||||||
|
if (!cmd.matches) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Array.isArray(cmd.matches)) {
|
||||||
|
return cmd.matches.some(matches => matches.includes(command));
|
||||||
|
}
|
||||||
|
if (typeof cmd.matches === 'function') {
|
||||||
|
return cmd.matches(command);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
assert(registered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PluginsMock {
|
class PluginsMock {
|
||||||
|
@ -142,6 +162,38 @@ class PluginsMock {
|
||||||
this.plugins = plugins;
|
this.plugins = plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consoleCommand(cmd) {
|
||||||
|
const command = this.plugins.plugin.console.find(c => {
|
||||||
|
if (!c.matches) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(c.matches) && c.matches.some(matches => matches.includes(cmd))) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (typeof c.matches === 'function' && c.matches(cmd)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
assert(command, `Console command for '${cmd}' wanted, but not registered`);
|
||||||
|
const cb = sinon.fake();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
command.process(cmd, (err, ...res) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
if (res.length && res.length > 1) {
|
||||||
|
cb(res);
|
||||||
|
return resolve(cb);
|
||||||
|
}
|
||||||
|
cb(res[0]);
|
||||||
|
return resolve(cb);
|
||||||
|
});
|
||||||
|
resolve(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async apiCall(method, endpoint, params) {
|
async apiCall(method, endpoint, params) {
|
||||||
const index = (method + endpoint).toLowerCase();
|
const index = (method + endpoint).toLowerCase();
|
||||||
const apiFn = this.plugins.plugin.apiCalls[index];
|
const apiFn = this.plugins.plugin.apiCalls[index];
|
||||||
|
|
Loading…
Reference in New Issue