- Delete .cursor/rules/boardui.mdc (rules live in AGENTS.md) and package-lock.json; README now uses bun install/dev/test/build - Remove migrateV1Slots, the v1 localStorage key, the legacy "asian" cuisine expansion, the ownsPantryStaples fallback, and the pre-BoardUI theme-key carryover in the layout init script; drop their tests Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
72 lines
3.1 KiB
TypeScript
72 lines
3.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import type { MealPlanState } from "@/app/types";
|
|
import { activeRecipeIds, mealKindFor, mealLabel, visibleMeals } from "./plan";
|
|
import { DEFAULT_STATE } from "./sanitize";
|
|
import { RECIPES } from "./recipes";
|
|
import { planReducer } from "./usePlanState";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Meal slots. Regression tests for the "change meals per day and your
|
|
// breakfast turns into lunch" bug. Meal numbers are fixed:
|
|
// 1 = Breakfast, 2 = Lunch, 3 = Dinner
|
|
// and "meals per day" only decides which ones you can see.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// Any real recipes will do; names are just for readability.
|
|
const PANCAKES = RECIPES.find((r) => r.kind === "breakfast")!.id;
|
|
const [SANDWICH, STEW] = RECIPES.filter((r) => r.kind === "main").map((r) => r.id);
|
|
|
|
/** Monday with all three meals planned. */
|
|
const fullMonday: MealPlanState = {
|
|
...DEFAULT_STATE,
|
|
daysCount: 1,
|
|
mealsPerDay: 3,
|
|
slots: { "0-1": PANCAKES, "0-2": SANDWICH, "0-3": STEW },
|
|
};
|
|
|
|
/** What the grid shows, as "Label: recipe". */
|
|
function visibleGrid(state: MealPlanState): string[] {
|
|
return visibleMeals(state.mealsPerDay).map((meal) => `${mealLabel(meal)}: ${state.slots[`0-${meal}`] ?? "—"}`);
|
|
}
|
|
|
|
describe("visible meals", () => {
|
|
test("fewer meals hides from the front of the day", () => {
|
|
expect(visibleMeals(3).map(mealLabel)).toEqual(["Breakfast", "Lunch", "Dinner"]);
|
|
expect(visibleMeals(2).map(mealLabel)).toEqual(["Lunch", "Dinner"]);
|
|
expect(visibleMeals(1).map(mealLabel)).toEqual(["Dinner"]);
|
|
});
|
|
|
|
test("only meal 1 is breakfast", () => {
|
|
expect([1, 2, 3].map(mealKindFor)).toEqual(["breakfast", "main", "main"]);
|
|
});
|
|
});
|
|
|
|
describe("changing meals per day", () => {
|
|
test("3 → 2 keeps lunch as lunch and dinner as dinner", () => {
|
|
const state = planReducer(fullMonday, { type: "setMealsPerDay", value: 2 });
|
|
expect(visibleGrid(state)).toEqual([`Lunch: ${SANDWICH}`, `Dinner: ${STEW}`]);
|
|
});
|
|
|
|
test("3 → 1 → 3 brings breakfast and lunch back (nothing deleted)", () => {
|
|
const down = planReducer(fullMonday, { type: "setMealsPerDay", value: 1 });
|
|
expect(visibleGrid(down)).toEqual([`Dinner: ${STEW}`]);
|
|
|
|
const backUp = planReducer(down, { type: "setMealsPerDay", value: 3 });
|
|
expect(visibleGrid(backUp)).toEqual([`Breakfast: ${PANCAKES}`, `Lunch: ${SANDWICH}`, `Dinner: ${STEW}`]);
|
|
});
|
|
|
|
test("hidden meals don't count toward the cart", () => {
|
|
expect(activeRecipeIds({ ...fullMonday, mealsPerDay: 1 })).toEqual([STEW]);
|
|
expect(activeRecipeIds({ ...fullMonday, mealsPerDay: 2 })).toEqual([SANDWICH, STEW]);
|
|
});
|
|
});
|
|
|
|
describe("Clear", () => {
|
|
test("empties the visible grid but keeps hidden meals", () => {
|
|
const lunchAndDinner = { ...fullMonday, mealsPerDay: 2 };
|
|
const cleared = planReducer(lunchAndDinner, { type: "clearSlots" });
|
|
|
|
expect(visibleGrid(cleared)).toEqual(["Lunch: —", "Dinner: —"]);
|
|
expect(cleared.slots).toEqual({ "0-1": PANCAKES }); // breakfast was hidden, so untouched
|
|
});
|
|
});
|