Add tests and expect library
This commit is contained in:
parent
ebf846c154
commit
ab2ef3e803
16 changed files with 256 additions and 108 deletions
|
@ -1,37 +1,27 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
moduleFileExtensions: [
|
moduleFileExtensions: ["js", "jsx", "json", "vue", "ts", "tsx"],
|
||||||
'js',
|
|
||||||
'jsx',
|
|
||||||
'json',
|
|
||||||
'vue',
|
|
||||||
'ts',
|
|
||||||
'tsx'
|
|
||||||
],
|
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.vue$': 'vue-jest',
|
"^.+\\.vue$": "vue-jest",
|
||||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
|
||||||
'^.+\\.tsx?$': 'ts-jest'
|
"jest-transform-stub",
|
||||||
|
"^.+\\.tsx?$": "ts-jest"
|
||||||
},
|
},
|
||||||
transformIgnorePatterns: [
|
transformIgnorePatterns: ["/node_modules/"],
|
||||||
'/node_modules/'
|
|
||||||
],
|
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^@/(.*)$': '<rootDir>/src/$1'
|
"^@/(.*)$": "<rootDir>/src/$1"
|
||||||
},
|
},
|
||||||
snapshotSerializers: [
|
snapshotSerializers: ["jest-serializer-vue"],
|
||||||
'jest-serializer-vue'
|
|
||||||
],
|
|
||||||
testMatch: [
|
testMatch: [
|
||||||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
"**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
|
||||||
],
|
],
|
||||||
testURL: 'http://localhost/',
|
testURL: "http://localhost/",
|
||||||
watchPlugins: [
|
watchPlugins: [
|
||||||
'jest-watch-typeahead/filename',
|
"jest-watch-typeahead/filename",
|
||||||
'jest-watch-typeahead/testname'
|
"jest-watch-typeahead/testname"
|
||||||
],
|
],
|
||||||
globals: {
|
globals: {
|
||||||
'ts-jest': {
|
"ts-jest": {
|
||||||
babelConfig: true
|
babelConfig: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import { PeerMetadata, NetworkMessage } from "./types";
|
import { PeerMetadata, NetworkMessage } from "./types";
|
||||||
|
import EventEmitter from "eventemitter3";
|
||||||
|
|
||||||
export class LocalClient {
|
export class LocalClient extends EventEmitter {
|
||||||
public metadata: PeerMetadata;
|
public metadata: PeerMetadata;
|
||||||
public receiver!: (data: NetworkMessage) => void;
|
public receiver!: (data: NetworkMessage) => void;
|
||||||
|
|
||||||
public constructor(metadata: PeerMetadata) {
|
public constructor(metadata: PeerMetadata) {
|
||||||
|
super();
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public receive(data: NetworkMessage) {
|
public receive(data: NetworkMessage) {
|
||||||
|
this.emit("data", data);
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import Peer, { DataConnection } from "peerjs";
|
import Peer, { DataConnection } from "peerjs";
|
||||||
import { NetworkMessage } from "./types";
|
import { NetworkMessage } from "./types";
|
||||||
|
import EventEmitter from "eventemitter3";
|
||||||
|
|
||||||
export class NetworkPeer {
|
export class NetworkPeer extends EventEmitter {
|
||||||
protected peer: Peer;
|
protected peer: Peer;
|
||||||
protected constructor(peer?: Peer) {
|
protected constructor(peer?: Peer) {
|
||||||
|
super();
|
||||||
this.peer = peer ? peer : new Peer();
|
this.peer = peer ? peer : new Peer();
|
||||||
this.peer.on("open", function(id) {
|
this.peer.on("open", function(id) {
|
||||||
console.info("Peer ID assigned: %s", id);
|
console.info("Peer ID assigned: %s", id);
|
||||||
|
@ -11,7 +13,6 @@ export class NetworkPeer {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected send<T extends NetworkMessage>(conn: DataConnection, data: T) {
|
protected send<T extends NetworkMessage>(conn: DataConnection, data: T) {
|
||||||
//TODO Debugging support?
|
|
||||||
conn.send(data);
|
conn.send(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
35
src/network/PeerClient.ts
Normal file
35
src/network/PeerClient.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import NetworkPeer from "./NetworkPeer";
|
||||||
|
import Peer, { DataConnection } from "peerjs";
|
||||||
|
import { PeerMetadata, NetworkMessage } from "./types";
|
||||||
|
|
||||||
|
export class PeerClient extends NetworkPeer {
|
||||||
|
private connection?: DataConnection;
|
||||||
|
private metadata: PeerMetadata;
|
||||||
|
|
||||||
|
public constructor(metadata: PeerMetadata, customPeer?: Peer) {
|
||||||
|
super(customPeer);
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public connect(peerid: string) {
|
||||||
|
this.connection = this.peer.connect(peerid, {
|
||||||
|
metadata: this.metadata,
|
||||||
|
reliable: true
|
||||||
|
});
|
||||||
|
if (!this.connection) {
|
||||||
|
throw new Error("Could not connect");
|
||||||
|
}
|
||||||
|
this.connection.on("open", () => {
|
||||||
|
this.emit("connected");
|
||||||
|
});
|
||||||
|
this.connection.on("data", data => {
|
||||||
|
this._received(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _received(data: NetworkMessage) {
|
||||||
|
this.emit("data", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PeerClient;
|
|
@ -1,4 +1,3 @@
|
||||||
import NetworkPeer from "./peer";
|
|
||||||
import Peer, { DataConnection } from "peerjs";
|
import Peer, { DataConnection } from "peerjs";
|
||||||
import {
|
import {
|
||||||
RoomInfo,
|
RoomInfo,
|
||||||
|
@ -16,7 +15,7 @@ import {
|
||||||
NetworkPlayer,
|
NetworkPlayer,
|
||||||
AckMessage
|
AckMessage
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import LocalClient from "./local";
|
import { NetworkPeer, LocalClient } from ".";
|
||||||
|
|
||||||
// Increment name, add number at the end if not present
|
// Increment name, add number at the end if not present
|
||||||
// Examples:
|
// Examples:
|
||||||
|
@ -56,7 +55,9 @@ export class PeerServer extends NetworkPeer {
|
||||||
info: roomInfo,
|
info: roomInfo,
|
||||||
players
|
players
|
||||||
};
|
};
|
||||||
this.peer.on("connection", this._connection.bind(this));
|
this.peer.on("connection", conn => {
|
||||||
|
this._connection(conn);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _connection(conn: DataConnection) {
|
private _connection(conn: DataConnection) {
|
||||||
|
@ -77,7 +78,10 @@ export class PeerServer extends NetworkPeer {
|
||||||
// Check if there is already a player called that way
|
// Check if there is already a player called that way
|
||||||
if (this.room.players[metadata.name]) {
|
if (this.room.players[metadata.name]) {
|
||||||
// Force rename
|
// Force rename
|
||||||
const newname = nextName(metadata.name);
|
let newname = metadata.name;
|
||||||
|
while (this.room.players[newname]) {
|
||||||
|
newname = nextName(metadata.name);
|
||||||
|
}
|
||||||
this.send<RenameMessage>(conn, {
|
this.send<RenameMessage>(conn, {
|
||||||
kind: "rename",
|
kind: "rename",
|
||||||
oldname: metadata.name,
|
oldname: metadata.name,
|
|
@ -1,26 +0,0 @@
|
||||||
import NetworkPeer from "./peer";
|
|
||||||
import Peer, { DataConnection } from "peerjs";
|
|
||||||
import { PeerMetadata, NetworkMessage } from "./types";
|
|
||||||
|
|
||||||
export class PeerClient extends NetworkPeer {
|
|
||||||
private connection: DataConnection;
|
|
||||||
public constructor(
|
|
||||||
peerid: string,
|
|
||||||
metadata: PeerMetadata,
|
|
||||||
customPeer?: Peer
|
|
||||||
) {
|
|
||||||
super(customPeer);
|
|
||||||
this.connection = this.peer.connect(peerid, {
|
|
||||||
metadata,
|
|
||||||
reliable: true
|
|
||||||
});
|
|
||||||
this.connection.on("open", () => {
|
|
||||||
console.info("Connected to server");
|
|
||||||
});
|
|
||||||
this.connection.on("data", this._received.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private _received(data: NetworkMessage) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PeerClient;
|
|
|
@ -1,5 +1,5 @@
|
||||||
export * from "./client";
|
export * from "./PeerClient";
|
||||||
export * from "./local";
|
export * from "./LocalClient";
|
||||||
export * from "./peer";
|
export * from "./NetworkPeer";
|
||||||
export * from "./server";
|
export * from "./PeerServer";
|
||||||
export * from "./types";
|
export * from "./types";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { DataConnection } from "peerjs";
|
import { DataConnection } from "peerjs";
|
||||||
import LocalClient from "./local";
|
import LocalClient from "./LocalClient";
|
||||||
|
|
||||||
export interface LocalPlayer {
|
export interface LocalPlayer {
|
||||||
kind: "local";
|
kind: "local";
|
||||||
|
|
63
src/testing/EventHook.ts
Normal file
63
src/testing/EventHook.ts
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import EventEmitter from "eventemitter3";
|
||||||
|
import { withTimeout } from "@/utils";
|
||||||
|
|
||||||
|
interface HookedEvent {
|
||||||
|
date: Date;
|
||||||
|
arguments: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultCmp = () => {};
|
||||||
|
|
||||||
|
export class EventHook extends EventEmitter {
|
||||||
|
public backlog: Record<string, HookedEvent[]> = {};
|
||||||
|
|
||||||
|
public hookEmitter(emitter: EventEmitter, event: string, id: string) {
|
||||||
|
emitter.on(event, this._receivedEmitter.bind(this, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public expect(
|
||||||
|
id: string,
|
||||||
|
timeout: number = 1000,
|
||||||
|
cmp: (...args: any) => void = defaultCmp
|
||||||
|
): Promise<void> {
|
||||||
|
// Build promise
|
||||||
|
const promise = new Promise<void>((resolve, reject) => {
|
||||||
|
const getLastEvent = () => {
|
||||||
|
// Take first element in the backlog
|
||||||
|
let event = this.backlog[id].shift();
|
||||||
|
if (!event) {
|
||||||
|
// Should never happen
|
||||||
|
return reject(`undefined event in list (??)`);
|
||||||
|
}
|
||||||
|
// Send to check function, then resolve
|
||||||
|
resolve(cmp(...event.arguments));
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (this.backlog[id] && this.backlog[id].length > 0) {
|
||||||
|
// Event is already in the backlog
|
||||||
|
getLastEvent();
|
||||||
|
} else {
|
||||||
|
// If the event hasn't fired yet, subscribe to the next time it will
|
||||||
|
this.once(id, getLastEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return promise with added timeout
|
||||||
|
return withTimeout(promise, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When events are received
|
||||||
|
private _receivedEmitter(id: string, ...args: any) {
|
||||||
|
const event: HookedEvent = {
|
||||||
|
date: new Date(),
|
||||||
|
arguments: args
|
||||||
|
};
|
||||||
|
// Create backlog if it doesn't exist
|
||||||
|
if (!this.backlog[id]) {
|
||||||
|
this.backlog[id] = [];
|
||||||
|
}
|
||||||
|
// Push to backlog and emit event (for pending expects)
|
||||||
|
this.backlog[id].push(event);
|
||||||
|
this.emit(id, event);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,19 @@
|
||||||
import EventEmitter from "eventemitter3";
|
import EventEmitter from "eventemitter3";
|
||||||
import LocalPeer from "./LocalPeer";
|
import MockPeer from "./MockPeer";
|
||||||
import { PeerConnectOption } from "peerjs";
|
import { PeerConnectOption } from "peerjs";
|
||||||
|
|
||||||
export default class LocalDataConnection extends EventEmitter {
|
export class MockDataConnection extends EventEmitter {
|
||||||
public options: PeerConnectOption;
|
public options: PeerConnectOption;
|
||||||
public peer: string;
|
public peer: string;
|
||||||
public provider: LocalPeer;
|
public provider: MockPeer;
|
||||||
public open: boolean = false;
|
public open: boolean = false;
|
||||||
private _connection?: LocalDataConnection;
|
private _connection?: MockDataConnection;
|
||||||
public id: string;
|
public id: string;
|
||||||
public label: string;
|
public label: string;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
peer: string,
|
peer: string,
|
||||||
provider: LocalPeer,
|
provider: MockPeer,
|
||||||
options?: PeerConnectOption
|
options?: PeerConnectOption
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -57,7 +57,7 @@ export default class LocalDataConnection extends EventEmitter {
|
||||||
this.emit("close");
|
this.emit("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
public _setRemote(connection: LocalDataConnection) {
|
public _setRemote(connection: MockDataConnection) {
|
||||||
this._connection = connection;
|
this._connection = connection;
|
||||||
this._connection.on("open", () => {
|
this._connection.on("open", () => {
|
||||||
if (!this.open) {
|
if (!this.open) {
|
||||||
|
@ -68,7 +68,7 @@ export default class LocalDataConnection extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public _configureDataChannel(
|
public _configureDataChannel(
|
||||||
mocks: Record<string, LocalPeer>,
|
mocks: Record<string, MockPeer>,
|
||||||
options?: PeerConnectOption
|
options?: PeerConnectOption
|
||||||
) {
|
) {
|
||||||
if (!this._connection && this.peer in mocks) {
|
if (!this._connection && this.peer in mocks) {
|
||||||
|
@ -217,3 +217,5 @@ export default class LocalDataConnection extends EventEmitter {
|
||||||
throw new Error("not implemented");
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default MockDataConnection;
|
|
@ -1,30 +1,35 @@
|
||||||
import EventEmitter from "eventemitter3";
|
import EventEmitter from "eventemitter3";
|
||||||
import Peer, { PeerConnectOption, PeerJSOption } from "peerjs";
|
import Peer, { PeerConnectOption, PeerJSOption } from "peerjs";
|
||||||
import LocalDataConnection from "./LocalDataConnection";
|
import MockDataConnection from "./MockDataConnection";
|
||||||
|
|
||||||
let mocks: Record<string, LocalPeer> = {};
|
export class MockPeer extends EventEmitter {
|
||||||
|
public connections: Record<string, MockDataConnection[]>;
|
||||||
export default class LocalPeer extends EventEmitter {
|
|
||||||
public connections: Record<string, LocalDataConnection[]>;
|
|
||||||
public id: string;
|
public id: string;
|
||||||
public options: PeerJSOption;
|
public options: PeerJSOption;
|
||||||
public disconnected: boolean;
|
public disconnected: boolean;
|
||||||
public destroyed: boolean;
|
public destroyed: boolean;
|
||||||
public prototype: unknown;
|
public prototype: unknown;
|
||||||
|
private mocks: Record<string, MockPeer>;
|
||||||
|
|
||||||
public constructor(id: string, options?: PeerJSOption) {
|
public constructor(
|
||||||
|
mockSource: Record<string, MockPeer>,
|
||||||
|
id: string,
|
||||||
|
options?: PeerJSOption
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.options = options ? options : {};
|
this.options = options ? options : {};
|
||||||
this.connections = {};
|
this.connections = {};
|
||||||
this.disconnected = false;
|
this.disconnected = false;
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
mocks[id] = this;
|
this.mocks = mockSource;
|
||||||
|
this.mocks[id] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public connect(id: string, options?: PeerConnectOption): LocalDataConnection {
|
public connect(id: string, options?: PeerConnectOption): MockDataConnection {
|
||||||
let connection = new LocalDataConnection(id, this, options);
|
let connection = new MockDataConnection(id, this, options);
|
||||||
connection._configureDataChannel(mocks, options);
|
// hacky way to avoid race conditions
|
||||||
|
setTimeout(() => connection._configureDataChannel(this.mocks, options), 1);
|
||||||
this._addConnection(id, connection);
|
this._addConnection(id, connection);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +46,7 @@ export default class LocalPeer extends EventEmitter {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addConnection(peer: string, connection: LocalDataConnection) {
|
private _addConnection(peer: string, connection: MockDataConnection) {
|
||||||
if (!this.connections[peer]) {
|
if (!this.connections[peer]) {
|
||||||
this.connections[peer] = [];
|
this.connections[peer] = [];
|
||||||
}
|
}
|
||||||
|
@ -50,10 +55,10 @@ export default class LocalPeer extends EventEmitter {
|
||||||
|
|
||||||
public _negotiate(
|
public _negotiate(
|
||||||
peer: string,
|
peer: string,
|
||||||
remoteConnection: LocalDataConnection,
|
remoteConnection: MockDataConnection,
|
||||||
options?: PeerConnectOption
|
options?: PeerConnectOption
|
||||||
) {
|
) {
|
||||||
let localConnection = new LocalDataConnection(peer, this, options);
|
let localConnection = new MockDataConnection(peer, this, options);
|
||||||
localConnection._setRemote(remoteConnection);
|
localConnection._setRemote(remoteConnection);
|
||||||
this._addConnection(peer, localConnection);
|
this._addConnection(peer, localConnection);
|
||||||
this.emit("connection", localConnection);
|
this.emit("connection", localConnection);
|
||||||
|
@ -73,9 +78,9 @@ export default class LocalPeer extends EventEmitter {
|
||||||
public getConnection(
|
public getConnection(
|
||||||
peerId: string,
|
peerId: string,
|
||||||
connectionId: string
|
connectionId: string
|
||||||
): LocalDataConnection | null {
|
): MockDataConnection | null {
|
||||||
if (peerId in mocks) {
|
if (peerId in this.mocks) {
|
||||||
let map = mocks[peerId].connections;
|
let map = this.mocks[peerId].connections;
|
||||||
if (connectionId in map) {
|
if (connectionId in map) {
|
||||||
return map[connectionId][0];
|
return map[connectionId][0];
|
||||||
}
|
}
|
||||||
|
@ -86,3 +91,5 @@ export default class LocalPeer extends EventEmitter {
|
||||||
|
|
||||||
public listAllPeers() {}
|
public listAllPeers() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default MockPeer;
|
2
src/testing/index.ts
Normal file
2
src/testing/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./MockDataConnection";
|
||||||
|
export * from "./MockPeer";
|
80
src/tests/unit/network.spec.ts
Normal file
80
src/tests/unit/network.spec.ts
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import Peer from "peerjs";
|
||||||
|
import { MockPeer } from "@/testing";
|
||||||
|
import { PeerServer, LocalClient, PeerClient, NetworkMessage } from "@/network";
|
||||||
|
import { EventHook } from "@/testing/EventHook";
|
||||||
|
|
||||||
|
const sampleRoom = () => ({
|
||||||
|
max_players: 3,
|
||||||
|
password: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
function mockSource(): Record<string, MockPeer> {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createServer(
|
||||||
|
mockSource: Record<string, MockPeer>,
|
||||||
|
id: string = "test-server",
|
||||||
|
name: string = "server-client"
|
||||||
|
) {
|
||||||
|
const serverPeer = new MockPeer(mockSource, id, {});
|
||||||
|
const serverPlayer = new LocalClient({
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
return new PeerServer(sampleRoom(), serverPlayer, serverPeer as Peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createClient(
|
||||||
|
mockSource: Record<string, MockPeer>,
|
||||||
|
id: string = "test-client",
|
||||||
|
name: string = "client-peer"
|
||||||
|
) {
|
||||||
|
const clientPeer = new MockPeer(mockSource, id, {});
|
||||||
|
return new PeerClient({ name }, clientPeer as Peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function messageKind(kind: string): (msg: NetworkMessage) => void {
|
||||||
|
return msg => {
|
||||||
|
expect(msg.kind).toEqual(kind);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("network/PeerServer", () => {
|
||||||
|
test("Create server", () => {
|
||||||
|
const mox = mockSource();
|
||||||
|
createServer(mox);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test client join", async () => {
|
||||||
|
const mox = mockSource();
|
||||||
|
const hook = new EventHook();
|
||||||
|
createServer(mox);
|
||||||
|
const client = createClient(mox);
|
||||||
|
hook.hookEmitter(client, "data", "client-data");
|
||||||
|
client.connect("test-server");
|
||||||
|
await hook.expect("client-data", 1000, messageKind("room-info"));
|
||||||
|
await hook.expect("client-data", 1000, messageKind("player-joined"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test multiple clients", async () => {
|
||||||
|
const mox = mockSource();
|
||||||
|
const hook = new EventHook();
|
||||||
|
createServer(mox);
|
||||||
|
const client1 = createClient(mox);
|
||||||
|
const client2 = createClient(mox);
|
||||||
|
hook.hookEmitter(client1, "data", "client1-data");
|
||||||
|
hook.hookEmitter(client2, "data", "client2-data");
|
||||||
|
client1.connect("test-server");
|
||||||
|
await hook.expect("client1-data", 1000, messageKind("room-info"));
|
||||||
|
await hook.expect("client1-data", 1000, messageKind("player-joined"));
|
||||||
|
client2.connect("test-server");
|
||||||
|
await hook.expect("client2-data", 1000, messageKind("rename"));
|
||||||
|
await hook.expect("client2-data", 1000, messageKind("room-info"));
|
||||||
|
await hook.expect("client2-data", 1000, messageKind("player-joined"));
|
||||||
|
await hook.expect("client1-data", 1000, messageKind("player-joined"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("network/PeerClient", () => {
|
||||||
|
//TODO Client tests
|
||||||
|
});
|
|
@ -1,23 +0,0 @@
|
||||||
import LocalPeer from "@/testing/LocalPeer";
|
|
||||||
import Peer from "peerjs";
|
|
||||||
import { PeerServer, LocalClient, PeerClient } from "@/network";
|
|
||||||
|
|
||||||
describe("network/PeerServer", () => {
|
|
||||||
test("Create server and client", () => {
|
|
||||||
const serverPeer = new LocalPeer("test-server", {});
|
|
||||||
const clientPeer = new LocalPeer("test-client", {});
|
|
||||||
const serverPlayer = new LocalClient({
|
|
||||||
name: "server-client"
|
|
||||||
});
|
|
||||||
const roomInfo = {
|
|
||||||
max_players: 3,
|
|
||||||
password: ""
|
|
||||||
};
|
|
||||||
const server = new PeerServer(roomInfo, serverPlayer, serverPeer as Peer);
|
|
||||||
const client = new PeerClient(
|
|
||||||
"test-server",
|
|
||||||
{ name: "test" },
|
|
||||||
clientPeer as Peer
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
1
src/utils/index.ts
Normal file
1
src/utils/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./timeout";
|
9
src/utils/timeout.ts
Normal file
9
src/utils/timeout.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
|
||||||
|
const timeout = new Promise<T>((resolve, reject) => {
|
||||||
|
let id = setTimeout(() => {
|
||||||
|
clearTimeout(id);
|
||||||
|
reject("Timed out after " + ms + "ms.");
|
||||||
|
}, ms);
|
||||||
|
});
|
||||||
|
return Promise.race<T>([promise, timeout]);
|
||||||
|
}
|
Loading…
Reference in a new issue