单测
This commit is contained in:
parent
eeaf9e071e
commit
e9cdb48d30
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import EventEmitter from "eventemitter3";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
@ -23,6 +24,7 @@ export class Server {
|
||||
});
|
||||
}
|
||||
|
||||
on(eventName: "connection", callback: (con: IConnect) => void): void;
|
||||
on(eventName: string, callback: (con: IConnect) => void) {
|
||||
this.EE.on(eventName, callback);
|
||||
}
|
||||
@ -31,29 +33,11 @@ export class Server {
|
||||
export class Connect {
|
||||
private EE: EventEmitter;
|
||||
|
||||
private con: IConnect;
|
||||
|
||||
constructor(
|
||||
private id: string | IConnect,
|
||||
con?: IConnect
|
||||
) {
|
||||
constructor(private con: IConnect) {
|
||||
this.EE = new EventEmitter();
|
||||
if (arguments.length === 1) {
|
||||
this.con = id as IConnect;
|
||||
this.con.onMessage((message) => {
|
||||
this.messageHandler(message);
|
||||
});
|
||||
} else {
|
||||
// 子连接
|
||||
this.con = con!;
|
||||
this.con.onMessage((message) => {
|
||||
const data = message as { eventName: string; data: unknown; id: string };
|
||||
if (data.eventName === "subcon") {
|
||||
if (data.id !== this.id) return;
|
||||
this.messageHandler(data.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.con.onMessage((message) => {
|
||||
this.messageHandler(message);
|
||||
});
|
||||
this.con.onDisconnect(() => {
|
||||
this.EE.emit("disconnect");
|
||||
this.EE.removeAllListeners();
|
||||
@ -67,12 +51,16 @@ export class Connect {
|
||||
}
|
||||
|
||||
private messageHandler(data: unknown) {
|
||||
const subData = data as { eventName: string; data: unknown[]; messageId: string };
|
||||
const subData = data as { eventName: string; data: unknown[]; messageId: string; conType: string; id: string };
|
||||
if (subData.eventName === "callback") {
|
||||
this.EE.emit(subData.eventName + subData.messageId, ...subData.data);
|
||||
return;
|
||||
}
|
||||
subData.data.push(this.callbackFunc(subData.messageId));
|
||||
this.EE.emit(subData.eventName, ...subData.data);
|
||||
}
|
||||
|
||||
on(eventName: string, callback: (message: unknown) => void) {
|
||||
on(eventName: string, callback: (...args: any[]) => void) {
|
||||
this.EE.on(eventName, callback);
|
||||
}
|
||||
|
||||
@ -80,17 +68,18 @@ export class Connect {
|
||||
this.con.postMessage({ eventName, data });
|
||||
}
|
||||
|
||||
emit(eventName: string, ...data: unknown[]) {
|
||||
emit(eventName: string, ...data: any[]) {
|
||||
// 判断最后一个参数是否为函数
|
||||
const callback = data.pop();
|
||||
const messageId = uuidv4();
|
||||
if (typeof callback !== "function") {
|
||||
data.push(callback);
|
||||
} else {
|
||||
this.EE.on("callback" + messageId, (...args) => {
|
||||
callback(...args);
|
||||
});
|
||||
}
|
||||
this.con.postMessage({ eventName, data, messageId: uuidv4() });
|
||||
}
|
||||
|
||||
// 子连接
|
||||
connect() {
|
||||
return new Connect(uuidv4(), this.con);
|
||||
const sendData = { eventName, data, messageId };
|
||||
this.con.postMessage(sendData);
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,65 @@
|
||||
// @vitest-environment jsdom
|
||||
import { expect, test, vi } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { Server, Connect } from ".";
|
||||
import { connect, WindowServer } from "./window";
|
||||
|
||||
test("server", async () => {
|
||||
const myFunc = vi.fn();
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
con.onMessage((message) => {
|
||||
myFunc(message);
|
||||
describe("server", () => {
|
||||
it("hello", async () => {
|
||||
const myFunc = vi.fn();
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
con.onMessage((message) => {
|
||||
myFunc(message);
|
||||
});
|
||||
});
|
||||
const client = connect(window, window);
|
||||
client.postMessage("hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
expect(myFunc).toHaveBeenCalledTimes(2);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
});
|
||||
const client = connect(window, window);
|
||||
client.postMessage("hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
expect(myFunc).toHaveBeenCalledTimes(2);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
});
|
||||
|
||||
test("connect", async () => {
|
||||
const myFunc = vi.fn();
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
const wrapCon = new Connect(con);
|
||||
wrapCon.on("hello", (message) => {
|
||||
myFunc(message);
|
||||
wrapCon.emit("world", "world");
|
||||
describe("connect", async () => {
|
||||
it("hello", async () => {
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
const myFunc = vi.fn();
|
||||
server.on("connection", (con) => {
|
||||
myFunc();
|
||||
const wrapCon = new Connect(con);
|
||||
wrapCon.on("hello", (message) => {
|
||||
myFunc(message);
|
||||
wrapCon.emit("world", "world");
|
||||
});
|
||||
});
|
||||
const client = new Connect(connect(window, window));
|
||||
client.on("world", (message) => {
|
||||
myFunc(message);
|
||||
});
|
||||
client.emit("hello", "hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
expect(myFunc).toHaveBeenCalledTimes(3);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
expect(myFunc).toHaveBeenCalledWith("world");
|
||||
});
|
||||
const client = new Connect(connect(window, window));
|
||||
client.on("world", (message) => {
|
||||
myFunc(message);
|
||||
it("response", async () => {
|
||||
const server = new Server(new WindowServer(global.window));
|
||||
const myFunc = vi.fn();
|
||||
server.on("connection", (con) => {
|
||||
const wrapCon = new Connect(con);
|
||||
wrapCon.on("ping", (message, response) => {
|
||||
myFunc(message);
|
||||
response("pong");
|
||||
});
|
||||
});
|
||||
const client = new Connect(connect(window, window));
|
||||
client.emit("ping", "ping", (message: string) => {
|
||||
myFunc(message);
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
expect(myFunc).toHaveBeenCalledTimes(2);
|
||||
expect(myFunc).toHaveBeenCalledWith("ping");
|
||||
expect(myFunc).toHaveBeenCalledWith("pong");
|
||||
});
|
||||
client.emit("hello", "hello");
|
||||
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||
expect(myFunc).toHaveBeenCalledTimes(3);
|
||||
expect(myFunc).toHaveBeenCalledWith("hello");
|
||||
expect(myFunc).toHaveBeenCalledWith("world");
|
||||
});
|
||||
|
@ -20,8 +20,9 @@ export class WindowServer implements IServer {
|
||||
}
|
||||
|
||||
export function connect(source: Window, target: Window) {
|
||||
const con = new WindowConnect(uuidv4(), source, target);
|
||||
con.postMessage({ type: "connect" });
|
||||
const connectId = uuidv4();
|
||||
target.postMessage({ type: "connect", connectId }, "*");
|
||||
const con = new WindowConnect(connectId, source, target);
|
||||
return con;
|
||||
}
|
||||
|
||||
@ -35,14 +36,14 @@ export class WindowConnect implements IConnect {
|
||||
) {
|
||||
this.EE = new EventEmitter();
|
||||
this.source.addEventListener("message", (event) => {
|
||||
if (event.data.id === id) {
|
||||
this.EE.emit("message", event.data);
|
||||
if (event.data.eventName === "message" && event.data.id === id) {
|
||||
this.EE.emit("message", event.data.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
postMessage(message: unknown) {
|
||||
this.target.postMessage(message, "*");
|
||||
postMessage(data: unknown) {
|
||||
this.target.postMessage({ eventName: "message", id: this.id, data }, "*");
|
||||
}
|
||||
|
||||
onMessage(callback: (message: unknown) => void) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user