const test = require('node:test'); const assert = require('node:assert/strict'); const { predict } = require('generalFunctions'); const { buildPredictors } = require('../../src/prediction/predictors'); function makeCanonicalCurve() { // Canonical units already applied: pressure Pa, flow m3/s, power W, // x-axis is control %. Two pressure levels, monotonically rising y. 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('buildPredictors: returns three Predict instances', () => { const predictors = buildPredictors(makeCanonicalCurve()); assert.ok(predictors.predictFlow instanceof predict); assert.ok(predictors.predictPower instanceof predict); assert.ok(predictors.predictCtrl instanceof predict); }); test('buildPredictors: predictFlow yMax/yMin reflect input range', () => { const predictors = buildPredictors(makeCanonicalCurve()); // After buildAllFxyCurves the fDimension is initialised to fValues.min. // currentFxyYMin/Max are the y-range at that pressure curve. assert.ok(Number.isFinite(predictors.predictFlow.currentFxyYMax)); assert.ok(Number.isFinite(predictors.predictFlow.currentFxyYMin)); assert.ok(predictors.predictFlow.currentFxyYMax > predictors.predictFlow.currentFxyYMin); }); test('buildPredictors: predictCtrl is built from reversed nq (flow->ctrl mapping)', () => { const predictors = buildPredictors(makeCanonicalCurve()); // predictCtrl's x-axis values must come from y-values in nq. // sanity-check via currentFxyXMax being in the flow range assert.ok(predictors.predictCtrl.currentFxyXMax <= 0.02, // flow range upper bound `expected predictCtrl xMax in flow-range, got ${predictors.predictCtrl.currentFxyXMax}`); }); test('buildPredictors: throws when machineCurve is missing nq or np', () => { assert.throws(() => buildPredictors(null), /machineCurve\.nq and \.np are required/); assert.throws(() => buildPredictors({ nq: {} }), /required/); });