Skip to content

Commit 56d5b45

Browse files
emizzle0x-r4bbit
authored andcommitted
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
1 parent d5e0897 commit 56d5b45

File tree

5 files changed

+184
-24
lines changed

5 files changed

+184
-24
lines changed

packages/utils/testing/src/embark.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ const sinon = require('sinon');
22
import fs from 'fs-extra';
33

44
class Embark {
5-
constructor(events, plugins, config) {
5+
constructor(events, plugins, config = {}, ipc) {
66
this.events = events;
77
this.plugins = plugins;
88
this.config = config || {};
99
this.config.plugins = plugins;
10+
this.ipc = ipc;
11+
this.config.ipc = ipc;
1012
this.assert = new EmbarkAssert(this);
1113
this.fs = fs;
1214

@@ -32,12 +34,14 @@ class Embark {
3234
}
3335

3436
teardown() {
35-
this.config = { plugins: this.plugins };
37+
this.config = { plugins: this.plugins, ipc: this.ipc };
3638
this.plugins.teardown();
39+
this.ipc.teardown();
40+
this.events.teardown();
3741
}
3842

3943
setConfig(config) {
40-
this.config = { ...config, plugins: this.plugins };
44+
this.config = { ...config, plugins: this.plugins, ipc: this.ipc };
4145
}
4246
}
4347

packages/utils/testing/src/events.js

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class Events {
55
constructor() {
66
this.commandHandlers = {};
77
this.handlers = {};
8+
this.emissions = {};
89

910
this.assert = new EventsAssert(this);
1011
}
@@ -18,14 +19,13 @@ class Events {
1819
this.handlers[ev] = [];
1920
}
2021

21-
this.handlers[ev].push(cb);
22+
this.handlers[ev].push(sinon.spy(cb));
2223
}
2324

24-
emit() {
25+
emit(ev, ...args) {
2526

26-
}
27+
this.emissions[ev] = args;
2728

28-
trigger(ev, ...args) {
2929
if (!this.handlers[ev]) {
3030
return;
3131
}
@@ -34,12 +34,12 @@ class Events {
3434
}
3535

3636
request(cmd, ...args) {
37-
assert(this.commandHandlers[cmd], `command handler for ${cmd} not registered`);
37+
assert(this.commandHandlers[cmd], `command handler for '${cmd}' not registered`);
3838
Promise.resolve(this.commandHandlers[cmd](...args));
3939
}
4040

4141
request2(cmd, ...args) {
42-
assert(this.commandHandlers[cmd], `command handler for ${cmd} not registered`);
42+
assert(this.commandHandlers[cmd], `command handler for '${cmd}' not registered`);
4343
return new Promise((resolve, reject) => {
4444
args.push((err, ...res) => {
4545
if (err) {
@@ -53,6 +53,12 @@ class Events {
5353
this.commandHandlers[cmd](...args);
5454
});
5555
}
56+
57+
teardown() {
58+
this.commandHandlers = {};
59+
this.handlers = {};
60+
this.emissions = {};
61+
}
5662
}
5763

5864
class EventsAssert {
@@ -61,19 +67,40 @@ class EventsAssert {
6167
}
6268

6369
commandHandlerRegistered(cmd) {
64-
assert(this.events.commandHandlers[cmd], `command handler for ${cmd} wanted, but not registered`);
70+
assert(this.events.commandHandlers[cmd], `command handler for '${cmd}' wanted, but not registered`);
6571
}
6672

6773
commandHandlerCalled(cmd) {
6874
this.commandHandlerRegistered(cmd);
6975
sinon.assert.called(this.events.commandHandlers[cmd]);
7076
}
77+
78+
commandHandlerNotCalled(cmd) {
79+
this.commandHandlerRegistered(cmd);
80+
assert(!this.events.commandHandlers[cmd].called);
81+
}
7182

7283
commandHandlerCalledWith(cmd, ...args) {
7384
this.commandHandlerRegistered(cmd);
7485
sinon.assert.calledWith(this.events.commandHandlers[cmd], ...args);
7586
}
7687

88+
listenerRegistered(name) {
89+
assert(this.events.handlers[name], `event listener for '${name}' wanted, but not registered`);
90+
}
91+
92+
emitted(name) {
93+
assert(this.events.emissions[name]);
94+
}
95+
96+
notEmitted(name) {
97+
assert(!Object.keys(this.events.emissions).includes(name));
98+
}
99+
100+
emittedWith(name, ...args) {
101+
assert.equal(this.events.emissions[name], ...args);
102+
}
103+
77104
}
78105

79106
module.exports = Events;

packages/utils/testing/src/index.js

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,14 @@ const Embark = require('./embark');
22
const Events = require('./events');
33
const Plugins = require('./plugin');
44
const HttpMockServer = require('./httpServer');
5+
const Ipc = require('./ipc');
56

6-
const fakeEmbark = (config) => {
7+
const fakeEmbark = (config = {}) => {
78
const events = new Events();
89
const plugins = new Plugins();
10+
const ipc = config.ipc ?? new Ipc();
911

10-
const ipc = {
11-
isServer: () => { return true; },
12-
broadcast: () => {},
13-
on: () => {},
14-
isClient: () => { return false; }
15-
};
16-
17-
config = config || {};
18-
config.ipc = config.ipc || ipc;
19-
20-
const embark = new Embark(events, plugins, config);
12+
const embark = new Embark(events, plugins, config, ipc);
2113
return {
2214
embark,
2315
plugins
@@ -29,6 +21,6 @@ module.exports = {
2921
Events,
3022
Plugins,
3123
HttpMockServer,
32-
24+
Ipc,
3325
fakeEmbark
3426
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const assert = require('assert');
2+
const sinon = require('sinon');
3+
4+
class Ipc {
5+
constructor(isServer = true) {
6+
this._isServer = isServer;
7+
this.handlers = {};
8+
this.assert = new IpcAssert(this);
9+
this._client = null;
10+
this.broadcasts = {};
11+
}
12+
13+
get connected() {
14+
return true;
15+
}
16+
17+
get client() {
18+
if (this._client !== null) {
19+
return this._client;
20+
}
21+
this._client = new Ipc(false);
22+
return this._client;
23+
}
24+
25+
broadcast(ev, ...args) {
26+
this.broadcasts[ev] = args;
27+
}
28+
29+
isClient() {
30+
return !this._isServer;
31+
}
32+
33+
isServer() {
34+
return this._isServer;
35+
}
36+
37+
on(ev, cb) {
38+
if (!this.handlers[ev]) {
39+
this.handlers[ev] = [];
40+
}
41+
42+
this.handlers[ev].push(cb);
43+
}
44+
45+
request(ev, ...args) {
46+
if (!this.handlers[ev]) {
47+
return;
48+
}
49+
50+
this.handlers[ev].forEach(h => h(...args));
51+
}
52+
53+
teardown() {
54+
this.handlers = {};
55+
this._client = null;
56+
this.broadcasts = {};
57+
}
58+
}
59+
60+
class IpcAssert {
61+
constructor(ipc) {
62+
this.ipc = ipc;
63+
}
64+
65+
listenerRegistered(cmd) {
66+
assert(this.ipc.handlers[cmd], `listener for '${cmd}' wanted, but not registered`);
67+
}
68+
69+
listenerNotRegistered(cmd) {
70+
assert(!Object.keys(this.ipc.handlers).some(command => command === cmd), `listener for '${cmd}' registered, but expected to not be registered`);
71+
}
72+
73+
listenerRequested(cmd) {
74+
this.listenerRegistered(cmd);
75+
sinon.assert.called(this.events.handlers[cmd]);
76+
}
77+
78+
listenerRequestedWith(cmd, ...args) {
79+
this.listenerRequested(cmd);
80+
sinon.assert.calledWith(this.events.handlers[cmd], ...args);
81+
}
82+
83+
}
84+
85+
module.exports = Ipc;

packages/utils/testing/src/plugin.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Plugins {
4646
}
4747

4848
teardown() {
49-
this.plugin.listeners = {};
49+
this.plugin.teardown();
5050
this.plugins.forEach(plugin => plugin.teardown());
5151
}
5252

@@ -108,6 +108,10 @@ class Plugin {
108108
}
109109

110110
teardown() {
111+
this.listeners = {};
112+
this.apiCalls = {};
113+
this.pluginTypes = [];
114+
this.console = [];
111115
this.compilers = [];
112116
}
113117
}
@@ -135,13 +139,61 @@ class PluginsAssert {
135139
const index = (method + endpoint).toLowerCase();
136140
assert(this.plugins.plugin.apiCalls[index], `API call for '${method} ${endpoint}' wanted, but not registered`);
137141
}
142+
143+
consoleCommandRegistered(command) {
144+
const registered = this.plugins.plugin.console.some(cmd => {
145+
if (!cmd.matches) {
146+
return false;
147+
}
148+
if (Array.isArray(cmd.matches)) {
149+
return cmd.matches.some(matches => matches.includes(command));
150+
}
151+
if (typeof cmd.matches === 'function') {
152+
return cmd.matches(command);
153+
}
154+
return false;
155+
});
156+
assert(registered);
157+
}
138158
}
139159

140160
class PluginsMock {
141161
constructor(plugins) {
142162
this.plugins = plugins;
143163
}
144164

165+
consoleCommand(cmd) {
166+
const command = this.plugins.plugin.console.find(c => {
167+
if (!c.matches) {
168+
return;
169+
}
170+
if (Array.isArray(c.matches) && c.matches.some(matches => matches.includes(cmd))) {
171+
return c;
172+
}
173+
if (typeof c.matches === 'function' && c.matches(cmd)) {
174+
return c;
175+
}
176+
return;
177+
});
178+
assert(command, `Console command for '${cmd}' wanted, but not registered`);
179+
const cb = sinon.fake();
180+
181+
return new Promise((resolve, reject) => {
182+
command.process(cmd, (err, ...res) => {
183+
if (err) {
184+
return reject(err);
185+
}
186+
if (res.length && res.length > 1) {
187+
cb(res);
188+
return resolve(cb);
189+
}
190+
cb(res[0]);
191+
return resolve(cb);
192+
});
193+
resolve(cb);
194+
});
195+
}
196+
145197
async apiCall(method, endpoint, params) {
146198
const index = (method + endpoint).toLowerCase();
147199
const apiFn = this.plugins.plugin.apiCalls[index];

0 commit comments

Comments
 (0)