fix: recalibrate Neapolitan yeast for v1.1
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const vm = require('node:vm');
|
||||
|
||||
const html = fs.readFileSync(path.join(__dirname, '..', 'index.html'), 'utf8');
|
||||
|
||||
function between(start, end) {
|
||||
const from = html.indexOf(start);
|
||||
const to = html.indexOf(end, from);
|
||||
assert.ok(from >= 0 && to > from, `Quellbereich fehlt: ${start} … ${end}`);
|
||||
return html.slice(from, to);
|
||||
}
|
||||
|
||||
const core = between('const STYLES =', '/* ============================================================\n ZEITPLAN');
|
||||
const simple = between('function applySimpleFermentation()', 'function initUI()');
|
||||
const warnings = between('function renderWarnings(', 'function renderRecipe(');
|
||||
const fixedNow = 1_700_000_000_000;
|
||||
class FixedDate extends Date {
|
||||
static now() { return fixedNow; }
|
||||
}
|
||||
const warningHost = { innerHTML: '' };
|
||||
const sandbox = {
|
||||
Date: FixedDate,
|
||||
console,
|
||||
$: id => id === 'warns' ? warningHost : {},
|
||||
pct: x => `${x} %`,
|
||||
n1: x => String(x),
|
||||
};
|
||||
vm.createContext(sandbox);
|
||||
vm.runInContext(`${core}\n${simple}\n${warnings}\nglobalThis.api={STYLES,DEFAULT,calc,applySimpleFermentation,renderWarnings,setState:s=>S=s,getState:()=>S};`, sandbox);
|
||||
const { STYLES, DEFAULT, calc, applySimpleFermentation, renderWarnings, setState, getState } = sandbox.api;
|
||||
|
||||
function state(overrides = {}) {
|
||||
return { ...DEFAULT, pf: 'none', yeast: 'fresh', balls: 4, ball: 250, mode: 'w', ...overrides };
|
||||
}
|
||||
|
||||
// Napoletana und Contemporanea werden bewusst niedriger kalibriert.
|
||||
assert.equal(STYLES.napo.yeastK, 1.5);
|
||||
assert.equal(STYLES.contemp.yeastK, 1.7);
|
||||
|
||||
// 8 h warme Napoletana bei 20 °C: rund 0,19 % Frischhefe statt bisher 0,76 %.
|
||||
const napo8 = calc(state({ style: 'napo', seq: 'room', roomH: 8, roomT: 20, fridgeH: 0 }));
|
||||
assert.ok(Math.abs(napo8.yPct - 0.190875) < 1e-9, `unerwartet: ${napo8.yPct}%`);
|
||||
assert.ok(napo8.main.yeast > 1.1 && napo8.main.yeast < 1.2, `unerwartet: ${napo8.main.yeast} g`);
|
||||
|
||||
// Nicht neu kalibrierte Stile behalten den bisherigen Referenzfaktor 6.
|
||||
const ny8 = calc(state({ style: 'ny', salt: 2, seq: 'room', roomH: 8, roomT: 20, fridgeH: 0 }));
|
||||
assert.equal(ny8.yPct, 0.75);
|
||||
|
||||
// Lange Führung im Einfach-Modus endet mit 4 h warmer Stückgare.
|
||||
setState(state({ uxMode: 'simple', bake: fixedNow + 24.75 * 3600e3 }));
|
||||
applySimpleFermentation();
|
||||
assert.equal(getState().seq, 'coldwarm');
|
||||
assert.equal(getState().roomH, 4);
|
||||
assert.equal(getState().fridgeH, 20);
|
||||
|
||||
setState(state({ uxMode: 'simple', bake: fixedNow + 48.75 * 3600e3 }));
|
||||
applySimpleFermentation();
|
||||
assert.equal(getState().roomH, 4);
|
||||
assert.equal(getState().fridgeH, 44);
|
||||
|
||||
// Unter 4 h wird Napoletana ausdrücklich als Schnellteig gekennzeichnet.
|
||||
const napo3State = state({ style: 'napo', seq: 'room', roomH: 3, roomT: 20, fridgeH: 0 });
|
||||
setState(napo3State);
|
||||
const napo3 = calc(napo3State);
|
||||
renderWarnings({ n: 'Testmehl', reife: [0, 120], hyd: [50, 90], vt: true }, napo3);
|
||||
assert.match(warningHost.innerHTML, /Schnellteig/);
|
||||
|
||||
// Kleine absolute Hefemengen nennen die Feinwaage, auch wenn der Prozentwert über 0,03 % liegt.
|
||||
const napo24State = state({ style: 'napo', seq: 'room', roomH: 24, roomT: 20, fridgeH: 0 });
|
||||
setState(napo24State);
|
||||
const napo24 = calc(napo24State);
|
||||
assert.ok(napo24.main.yeast < 0.5 && napo24.yPct > 0.03);
|
||||
renderWarnings({ n: 'Testmehl', reife: [0, 120], hyd: [50, 90], vt: true }, napo24);
|
||||
assert.match(warningHost.innerHTML, /Feinwaage/);
|
||||
|
||||
console.log('yeast calibration regression tests: OK');
|
||||
Reference in New Issue
Block a user