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
192 lines
5.9 KiB
JavaScript
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);
|
|
}
|