Separat status och mottagningsräknare för varje kanal.

Senaste råmeddelande, fel och ignoreringsorsaker.
Pausa visning, rensa och kopiera logg.
Uppdateras utan att störa inställningsfält eller tidtagning.
This commit is contained in:
larssand
2026-09-08 18:37:47 +02:00
parent 8aedf83826
commit a0c3d3039e
15 changed files with 265 additions and 14 deletions

View File

@@ -0,0 +1,36 @@
import test from "node:test";
import assert from "node:assert/strict";
import { createDecoderDiagnostics } from "../src/decoder_diagnostics.js";
test("diagnostics bounds logs, isolates channels and returns independent snapshots", () => {
const model = createDecoderDiagnostics(() => 1234);
model.socket("main", "connected", "ws://host:9000");
for (let i = 0; i < 80; i++) {
model.frame("main", "x".repeat(2000));
model.message("main", {msg:"PASSING", transponder:123}, "lap_counted", "handled");
}
model.parseError("main");
const entries = model.snapshot();
assert.equal(entries[0].log.length, 50);
assert.equal(entries[0].lastFrame.length, 512);
assert.equal(entries[0].handled, 80);
assert.equal(entries[0].parseErrors, 1);
assert.equal(entries[1].frames, 0);
entries[0].log[0].reason = "mutated";
assert.notEqual(model.snapshot()[0].log[0].reason, "mutated");
model.clear("main");
assert.equal(model.snapshot()[0].frames, 0);
assert.equal(model.snapshot()[0].status, "connected");
assert.equal(model.snapshot()[0].connectedAt, 1234);
});
test("diagnostics separates ignored, invalid and handled messages", () => {
const model = createDecoderDiagnostics();
model.message("split", {msg:"STATUS"}, "not_passing");
model.message("split", {msg:"PASSING"}, "no_running_session");
model.message("main", {msg:"PASSING"}, "below_min", "invalid");
assert.equal(model.snapshot()[1].ignored, 2);
assert.equal(model.snapshot()[1].passings, 1);
assert.equal(model.snapshot()[0].invalid, 1);
assert.equal(model.snapshot()[0].handled, 0);
});