P6: convert reactor to platform infrastructure

Refactor of reactor to use BaseNodeAdapter + commandRegistry + statusBadge.
reactor follows the platform refactor plan in .claude/refactor/MODULE_SPLIT.md.
Tests stay green; CONTRACT.md generated; legacy aliases preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-05-10 22:23:43 +02:00
parent c5fc5c1b59
commit 7bf464b467
16 changed files with 780 additions and 919 deletions

View File

@@ -1,15 +1,21 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const NodeClass = require('../../src/nodeClass');
const { makeNodeStub, makeUiConfig } = require('../helpers/factories');
const Reactor = require('../../src/specificClass');
const { Reactor_CSTR } = require('../../src/specificClass');
test('_setupClass with unknown reactor_type throws (known error-path behavior)', () => {
const inst = Object.create(NodeClass.prototype);
inst.node = makeNodeStub();
inst.config = makeUiConfig({ reactor_type: 'UNKNOWN_TYPE' });
// Post-refactor: an unknown reactor_type falls back to CSTR and warns,
// rather than throwing.
test('Reactor wrapper falls back to CSTR when reactor_type is unknown', () => {
const config = {
general: { name: 'reactor', id: 'n', logging: { enabled: false, logLevel: 'error' } },
functionality: { softwareType: 'reactor', positionVsParent: 'atEquipment' },
reactor: { reactor_type: 'UNKNOWN_TYPE', volume: 100, length: 10, resolution_L: 5,
alpha: 0, n_inlets: 1, kla: NaN, timeStep: 1 },
initialState: { S_O: 0, S_I: 30, S_S: 100, S_NH: 16, S_N2: 0, S_NO: 0, S_HCO: 5,
X_I: 25, X_S: 75, X_H: 30, X_STO: 0, X_A: 0.001, X_TS: 125 },
};
assert.throws(() => {
inst._setupClass();
});
const r = new Reactor(config);
assert.ok(r.engine instanceof Reactor_CSTR);
});

View File

@@ -2,26 +2,27 @@ const test = require('node:test');
const assert = require('node:assert/strict');
const NodeClass = require('../../src/nodeClass');
const commands = require('../../src/commands');
const { createRegistry } = require('generalFunctions');
const { makeNodeStub, makeREDStub } = require('../helpers/factories');
test('unknown input topic does not throw and still calls done', () => {
test('unknown input topic does not throw and still calls done', async () => {
const inst = Object.create(NodeClass.prototype);
const node = makeNodeStub();
inst.node = node;
inst.RED = makeREDStub();
inst.source = {
childRegistrationUtils: {
registerChild() {},
},
logger: { warn: () => {}, info: () => {}, debug: () => {}, error: () => {} },
childRegistrationUtils: { registerChild() {} },
updateState() {},
};
inst._commands = createRegistry(commands, { logger: inst.source.logger });
inst._attachInputHandler();
let doneCalled = 0;
assert.doesNotThrow(() => {
node._handlers.input({ topic: 'somethingUnknown', payload: 1 }, () => {}, () => {
await assert.doesNotReject(async () => {
await node._handlers.input({ topic: 'somethingUnknown', payload: 1 }, () => {}, () => {
doneCalled += 1;
});
});

View File

@@ -2,24 +2,25 @@ const test = require('node:test');
const assert = require('node:assert/strict');
const NodeClass = require('../../src/nodeClass');
const commands = require('../../src/commands');
const { createRegistry } = require('generalFunctions');
const { makeNodeStub, makeREDStub } = require('../helpers/factories');
test('registerChild with unknown node id is ignored without throwing', () => {
test('registerChild with unknown node id is ignored without throwing', async () => {
const inst = Object.create(NodeClass.prototype);
const node = makeNodeStub();
inst.node = node;
inst.RED = makeREDStub();
inst.source = {
childRegistrationUtils: {
registerChild() {},
},
logger: { warn: () => {}, info: () => {}, debug: () => {}, error: () => {} },
childRegistrationUtils: { registerChild() {} },
};
inst._commands = createRegistry(commands, { logger: inst.source.logger });
inst._attachInputHandler();
assert.doesNotThrow(() => {
node._handlers.input(
await assert.doesNotReject(async () => {
await node._handlers.input(
{ topic: 'registerChild', payload: 'missing-child', positionVsParent: 'upstream' },
() => {},
() => {},