mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
151 lines
4.1 KiB
JavaScript
151 lines
4.1 KiB
JavaScript
import EventEmitter from "events";
|
|
import { Tinytest } from "meteor/tinytest";
|
|
import { enable } from "./inter-process-messaging.js";
|
|
|
|
// Simulated handle for a child process held by the parent process, like
|
|
// the object returned by child_process.spawn. Emits any sent messages in
|
|
// the child process, represented by this.child.
|
|
class FakeChildProcess extends EventEmitter {
|
|
constructor() {
|
|
super();
|
|
this.child = new FakeProcess(this);
|
|
enable(this);
|
|
}
|
|
|
|
send(message) {
|
|
this.child.emit("message", JSON.parse(JSON.stringify(message)));
|
|
}
|
|
}
|
|
|
|
// Fake process object analogous to global.process.
|
|
class FakeProcess extends EventEmitter {
|
|
constructor(parent) {
|
|
super();
|
|
this.parent = parent;
|
|
enable(this);
|
|
}
|
|
|
|
send(message) {
|
|
this.parent.emit("message", JSON.parse(JSON.stringify(message)));
|
|
}
|
|
}
|
|
|
|
Tinytest.addAsync('inter-process-messaging - basic', async (test) => {
|
|
const proc = new FakeChildProcess;
|
|
|
|
// Reach into the fake child process to register a listener.
|
|
proc.child.onMessage("add-one-eleven", value => {
|
|
return value + 111;
|
|
});
|
|
|
|
const results = await proc.sendMessage("add-one-eleven", 123);
|
|
|
|
test.equal(results, [234]);
|
|
});
|
|
|
|
Tinytest.addAsync('inter-process-messaging - multiple listeners', async (test) => {
|
|
const proc = new FakeChildProcess;
|
|
|
|
proc.child.onMessage("popular-topic", () => "a");
|
|
proc.child.onMessage("popular-topic", async () => {
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
return "b";
|
|
});
|
|
proc.child.onMessage("popular-topic", async () => "c");
|
|
|
|
const popularResults = await proc.sendMessage("popular-topic");
|
|
test.equal(popularResults, ["a", "b", "c"]);
|
|
|
|
const unpopularResults = await proc.sendMessage("unpopular-topic");
|
|
test.equal(unpopularResults, []);
|
|
|
|
proc.child.onMessage("unpopular-topic", () => "finally");
|
|
test.equal(await proc.sendMessage("unpopular-topic"), ["finally"]);
|
|
});
|
|
|
|
Tinytest.addAsync('inter-process-messaging - errors', async (test) => {
|
|
const proc = new FakeChildProcess;
|
|
const expectedError = new Error("expected");
|
|
|
|
proc.child.onMessage("risky-topic", () => "a");
|
|
proc.child.onMessage("risky-topic", () => {
|
|
throw expectedError;
|
|
});
|
|
|
|
return proc.sendMessage("risky-topic").then(result => {
|
|
throw new Error("should have thrown");
|
|
}, error => {
|
|
test.equal(error.message, "expected");
|
|
});
|
|
});
|
|
|
|
Tinytest.addAsync('inter-process-messaging - message from child', async (test) => {
|
|
const proc = new FakeChildProcess;
|
|
|
|
proc.onMessage("from-child", async (payload) => {
|
|
test.equal(payload.hello, "hi");
|
|
return "right back atcha";
|
|
});
|
|
|
|
const results = await proc.child.sendMessage("from-child", {
|
|
hello: "hi"
|
|
});
|
|
|
|
test.equal(results, ["right back atcha"]);
|
|
});
|
|
|
|
Tinytest.addAsync('inter-process-messaging - exotic payloads', async (test) => {
|
|
const proc = new FakeChildProcess;
|
|
|
|
// Reach into the fake child process to register a listener.
|
|
proc.child.onMessage("self-reference", payload => {
|
|
test.ok(payload.self === payload);
|
|
return payload;
|
|
});
|
|
|
|
const obj = {};
|
|
obj.self = obj;
|
|
const [obj2] = await proc.sendMessage("self-reference", obj);
|
|
|
|
test.ok(obj2 !== obj);
|
|
test.ok(obj2.self === obj2);
|
|
|
|
// Reach into the fake child process to register a listener.
|
|
proc.child.onMessage("repeated-reference", payload => {
|
|
test.ok(payload[0] === payload[1]);
|
|
return payload;
|
|
});
|
|
|
|
const arr = [obj, obj, obj];
|
|
const [arr2] = await proc.sendMessage("repeated-reference", arr);
|
|
|
|
test.ok(arr2 !== arr);
|
|
test.ok(arr2[0] === arr2[1]);
|
|
test.ok(arr2[1] === arr2[2]);
|
|
|
|
// Reach into the fake child process to register a listener.
|
|
proc.child.onMessage("Set-Map-containment", map => {
|
|
checkMap(map);
|
|
return map;
|
|
});
|
|
|
|
function checkMap(map) {
|
|
test.equal(map.size, 1);
|
|
map.forEach((set, self) => {
|
|
test.ok(self === map);
|
|
test.equal(set.size, 2);
|
|
test.ok(set.has(map));
|
|
test.ok(set.has(set));
|
|
});
|
|
}
|
|
|
|
const map = new Map;
|
|
const set = new Set;
|
|
map.set(map, set);
|
|
set.add(map).add(set);
|
|
|
|
const [map2] = await proc.sendMessage("Set-Map-containment", map);
|
|
test.ok(map2 !== map);
|
|
checkMap(map2);
|
|
});
|