Files
pumpingStation/test/basic/BasinGeometry.basic.test.js

107 lines
3.4 KiB
JavaScript
Raw Normal View History

// Basic unit tests for BasinGeometry.
// Run with: node --test test/basic/BasinGeometry.basic.test.js
const test = require('node:test');
const assert = require('node:assert/strict');
const BasinGeometry = require('../../src/basin/BasinGeometry');
function makeBasin(overrides = {}) {
const basin = {
volume: 50,
height: 5,
inflowLevel: 3,
outflowLevel: 0.2,
overflowLevel: 4.5,
...overrides.basin,
};
const hydraulics = {
minHeightBasedOn: 'outlet',
...overrides.hydraulics,
};
return new BasinGeometry(basin, hydraulics);
}
test('constructor produces correct surfaceArea = volume / height', () => {
const g = makeBasin();
assert.equal(g.surfaceArea, 10); // 50 / 5
assert.equal(g.heightBasin, 5);
assert.equal(g.volEmptyBasin, 50);
});
test('maxVolAtOverflow equals overflowLevel × surfaceArea', () => {
const g = makeBasin();
assert.equal(g.maxVolAtOverflow, 4.5 * 10); // 45
assert.equal(g.minVolAtInflow, 3 * 10); // 30
assert.equal(g.minVolAtOutflow, 0.2 * 10); // 2
assert.equal(g.maxVol, 50);
});
test("minVol selects outlet-based when minHeightBasedOn = 'outlet'", () => {
const g = makeBasin();
assert.equal(g.minVol, g.minVolAtOutflow);
assert.equal(g.minHeightBasedOn, 'outlet');
});
test("minVol selects inlet-based when minHeightBasedOn = 'inlet'", () => {
const g = makeBasin({ hydraulics: { minHeightBasedOn: 'inlet' } });
assert.equal(g.minVol, g.minVolAtInflow);
assert.equal(g.minHeightBasedOn, 'inlet');
});
test('volumeFromLevel(0) returns 0; negative level clamps to 0', () => {
const g = makeBasin();
assert.equal(g.volumeFromLevel(0), 0);
assert.equal(g.volumeFromLevel(-1), 0);
assert.equal(g.volumeFromLevel(-1e9), 0);
});
test('volumeFromLevel(positive) is level × surfaceArea', () => {
const g = makeBasin();
assert.equal(g.volumeFromLevel(2.5), 25);
assert.equal(g.volumeFromLevel(5), 50);
});
test('levelFromVolume(maxVol) returns heightBasin', () => {
const g = makeBasin();
assert.equal(g.levelFromVolume(g.maxVol), g.heightBasin);
});
test('levelFromVolume(0) returns 0; negative volume clamps to 0', () => {
const g = makeBasin();
assert.equal(g.levelFromVolume(0), 0);
assert.equal(g.levelFromVolume(-10), 0);
});
test('round-trip: volumeFromLevel(levelFromVolume(v)) ≈ v for v in range', () => {
const g = makeBasin();
for (const v of [0, 0.001, 1, 12.34, 25, 49.999, 50]) {
const back = g.volumeFromLevel(g.levelFromVolume(v));
assert.ok(Math.abs(back - v) < 1e-9, `round-trip failed for v=${v}, got ${back}`);
}
});
test('round-trip: levelFromVolume(volumeFromLevel(L)) ≈ L for L in range', () => {
const g = makeBasin();
for (const L of [0, 0.05, 1, 2.5, 4.5, 5]) {
const back = g.levelFromVolume(g.volumeFromLevel(L));
assert.ok(Math.abs(back - L) < 1e-9, `round-trip failed for L=${L}, got ${back}`);
}
});
test('snapshot() exposes legacy this.basin field names', () => {
const g = makeBasin();
const s = g.snapshot();
const expectedKeys = [
'volEmptyBasin', 'heightBasin', 'inflowLevel', 'outflowLevel',
'overflowLevel', 'surfaceArea', 'maxVol', 'maxVolAtOverflow',
'minVolAtInflow', 'minVolAtOutflow', 'minVol', 'minHeightBasedOn',
];
for (const k of expectedKeys) {
assert.ok(k in s, `snapshot missing key: ${k}`);
}
assert.equal(s.volEmptyBasin, 50);
assert.equal(s.surfaceArea, 10);
assert.equal(s.minHeightBasedOn, 'outlet');
});