const test = require('node:test'); const assert = require('node:assert/strict'); const Machine = require('../../src/specificClass'); const { makeMachineConfig, makeStateConfig } = require('../helpers/factories'); test('movement from 0 to 50% updates position and predictions', async () => { const machine = new Machine(makeMachineConfig(), makeStateConfig()); await machine.handleInput('parent', 'execSequence', 'startup'); assert.equal(machine.state.getCurrentState(), 'operational'); machine.updateMeasuredPressure(1000, 'downstream', { timestamp: Date.now(), unit: 'mbar', childName: 'pt' }); await machine.handleInput('parent', 'execMovement', 50); const pos = machine.state.getCurrentPosition(); const { min, max } = machine._resolveSetpointBounds(); // Position should be constrained to bounds assert.ok(pos >= min && pos <= max, `Position ${pos} should be within [${min}, ${max}]`); const flow = machine.measurements.type('flow').variant('predicted').position('downstream').getCurrentValue(); assert.ok(flow > 0, 'Predicted flow should be positive at non-zero position'); }); test('flowmovement sets position based on flow setpoint', async () => { const machine = new Machine(makeMachineConfig(), makeStateConfig()); await machine.handleInput('parent', 'execSequence', 'startup'); machine.updateMeasuredPressure(1000, 'downstream', { timestamp: Date.now(), unit: 'mbar', childName: 'pt' }); // Request 100 m3/h flow — the machine should calculate the control position await machine.handleInput('parent', 'flowMovement', 100); const pos = machine.state.getCurrentPosition(); assert.ok(pos > 0, 'Position should be non-zero for a non-zero flow setpoint'); }); test('sequential movements update position correctly', async () => { const machine = new Machine(makeMachineConfig(), makeStateConfig()); await machine.handleInput('parent', 'execSequence', 'startup'); machine.updateMeasuredPressure(1000, 'downstream', { timestamp: Date.now(), unit: 'mbar', childName: 'pt' }); await machine.handleInput('parent', 'execMovement', 30); const pos30 = machine.state.getCurrentPosition(); await machine.handleInput('parent', 'execMovement', 60); const pos60 = machine.state.getCurrentPosition(); assert.ok(pos60 > pos30, 'Position at 60 should be greater than at 30'); }); test('movement to 0 sets flow and power predictions to minimum curve values', async () => { const machine = new Machine(makeMachineConfig(), makeStateConfig()); await machine.handleInput('parent', 'execSequence', 'startup'); machine.updateMeasuredPressure(1000, 'downstream', { timestamp: Date.now(), unit: 'mbar', childName: 'pt' }); await machine.handleInput('parent', 'execMovement', 0); const pos = machine.state.getCurrentPosition(); assert.equal(pos, 0, 'Position should be at 0'); }); test('movement is rejected in non-operational state', async () => { const machine = new Machine(makeMachineConfig(), makeStateConfig()); assert.equal(machine.state.getCurrentState(), 'idle'); // Attempt movement in idle state — handleInput should process but no movement happens await machine.handleInput('parent', 'execMovement', 50); // Machine should still be idle (movement requires operational state via sequence first) assert.equal(machine.state.getCurrentState(), 'idle'); });