Files
rotatingMachine/test/basic/operatingPoint.basic.test.js
znetsixe c5bb375dd0 P5 wave 1: extract rotatingMachine concerns into focused modules
src/curves/         loader + normalizer (with cross-pressure anomaly
                      detection) + reverseCurve helper
  src/prediction/     predictors (predictFlow/Power/Ctrl) +
                      groupPredictors (lazy group-scope views) +
                      OperatingPoint (pressure-driven prediction setpoints)
  src/drift/          DriftAssessor (per-metric drift) + PredictionHealth
                      (composes flow/power/pressure into HealthStatus +
                      confidence sibling — see OPEN_QUESTIONS 2026-05-10)
  src/pressure/       VirtualPressureChildren (dashboard-sim) +
                      PressureInitialization (real-vs-virtual tracking) +
                      PressureRouter (dispatches by position)
  src/state/          stateBindings (state.emitter listener helper) +
                      isOperationalState
  src/measurement/    measurementHandlers (dispatcher for flow/power/temp/pressure)
  src/flow/           flowController (handleInput body — execSequence,
                      execMovement, flowMovement, emergencystop)
  src/display/        workingCurves (showWorkingCurves + showCoG admin)
  src/commands/       canonical names: set.mode, cmd.startup/shutdown/estop,
                      set.setpoint, set.flow-setpoint,
                      data.simulate-measurement, query.curves, query.cog,
                      child.register. execSequence demuxes by payload.action
                      to canonical cmd.* handlers.
  CONTRACT.md         inputs/outputs/events/children surface

110 basic tests pass (100 new + 10 pre-existing).
specificClass.js / nodeClass.js untouched — integration in P5 wave 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:38:45 +02:00

74 lines
2.7 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const { buildPredictors } = require('../../src/prediction/predictors');
const { buildGroupPredictors } = require('../../src/prediction/groupPredictors');
const OperatingPoint = require('../../src/prediction/operatingPoint');
function makeCanonicalCurve() {
return {
nq: {
100000: { x: [0, 50, 100], y: [0, 0.005, 0.01] },
120000: { x: [0, 50, 100], y: [0, 0.006, 0.012] },
},
np: {
100000: { x: [0, 50, 100], y: [0, 500, 1000] },
120000: { x: [0, 50, 100], y: [0, 600, 1200] },
},
};
}
test('OperatingPoint.setIndividual: updates working pressure on all three predictors', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const op = new OperatingPoint(predictors);
const ok = op.setIndividual(100000);
assert.equal(ok, true);
assert.equal(predictors.predictFlow.currentF, 100000);
assert.equal(predictors.predictPower.currentF, 100000);
assert.equal(predictors.predictCtrl.currentF, 100000);
});
test('OperatingPoint.setIndividual: rejects non-finite pressure', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const op = new OperatingPoint(predictors);
assert.equal(op.setIndividual(NaN), false);
assert.equal(op.setIndividual('not-a-number'), false);
});
test('OperatingPoint.setGroup: no-op when group predictors absent', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const op = new OperatingPoint(predictors, null);
assert.equal(op.setGroup(100000), false);
});
test('OperatingPoint.setGroup: updates only group predictors', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const group = buildGroupPredictors(predictors);
const op = new OperatingPoint(predictors, group);
predictors.predictFlow.fDimension = 120000;
op.setGroup(100000);
assert.equal(group.groupPredictFlow.currentF, 100000);
assert.equal(predictors.predictFlow.currentF, 120000);
});
test('OperatingPoint.flowFor: returns a finite predicted flow', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const op = new OperatingPoint(predictors);
op.setIndividual(100000);
const flow = op.flowFor(50);
assert.ok(Number.isFinite(flow), `expected finite flow, got ${flow}`);
assert.ok(flow > 0);
});
test('OperatingPoint.useGroup: switches getters to group predictors', () => {
const predictors = buildPredictors(makeCanonicalCurve());
const group = buildGroupPredictors(predictors);
const op = new OperatingPoint(predictors, group);
op.setIndividual(100000);
op.setGroup(120000);
const indivFlow = op.useIndividual().flowFor(50);
const groupFlow = op.useGroup().flowFor(50);
assert.ok(Number.isFinite(indivFlow));
assert.ok(Number.isFinite(groupFlow));
});