P11.6 wiki regen + Phase 10 private-test rewrites where applicable
For all 11 nodes with auto-gen markers: wiki/Home.md sections 5 (topic contract) and 9 (data model) regenerated via npm run wiki:all. New Unit column shows '<measure> (default <unit>)' for declared topics, '—' otherwise. Effect column now uses descriptor.description (P11.2 field) overriding the generic per-prefix fallback. For rotatingMachine + reactor: Phase 10 test rewrites — 3 + 8 files moved off private nodeClass internals (_attachInputHandler, _commands, _pendingExtras, _registerChild, _tick, etc.) to the public BaseNodeAdapter surface (node.handlers.input, node.source.*). +6 / +7 net new tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,38 @@ const assert = require('node:assert/strict');
|
||||
|
||||
const Machine = require('../../src/specificClass');
|
||||
const NodeClass = require('../../src/nodeClass');
|
||||
const { makeMachineConfig, makeStateConfig, makeNodeStub } = require('../helpers/factories');
|
||||
const { makeMachineConfig, makeStateConfig, makeNodeStub, makeREDStub } = require('../helpers/factories');
|
||||
|
||||
function makeUiConfig(overrides = {}) {
|
||||
return {
|
||||
unit: 'm3/h', enableLog: false, logLevel: 'error',
|
||||
supplier: 'hidrostal', category: 'machine', assetType: 'pump',
|
||||
model: 'hidrostal-H05K-S03R',
|
||||
curvePressureUnit: 'mbar', curveFlowUnit: 'm3/h',
|
||||
curvePowerUnit: 'kW', curveControlUnit: '%',
|
||||
positionVsParent: 'atEquipment',
|
||||
speed: 1, movementMode: 'staticspeed',
|
||||
startup: 0, warmup: 0, shutdown: 0, cooldown: 0,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
// Adapters park a periodic status-poll timer. Drive the BaseNodeAdapter
|
||||
// close handler after each test to stop it — the public teardown path
|
||||
// used by Node-RED itself on flow shutdown.
|
||||
const _adapters = [];
|
||||
function buildAdapter(ui = makeUiConfig()) {
|
||||
const node = makeNodeStub();
|
||||
const inst = new NodeClass(ui, makeREDStub(), node, 'rotatingMachine');
|
||||
_adapters.push(node);
|
||||
return { inst, node };
|
||||
}
|
||||
test.afterEach(() => {
|
||||
while (_adapters.length) {
|
||||
const node = _adapters.pop();
|
||||
try { node._handlers.close?.(() => {}); } catch (_) { /* best effort */ }
|
||||
}
|
||||
});
|
||||
|
||||
test('setpoint rejects negative inputs without throwing', async () => {
|
||||
const machine = new Machine(makeMachineConfig(), makeStateConfig({ state: { current: 'operational' } }));
|
||||
@@ -35,16 +66,15 @@ test('setpoint is constrained to safe movement/curve bounds', async () => {
|
||||
});
|
||||
|
||||
test('source.getStatusBadge returns error status on internal failure', () => {
|
||||
// Status badge lives on the domain post-refactor. Build a tiny stub
|
||||
// that throws to verify the error-path returns an error badge.
|
||||
// Build the full adapter, then force the source's state.getCurrentState
|
||||
// to throw — the public getStatusBadge() must catch and return an
|
||||
// error badge without propagating.
|
||||
const { inst } = buildAdapter();
|
||||
const errors = [];
|
||||
const source = {
|
||||
currentMode: 'auto',
|
||||
state: { getCurrentState() { throw new Error('boom'); } },
|
||||
logger: { error: (m) => errors.push(m) },
|
||||
};
|
||||
const { buildStatusBadge } = require('../../src/io/output');
|
||||
const status = buildStatusBadge(source);
|
||||
inst.source.logger.error = (m) => errors.push(m);
|
||||
inst.source.state.getCurrentState = () => { throw new Error('boom'); };
|
||||
|
||||
const status = inst.source.getStatusBadge();
|
||||
assert.match(status.text, /Status Error/);
|
||||
assert.equal(status.fill, 'red');
|
||||
assert.equal(errors.length, 1);
|
||||
|
||||
Reference in New Issue
Block a user