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,68 +1,61 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const { Reactor_CSTR } = require('../../src/specificClass');
const nodeClass = require('../../src/nodeClass');
const { makeReactorConfig, makeUiConfig, makeNodeStub, makeREDStub } = require('../helpers/factories');
/**
* Smoke tests for Fix 3: configurable speedUpFactor on Reactor.
*/
test('specificClass defaults speedUpFactor to 1 when not in config', () => {
const config = makeReactorConfig();
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 1, 'speedUpFactor should default to 1');
});
test('specificClass accepts speedUpFactor from config', () => {
const config = makeReactorConfig();
config.speedUpFactor = 10;
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 10, 'speedUpFactor should be read from config');
});
test('specificClass accepts speedUpFactor = 60 for accelerated simulation', () => {
const config = makeReactorConfig();
config.speedUpFactor = 60;
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 60, 'speedUpFactor=60 should be accepted');
});
test('nodeClass passes speedUpFactor from uiConfig to reactor config', () => {
const uiConfig = makeUiConfig({ speedUpFactor: 5 });
const node = makeNodeStub();
const RED = makeREDStub();
const nc = new nodeClass(uiConfig, RED, node, 'test-reactor');
assert.equal(nc.source.speedUpFactor, 5, 'nodeClass should pass speedUpFactor=5 to specificClass');
});
test('nodeClass defaults speedUpFactor to 1 when not in uiConfig', () => {
const uiConfig = makeUiConfig();
// Ensure speedUpFactor is not set
delete uiConfig.speedUpFactor;
const node = makeNodeStub();
const RED = makeREDStub();
const nc = new nodeClass(uiConfig, RED, node, 'test-reactor');
assert.equal(nc.source.speedUpFactor, 1, 'nodeClass should default speedUpFactor to 1');
});
test('updateState with speedUpFactor=1 advances roughly real-time', () => {
const config = makeReactorConfig();
config.speedUpFactor = 1;
config.n_inlets = 1;
const reactor = new Reactor_CSTR(config);
// Set a known start time
const t0 = reactor.currentTime;
// Advance by 2 seconds real time
reactor.updateState(t0 + 2000);
// With speedUpFactor=1, simulation should have advanced ~2 seconds worth
// (not 120 seconds like with the old hardcoded 60x factor)
const elapsed = reactor.currentTime - t0;
assert.ok(elapsed < 5000, `Elapsed ${elapsed}ms should be close to 2000ms, not 120000ms (old 60x factor)`);
});
const test = require('node:test');
const assert = require('node:assert/strict');
const { Reactor_CSTR } = require('../../src/specificClass');
const NodeClass = require('../../src/nodeClass');
const { makeReactorConfig, makeUiConfig } = require('../helpers/factories');
/**
* Smoke tests for Fix 3: configurable speedUpFactor on Reactor.
*/
test('specificClass defaults speedUpFactor to 1 when not in config', () => {
const config = makeReactorConfig();
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 1, 'speedUpFactor should default to 1');
});
test('specificClass accepts speedUpFactor from config', () => {
const config = makeReactorConfig();
config.speedUpFactor = 10;
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 10, 'speedUpFactor should be read from config');
});
test('specificClass accepts speedUpFactor = 60 for accelerated simulation', () => {
const config = makeReactorConfig();
config.speedUpFactor = 60;
const reactor = new Reactor_CSTR(config);
assert.equal(reactor.speedUpFactor, 60, 'speedUpFactor=60 should be accepted');
});
test('buildDomainConfig propagates speedUpFactor from uiConfig', () => {
const inst = Object.create(NodeClass.prototype);
inst.node = { id: 'n-reactor' };
inst.name = 'reactor';
const dc = inst.buildDomainConfig(makeUiConfig({ speedUpFactor: 5 }));
assert.equal(dc.reactor.speedUpFactor, 5);
});
test('buildDomainConfig defaults speedUpFactor to 1 when missing from uiConfig', () => {
const inst = Object.create(NodeClass.prototype);
inst.node = { id: 'n-reactor' };
inst.name = 'reactor';
const ui = makeUiConfig();
delete ui.speedUpFactor;
const dc = inst.buildDomainConfig(ui);
assert.equal(dc.reactor.speedUpFactor, 1);
});
test('updateState with speedUpFactor=1 advances roughly real-time', () => {
const config = makeReactorConfig();
config.speedUpFactor = 1;
config.n_inlets = 1;
const reactor = new Reactor_CSTR(config);
const t0 = reactor.currentTime;
reactor.updateState(t0 + 2000);
const elapsed = reactor.currentTime - t0;
assert.ok(elapsed < 5000, `Elapsed ${elapsed}ms should be close to 2000ms, not 120000ms (old 60x factor)`);
});