Fas 3 steg 3b: minimala efterfrågor + hushållsantagandeprofiler per ingrediens
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { updateCookingAssumptionProfile } from "../src/cooking-profiles.js";
|
||||
|
||||
describe("updateCookingAssumptionProfile", () => {
|
||||
it("initializes profile from first observation", () => {
|
||||
const result = updateCookingAssumptionProfile(
|
||||
{
|
||||
householdId: "h1",
|
||||
canonicalIngredientId: "i1",
|
||||
plannedPortions: 4,
|
||||
actualPortionsEaten: 3,
|
||||
leftoverEstimatePortions: 1,
|
||||
sessionId: "s1",
|
||||
date: "2026-08-07",
|
||||
},
|
||||
{ averageEatenPortions: null, averageLeftoverPortions: null, observationCount: 0 },
|
||||
);
|
||||
expect(result.averageEatenPortions).toBe(3);
|
||||
expect(result.averageLeftoverPortions).toBe(1);
|
||||
expect(result.observationCount).toBe(1);
|
||||
});
|
||||
|
||||
it("clamps eaten and leftovers to valid ranges", () => {
|
||||
const result = updateCookingAssumptionProfile(
|
||||
{
|
||||
householdId: "h1",
|
||||
canonicalIngredientId: "i1",
|
||||
plannedPortions: 4,
|
||||
actualPortionsEaten: -1,
|
||||
leftoverEstimatePortions: 5,
|
||||
sessionId: "s1",
|
||||
date: "2026-08-07",
|
||||
},
|
||||
{ averageEatenPortions: 2, averageLeftoverPortions: 1, observationCount: 3 },
|
||||
);
|
||||
// Eaten clamps to 0, leftovers clamps to planned - eaten = 4.
|
||||
// alpha = 1/4, prevEaten=2 => 2 + 0.25*(0-2) = 1.5
|
||||
// prevLeftovers=1 => 1 + 0.25*(4-1) = 1.75
|
||||
expect(result.averageEatenPortions).toBe(1.5);
|
||||
expect(result.averageLeftoverPortions).toBe(1.75);
|
||||
});
|
||||
|
||||
it("keeps a rolling history of last 10 sessions", () => {
|
||||
type Profile = { averageEatenPortions: number | null; averageLeftoverPortions: number | null; observationCount: number; lastSessionAnswers?: Array<{ sessionId: string; eaten: number; leftovers: number; date: string }> | null };
|
||||
let existing: Profile = { averageEatenPortions: null, averageLeftoverPortions: null, observationCount: 0 };
|
||||
for (let i = 0; i < 12; i++) {
|
||||
existing = updateCookingAssumptionProfile(
|
||||
{
|
||||
householdId: "h1",
|
||||
canonicalIngredientId: "i1",
|
||||
plannedPortions: 4,
|
||||
actualPortionsEaten: 2,
|
||||
leftoverEstimatePortions: 1,
|
||||
sessionId: `s${i}`,
|
||||
date: "2026-08-07",
|
||||
},
|
||||
existing,
|
||||
);
|
||||
}
|
||||
expect(existing.lastSessionAnswers).toHaveLength(10);
|
||||
expect(existing.lastSessionAnswers![0]!.sessionId).toBe("s11");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user