Files
roast_command_center/test/bean-bro-context.test.js
T
snowspeeder eda3d8e77f
Test and deploy / test-and-deploy (push) Successful in 1m23s
Add explicit per-plan gauge temperature offset
2026-09-07 07:39:33 -04:00

59 lines
3.3 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import {buildPlanChatContext,partialReply} from "../server/plan-chat.js";
import {blankPlan} from "../shared/fields.js";
import {buildPlanCurve} from "../shared/curve.js";
import {computeLedger} from "../shared/ledger.js";
test("Bean Bro sees the displayed 392°F first crack even with blank raw temperatures",()=>{
const p=blankPlan();Object.assign(p.fields,{"1.4":"8:45","3.2":"-0:30","4.3":"1:38","4.1":"light"});
const ctx=buildPlanChatContext(p);
const fc=ctx.displayedMilestones.find(p=>p.event==="fc");
assert.equal(fc.tempF,392);assert.equal(fc.time,"8:45");assert.equal(fc.temperatureSource,"illustrative");
assert.equal(ctx.computedLedger.timingBreakdown.development.processAdjustmentS,-30);
assert.equal(ctx.computedLedger.developmentS,75);
for(const point of buildPlanCurve(p,computeLedger(p))) {
const item=ctx.displayedMilestones.find(i=>i.event===point.key);
assert.equal(item.tempC,point.tempC);assert.equal(item.timeS,point.timeS);
}
});
test("Bean Bro distinguishes entered targets, preheat and actual measurements without machine scaling",()=>{
const p=blankPlan();p.fields["1.4"]="8:45";p.fields["4.4"]="1:20";
p.temps.fc.tempC="195";p.preheat.tempC="175";p.planActual.fc.actualBt="171.111111";p.planActual.fc.actualTime="7:05";
const ctx=buildPlanChatContext(p);
assert.equal(ctx.displayedMilestones.find(p=>p.event==="fc").tempF,383);
assert.equal(ctx.displayedMilestones.find(p=>p.event==="fc").temperatureSource,"entered");
assert.equal(ctx.preheatSetpointF,347);assert.equal(ctx.recordedMilestones.find(p=>p.event==="fc").actualBtF,340);
assert.equal(buildPlanChatContext(blankPlan()).displayedMilestones.some(p=>p.event==="fc"),false);
});
test("streaming JSON decoder exposes only reply text and handles split escapes",()=>{
const text='The "FC" is 392°F.\nUse actual crack.';
const raw=JSON.stringify({reply:text,suggestions:[{fields:{"4.4":"1:20"}}]});
for(let i=0;i<=raw.length;i++) assert.ok(text.startsWith(partialReply(raw.slice(0,i))));
assert.equal(partialReply(raw),text);
assert.equal(partialReply('{"reply":"392\\u00'),"392");
assert.equal(partialReply('{"reply":"392\\u00b0F"}'),"392°F");
});
test("a manual gauge offset shifts illustrative events exactly once and reaches Bean Bro",()=>{
const p=blankPlan();p.fields["1.4"]="8:45";p.fields["4.4"]="1:20";
const original=buildPlanCurve(p,computeLedger(p));
p.temperatureOffsetF="-50";
const shifted=buildPlanCurve(p,computeLedger(p));
for(let i=0;i<original.length;i++){
assert.ok(Math.abs((shifted[i].tempC-original[i].tempC)*1.8+50)<1e-8);
assert.equal(shifted[i].timeS,original[i].timeS);
}
const ctx=buildPlanChatContext(p);
assert.equal(ctx.temperatureOffsetF,-50);
assert.equal(ctx.displayedMilestones.find(p=>p.event==="fc").tempF,342);
p.temps.fc.tempC="190";p.preheat.tempC="175";p.planActual.fc.actualBt="171.111111";
const entered=buildPlanChatContext(p);
assert.equal(entered.displayedMilestones.find(p=>p.event==="fc").tempF,374);
assert.equal(entered.preheatSetpointF,347);
assert.equal(entered.recordedMilestones.find(p=>p.event==="fc").actualBtF,340);
p.temperatureOffsetF="";delete p.temps.fc.tempC;
assert.deepEqual(buildPlanCurve(p,computeLedger(p)),original);
p.temperatureOffsetF="25";
assert.equal(buildPlanChatContext(p).displayedMilestones.find(p=>p.event==="fc").tempF,417);
});