mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-11-11 11:57:57 +00:00
test: cover partial observer chart construction failures (#2354)
Partial follow-up for #1778; addresses the chart-cleanup test gap identified in the review of #2339. The observer detail unit harness now throws during the second or fourth chart constructor. Both cases require existing chart instances to be destroyed, metadata/calibration to remain visible, the error to be rendered as text, and a later time-window retry to recover without extra requests. Production cleanup already behaves correctly; this PR adds coverage only. The parent-run ownership suite passes 30/30. Removing the actual cleanup produces exactly the two intended assertion failures. The remaining unit sources and runner match the current-master baseline whose 222 frontend suites passed; only this updated unit file differs within that test set. TDD scope: no production change or new behavior. The negative control removes existing cleanup to prove the new assertions detect its loss. No configuration, dependencies or runtime performance changes. Exact-head CI passed, including the browser shards. Independent adversarial, correctness and TDD reviews found no must-fix items. Co-authored-by: n30nex <6686206+n30nex@users.noreply.github.com>
This commit is contained in:
1 parent
b3a9f2a9e9
commit
d083f9ade9
1 file changed
+30
-2
@@ -5,10 +5,11 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
|
||||
function harness() {
|
||||
function harness(failChartAt = 0) {
|
||||
const elements = new Map();
|
||||
const requests = [];
|
||||
const charts = [];
|
||||
let chartAttempts = 0;
|
||||
let page;
|
||||
function element(id) {
|
||||
const children = [];
|
||||
@@ -36,7 +37,12 @@ function harness() {
|
||||
const app = element('app');
|
||||
class Chart {
|
||||
static defaults = {};
|
||||
constructor(canvas, config) { this.config = config; this.destroyed = false; charts.push(this); }
|
||||
constructor(canvas, config) {
|
||||
if (++chartAttempts === failChartAt) throw new Error('<chart construction failure>');
|
||||
this.config = config;
|
||||
this.destroyed = false;
|
||||
charts.push(this);
|
||||
}
|
||||
destroy() { this.destroyed = true; }
|
||||
}
|
||||
const context = vm.createContext({
|
||||
@@ -147,6 +153,28 @@ async function test(name, fn) {
|
||||
});
|
||||
}
|
||||
|
||||
for (const failedChart of [2, 4]) {
|
||||
await test('chart construction failure ' + failedChart + ' cleans up partial analytics and permits retry', async () => {
|
||||
const h = harness(failedChart);
|
||||
complete(h.visit('A'), 'A');
|
||||
await settled();
|
||||
assert.strictEqual(h.charts.length, failedChart - 1, 'failure follows successful chart construction');
|
||||
assert.ok(h.charts.every(chart => chart.destroyed), 'already constructed charts must be destroyed');
|
||||
assert.strictEqual(h.snapshot().charts.length, 0, 'failed analytics must retain no active charts');
|
||||
assert.strictEqual(h.snapshot().title, 'A');
|
||||
assert.match(h.snapshot().html, /Test radio/);
|
||||
assert.match(h.snapshot().html, /2 seconds/);
|
||||
assert.strictEqual(h.elements.get('obsAnalytics').firstChild.textContent, 'Error: <chart construction failure>');
|
||||
assert.doesNotMatch(h.snapshot().html, /<chart construction failure>/, 'construction error uses textContent');
|
||||
|
||||
complete(h.days(1), 'A', 'retry');
|
||||
await settled();
|
||||
assert.strictEqual(h.snapshot().charts.length, 4, 'a later load can construct its own charts');
|
||||
assert.ok(h.charts.slice(0, failedChart - 1).every(chart => chart.destroyed), 'retry cannot revive failed charts');
|
||||
assert.strictEqual(h.requests.length, 6, 'only the requested retry fetches again');
|
||||
});
|
||||
}
|
||||
|
||||
await test('identity failure stays visible when secondary responses settle later', async () => {
|
||||
const h = harness();
|
||||
const pending = h.visit('A');
|
||||
|
||||
Reference in new issue
Block a user