const test = require('node:test'); const assert = require('node:assert/strict'); const { calcBestCombination } = require('../../src/optimizer/bestCombination'); function makeMachine({ id, fMin = 0, fMax = 100, NCog = 0.5, costFn } = {}) { return { config: { general: { id } }, NCog, predictFlow: { currentFxyYMin: fMin, currentFxyYMax: fMax }, predictPower: { currentFxyYMin: 0, currentFxyYMax: fMax * 2 }, // Power model: caller picks the cost function so we can shape who wins. inputFlowCalcPower: costFn ?? ((flow) => flow * 1.0), }; } function mkCtx(machines) { return { machines, groupCurves: { groupFlow: (m) => m.predictFlow, groupPower: (m) => m.predictPower, groupNCog: (m) => m.NCog ?? 0, groupCalcPower: (m, f) => m.inputFlowCalcPower(f), }, logger: { debug: () => {} }, }; } test('calcBestCombination: 1 machine in combination receives Qd clamped to its range', () => { const machines = { a: makeMachine({ id: 'a', fMin: 5, fMax: 60 }) }; const ctx = mkCtx(machines); const res = calcBestCombination([['a']], 40, ctx); assert.ok(res.bestCombination); assert.equal(res.bestCombination.length, 1); assert.equal(res.bestCombination[0].flow, 40); // Above max — clamps to max. const high = calcBestCombination([['a']], 200, ctx); assert.equal(high.bestCombination[0].flow, 60); }); test('calcBestCombination: 2 machines with equal NCog split flow evenly', () => { const machines = { a: makeMachine({ id: 'a', NCog: 0.5, fMin: 0, fMax: 100 }), b: makeMachine({ id: 'b', NCog: 0.5, fMin: 0, fMax: 100 }), }; const ctx = mkCtx(machines); const res = calcBestCombination([['a', 'b']], 40, ctx); const aFlow = res.bestCombination.find(e => e.machineId === 'a').flow; const bFlow = res.bestCombination.find(e => e.machineId === 'b').flow; assert.ok(Math.abs(aFlow - bFlow) < 1e-6, `expected even split, got a=${aFlow} b=${bFlow}`); assert.ok(Math.abs(aFlow + bFlow - 40) < 1e-6); }); test('calcBestCombination: returns combination with the lowest total power', () => { // Two combinations: [a] (expensive) vs [b] (cheap). Both can deliver Qd=20. const machines = { a: makeMachine({ id: 'a', fMin: 0, fMax: 100, costFn: (f) => f * 10 }), b: makeMachine({ id: 'b', fMin: 0, fMax: 100, costFn: (f) => f * 1 }), }; const ctx = mkCtx(machines); const res = calcBestCombination([['a'], ['b']], 20, ctx); assert.equal(res.bestCombination[0].machineId, 'b'); assert.equal(res.bestPower, 20); });