Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
import { Mulberry32Rng } from "@suaveplan/pseudo-random";
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
applyNetworkConditions,
shouldDropPacket,
simulateLatency,
} from "./index.js";
const seededRng = (): Mulberry32Rng => new Mulberry32Rng(0xc0ffee);
describe("network legacy helpers", () => {
it("simulates latency within range", () => {
const latency = simulateLatency(
{
latencyMs: 100,
jitterMs: 20,
packetLossRate: 0,
},
seededRng()
);
expect(latency).toBeGreaterThanOrEqual(80);
expect(latency).toBeLessThanOrEqual(120);
});
it("never drops with zero loss rate", () => {
const rng = seededRng();
for (let i = 0; i < 100; i++) {
expect(
shouldDropPacket(
{
latencyMs: 50,
jitterMs: 0,
packetLossRate: 0,
},
rng
)
).toBe(false);
}
});
it("passes payload through network", () => {
const payload = new Uint8Array([1, 2, 3]);
const result = applyNetworkConditions(
payload,
{
latencyMs: 50,
jitterMs: 0,
packetLossRate: 0,
},
seededRng()
);
expect(result).toEqual(payload);
});
it("drops packet with 100% loss rate", () => {
const payload = new Uint8Array([1, 2, 3]);
const result = applyNetworkConditions(
payload,
{
latencyMs: 50,
jitterMs: 0,
packetLossRate: 1,
},
seededRng()
);
expect(result).toBeUndefined();
});
it("uses default conditions when none provided", () => {
const latency = simulateLatency(undefined, seededRng());
expect(latency).toBeGreaterThanOrEqual(40);
expect(latency).toBeLessThanOrEqual(60);
expect(shouldDropPacket(undefined, seededRng())).toBe(false);
const payload = new Uint8Array([1]);
expect(applyNetworkConditions(payload, undefined, seededRng())).toEqual(
payload
);
});
it("falls back to defaultRng when no Rng supplied", () => {
// In this test env the host lacks crypto.getRandomValues, so the
// default RNG factory throws RandomError. The genesis determinism
// rule forbids silent Math.random fallback; either crypto is
// available (function returns) or it isn't (function throws).
// Both outcomes exercise the fallback branch.
try {
simulateLatency();
// If it didn't throw, the host has crypto.getRandomValues.
expect(true).toBe(true);
} catch (e) {
expect(e).toBeInstanceOf(Error);
expect((e as Error).message).toMatch(
/random\.source\.unavailable|getRandomValues|crypto/i
);
}
try {
shouldDropPacket();
} catch (e) {
expect(e).toBeInstanceOf(Error);
}
try {
applyNetworkConditions(new Uint8Array([1]));
} catch (e) {
expect(e).toBeInstanceOf(Error);
}
});
});