Files
cell/tests/enet.js
John Alanbrook e9519484cc
Some checks failed
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
fix enet; add enet testing
2025-02-24 13:43:01 -06:00

192 lines
5.9 KiB
JavaScript

var os = use('os');
var enet = use('enet');
var json = use('json'); // Some QuickJS environments need this import for JSON
////////////////////////////////////////////////////////////////////////////////
// 1. Initialization
////////////////////////////////////////////////////////////////////////////////
// Make sure ENet is initialized before we do anything else
enet.initialize();
////////////////////////////////////////////////////////////////////////////////
// 2. "Framework": test runner & polling helper
////////////////////////////////////////////////////////////////////////////////
let results = [];
/**
* Simple test runner. Each test is given a name and a function.
* If the function throws an Error, the test is marked failed.
*/
function runTest(testName, testFunc) {
console.log(`=== Running Test: ${testName} ===`);
try {
testFunc();
results.push({ testName, passed: true });
} catch (err) {
console.log(`Test "${testName}" failed: ${err}`);
results.push({ testName, passed: false, error: err });
}
}
/**
* runSteps polls both client and server for `steps` iterations,
* each iteration calling service() with a small timeout. Any events
* are captured and returned in arrays for further inspection.
*
* @param {Object} client - the client ENet host
* @param {Object} server - the server ENet host
* @param {number} steps - how many iterations to process
* @param {boolean} printEvents - whether to log events to console
* @param {number} timeout - milliseconds to pass to service()
* @returns { clientEvents, serverEvents } arrays of all events captured
*/
function runSteps(client, server, steps = 5, printEvents = false, timeout = 10) {
let clientEvents = [];
let serverEvents = [];
for (let i = 0; i < steps; i++) {
// Poll the client
client.service((evt) => {
if (evt) {
clientEvents.push(evt);
if (printEvents) {
console.log("client:" + json.encode(evt));
}
}
}, timeout);
// Poll the server
server.service((evt) => {
if (evt) {
serverEvents.push(evt);
if (printEvents) {
console.log("server:" + json.encode(evt));
}
}
}, timeout);
}
return { clientEvents, serverEvents };
}
////////////////////////////////////////////////////////////////////////////////
// 3. Actual Tests
////////////////////////////////////////////////////////////////////////////////
let serverHost = null;
let clientHost = null;
let clientPeer = null;
runTest("Create Server", () => {
// Bind on 127.0.0.1:12345
serverHost = enet.create_host("127.0.0.1:12345");
if (!serverHost) {
throw new Error("Failed to create server host");
}
});
runTest("Create Client", () => {
clientHost = enet.create_host();
if (!clientHost) {
throw new Error("Failed to create client host");
}
});
runTest("Connect Client to Server", () => {
clientPeer = clientHost.connect("127.0.0.1", 12345);
if (!clientPeer) {
throw new Error("Failed to create client->server peer");
}
// Poll both sides for a few steps so the connection can succeed
const { clientEvents, serverEvents } = runSteps(clientHost, serverHost, 5, true);
// Verify the server got a 'connect' event
let connectEvent = serverEvents.find(evt => evt.type === "connect");
if (!connectEvent) {
throw new Error("Server did not receive a connect event");
}
});
runTest("Send Data from Client to Server", () => {
// Send some JSON object from client -> server
clientPeer.send({ hello: "HELLO" });
// Process for a few steps so the data actually arrives
const { clientEvents, serverEvents } = runSteps(clientHost, serverHost, 5, true);
// The server should get a 'receive' event
let receiveEvent = serverEvents.find(evt => evt.type === "receive");
if (!receiveEvent) {
throw new Error("Server did not receive data from the client");
}
// Check the payload
if (!receiveEvent.data || receiveEvent.data.hello !== "HELLO") {
throw new Error(`Server got unexpected data: ${JSON.stringify(receiveEvent.data)}`);
}
});
runTest("Broadcast from Server to Client", () => {
// The server broadcasts a JSON string
serverHost.broadcast({ broadcast: "HelloAll" });
// Let data flow
const { clientEvents, serverEvents } = runSteps(clientHost, serverHost, 5, true);
// Client should get a 'receive' event with broadcast data
let broadcastEvent = clientEvents.find(evt => evt.type === "receive");
if (!broadcastEvent) {
throw new Error("Client did not receive broadcast data");
}
// The broadcastEvent.data should be an object with broadcast="HelloAll"
if (!broadcastEvent.data || broadcastEvent.data.broadcast !== "HelloAll") {
throw new Error(`Client received unexpected broadcast: ${JSON.stringify(broadcastEvent.data)}`);
}
});
runTest("Disconnect Client", () => {
// Disconnect from the client side
clientPeer.disconnect();
// Let both sides see the disconnect
const { clientEvents, serverEvents } = runSteps(clientHost, serverHost, 5, true);
// The server should eventually get a "disconnect"
let disconnectEvent = serverEvents.find(evt => evt.type === "disconnect");
if (!disconnectEvent) {
throw new Error("Server never received a disconnect event");
}
});
runTest("Deinitialize ENet", () => {
enet.deinitialize();
});
////////////////////////////////////////////////////////////////////////////////
// 4. Print Summary & Exit
////////////////////////////////////////////////////////////////////////////////
console.log("\n=== Test Summary ===");
let passedCount = 0;
results.forEach(({ testName, passed, error }, idx) => {
console.log(`Test ${idx + 1}: ${testName} - ${passed ? "PASSED" : "FAILED"}`);
if (!passed && error) {
console.log(" Reason:", error);
}
if (passed) passedCount++;
});
console.log(`\nResult: ${passedCount}/${results.length} tests passed`);
if (passedCount < results.length) {
console.log("Overall: FAILED");
os.exit(1);
} else {
console.log("Overall: PASSED");
os.exit(0);
}