Files
Void-Bastion/server/nakama/tests/runtime_sim_test.js
T

108 lines
5.8 KiB
JavaScript

const assert = require("assert");
const fs = require("fs");
const vm = require("vm");
const path = require("path");
const source = fs.readFileSync(path.join(__dirname, "..", "runtime", "build", "index.js"), "utf8");
const context = { console, Math, Date, JSON, isFinite };
vm.createContext(context);
vm.runInContext(source, context);
const sent = [];
const dispatcher = {
broadcastMessage(opCode, data) {
sent.push({ opCode, data: JSON.parse(data) });
},
matchLabelUpdate(label) {
let data = label;
try { data = JSON.parse(label); } catch (error) {}
sent.push({ opCode: "label", data });
}
};
const nk = { binaryToString: data => Buffer.from(data).toString("utf8") };
const logger = { info() {} };
const presenceA = { userId: "pilot-a", sessionId: "a", username: "Pilot A" };
const presenceB = { userId: "pilot-b", sessionId: "b", username: "Pilot B" };
let updatedAccount = null;
let deletedAccount = null;
const accountNk = {
accountUpdateId(...args) { updatedAccount = args; },
accountDeleteId(...args) { deletedAccount = args; }
};
assert.deepStrictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: " Kommandant Ägir " }))), { accepted: true, display_name: "Kommandant Ägir" });
assert.strictEqual(updatedAccount[0], "pilot-a");
assert.strictEqual(updatedAccount[2], "Kommandant Ägir");
assert.strictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: "ADMIN" }))).accepted, false);
assert.strictEqual(JSON.parse(context.rpcUpdateDisplayName({ userId: "pilot-a" }, logger, accountNk, JSON.stringify({ display_name: "A!" }))).accepted, false);
assert.deepStrictEqual(JSON.parse(context.rpcDeleteAccount({ userId: "pilot-a" }, logger, accountNk, "{}")), { accepted: true });
assert.deepStrictEqual(deletedAccount, ["pilot-a", false]);
let state = context.matchInit({}, logger, nk, { difficulty: 1 }).state;
state = context.matchJoin({}, logger, nk, dispatcher, 1, state, [presenceA]).state;
state = context.matchJoin({}, logger, nk, dispatcher, 2, state, [presenceB]).state;
assert.strictEqual(state.started, false);
assert.strictEqual(state.slots["pilot-a"], 0);
assert.strictEqual(state.slots["pilot-b"], 1);
assert.ok(sent.some(entry => entry.opCode === 1 && entry.data.players[0].name === "Pilot A"));
assert.strictEqual(context.normalizeRoomCode(" ab-c12! "), "ABC12");
const privateMatch = context.matchInit({}, logger, nk, { difficulty: 2, mode: "private", roomCode: "AB23CD", hostUserId: "pilot-a" });
assert.strictEqual(privateMatch.label, "AB23CD");
assert.strictEqual(privateMatch.state.difficulty, 2);
const roomStorage = new Map();
const nkRooms = {
storageRead(ops) { return ops.map(op => roomStorage.get(op.key)).filter(Boolean); },
storageWrite(ops) { for (const op of ops) roomStorage.set(op.key, { value: op.value }); },
storageDelete(ops) { for (const op of ops) roomStorage.delete(op.key); },
matchCreate() { return "private-match-id"; }
};
const createdRoom = JSON.parse(context.rpcCreatePrivateRoom({ userId: "pilot-a" }, logger, nkRooms, JSON.stringify({ difficulty: 2 })));
assert.strictEqual(createdRoom.room_code.length, 6);
const joinedRoom = JSON.parse(context.rpcJoinPrivateRoom({ userId: "pilot-b" }, logger, nkRooms, JSON.stringify({ room_code: createdRoom.room_code.toLowerCase() })));
assert.strictEqual(joinedRoom.match_id, "private-match-id");
function message(sender, opCode, payload) {
return { sender, opCode, data: Buffer.from(JSON.stringify(payload)) };
}
state = context.matchLoop({}, logger, nk, dispatcher, 3, state, [message(presenceA, 14, { ready: true, name: "Kommandant A" })]).state;
assert.strictEqual(state.started, false);
state = context.matchLoop({}, logger, nk, dispatcher, 4, state, [message(presenceB, 14, { ready: true, name: "Kommandant B" })]).state;
assert.strictEqual(state.started, true);
assert.strictEqual(state.players["pilot-a"].name, "Kommandant A");
assert.ok(sent.some(entry => entry.opCode === "label" && entry.data.open === false));
state = context.matchLoop({}, logger, nk, dispatcher, 5, state, [
message(presenceA, 10, { tower_type: 0, x: 200, y: 200 }),
message(presenceB, 10, { tower_type: 1, x: 2760, y: 200 })
]).state;
assert.strictEqual(state.towers.length, 2);
assert.strictEqual(state.credits[0], 310);
assert.strictEqual(state.credits[1], 250);
state = context.matchLoop({}, logger, nk, dispatcher, 6, state, [message(presenceA, 13, {})]).state;
assert.strictEqual(state.wave, 1);
assert.strictEqual(state.waveActive, true);
for (let tick = 7; tick < 30; tick++) state = context.matchLoop({}, logger, nk, dispatcher, tick, state, []).state;
assert.ok(state.enemies.length > 0 || state.spawnRemaining > 0);
assert.ok(sent.some(entry => entry.opCode === 1 && entry.data.started === true));
const towerA = state.towers.find(tower => tower.owner === 0);
state = context.matchLoop({}, logger, nk, dispatcher, 30, state, [message(presenceA, 11, { tower_id: towerA.id })]).state;
assert.strictEqual(state.towers.find(tower => tower.id === towerA.id).level, 2);
state = context.matchLoop({}, logger, nk, dispatcher, 31, state, [message(presenceA, 12, { tower_id: towerA.id })]).state;
assert.ok(!state.towers.some(tower => tower.id === towerA.id));
state = context.matchLeave({}, logger, nk, dispatcher, 32, state, [presenceB]).state;
assert.strictEqual(state.started, true);
assert.strictEqual(state.pausedForReconnect, true);
assert.strictEqual(context.snapshot(state, 32).players[1].connected, false);
assert.strictEqual(context.matchJoinAttempt({}, logger, nk, dispatcher, 33, state, presenceB, {}).accept, true);
state = context.matchJoin({}, logger, nk, dispatcher, 33, state, [presenceB]).state;
assert.strictEqual(state.pausedForReconnect, false);
assert.strictEqual(state.slots["pilot-b"], 1);
console.log("VOID_BASTION_SERVER_SIM_OK");