From bdf87ffd67a7d32e290bcfdf174d1119ff14a31d Mon Sep 17 00:00:00 2001 From: znetsixe Date: Tue, 26 May 2026 17:55:39 +0200 Subject: [PATCH] test(dashboardapi): perf + uid-uniqueness for multi-child composition (#35) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architectural note: existing composition is "1 dashboardAPI → root dashboard + 1 per child", not "1 dashboardAPI → 1 dashboard with N panels" as the PRD assumed. Each generated dashboard is laid out at template-authoring time (explicit gridPos per panel inside config/.json); the composer's job is to substitute per-instance templating variables and assemble the cross-link list. So the PRD's "non-overlapping gridPos for N panels" lands as: - perf: 50 children compose in <500ms (PRD N-1). - uid-uniqueness: stableUid keyed on softwareType:nodeId never collides. - byte-identical idempotency (PRD N-2): two consecutive compositions match. - root links: one link per registered child. No production code change — this slice just adds the perf/uniqueness/idempotency guarantees as explicit tests so we can't regress. Closes #35 --- ...raph-perf-and-uid-uniqueness.basic.test.js | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 test/basic/slice35-graph-perf-and-uid-uniqueness.basic.test.js diff --git a/test/basic/slice35-graph-perf-and-uid-uniqueness.basic.test.js b/test/basic/slice35-graph-perf-and-uid-uniqueness.basic.test.js new file mode 100644 index 0000000..7da587f --- /dev/null +++ b/test/basic/slice35-graph-perf-and-uid-uniqueness.basic.test.js @@ -0,0 +1,75 @@ +'use strict'; + +const test = require('node:test'); +const assert = require('node:assert/strict'); + +const DashboardApi = require('../../src/specificClass.js'); + +function makeChild(i, softwareType = 'measurement', positionVsParent = 'downstream') { + return { + child: { + config: { + general: { id: `child-${i}`, name: `Child ${i}` }, + functionality: { softwareType, positionVsParent }, + }, + }, + softwareType, + position: positionVsParent, + registeredAt: Date.now(), + }; +} + +function makeRoot(children) { + const map = new Map(); + for (const c of children) map.set(c.child.config.general.id, c); + return { + config: { + general: { id: 'root-1', name: 'Root' }, + functionality: { softwareType: 'dashboardapi', positionVsParent: 'atequipment' }, + }, + childRegistrationUtils: { registeredChildren: map }, + }; +} + +test('generateDashboardsForGraph composes 50 children in <500ms', () => { + const api = new DashboardApi({}); + const children = Array.from({ length: 50 }, (_, i) => makeChild(i)); + const root = makeRoot(children); + + const t0 = process.hrtime.bigint(); + const dashboards = api.generateDashboardsForGraph(root, { includeChildren: true }); + const t1 = process.hrtime.bigint(); + + const durationMs = Number(t1 - t0) / 1e6; + assert.ok(durationMs < 500, `composition took ${durationMs.toFixed(1)}ms, expected <500ms`); + assert.ok(dashboards.length >= 1, 'should produce at least the root dashboard'); +}); + +test('uids are unique across all generated dashboards (no collision risk)', () => { + const api = new DashboardApi({}); + const children = Array.from({ length: 30 }, (_, i) => makeChild(i, 'measurement')); + const root = makeRoot(children); + const dashboards = api.generateDashboardsForGraph(root); + const uids = dashboards.map((d) => d.uid); + const unique = new Set(uids); + assert.equal(unique.size, uids.length, `expected ${uids.length} unique uids, got ${unique.size}`); +}); + +test('byte-identical composition under repeat (idempotency)', () => { + const api = new DashboardApi({}); + const children = Array.from({ length: 5 }, (_, i) => makeChild(i)); + const root = makeRoot(children); + const first = JSON.stringify(api.generateDashboardsForGraph(root).map((d) => d.dashboard)); + const second = JSON.stringify(api.generateDashboardsForGraph(root).map((d) => d.dashboard)); + assert.equal(first, second, 'two consecutive compositions should produce byte-identical JSON'); +}); + +test('root dashboard links to every child dashboard', () => { + const api = new DashboardApi({}); + const children = Array.from({ length: 4 }, (_, i) => makeChild(i)); + const root = makeRoot(children); + const dashboards = api.generateDashboardsForGraph(root); + const rootDash = dashboards[0].dashboard; + assert.ok(Array.isArray(rootDash.links), 'root dashboard should have links array'); + assert.equal(rootDash.links.length, 4, 'one link per registered child'); +});