Judge the day readout by the day's kinds, not the window's

A day whose food was all unlabelled read "Fri, Sep 18 — No kind 300 g · 300 g
in total": the number twice, under a label with nothing to distinguish it from.

The guard was on the wrong quantity. It asked whether the *chart* was split,
when what decides this is how many kinds *that day* holds — and a chart split
across other days can still land on a day of one kind. Keying off the day's own
parts fixes the reported case and a second one nobody had hit yet, where a day
of a single named kind read "Dry 300 g · 300 g in total".

So: several kinds keep the total beside them, being what the bar's height shows
and what you would otherwise add up. One kind does not, because it already is
the total. And "No kind" alone drops its label, which was only ever there to
tell it apart from something else.

The new assertions were checked against the old guard, where five of them fail.
The original ones passed throughout, which is the point — they only ever
exercised a chart with one series, and this bug lives on the other axis.
This commit is contained in:
Alexander Heldt
2026-09-22 15:05:02 +00:00
parent 8c9ea45410
commit cd13efdbed
2 changed files with 43 additions and 10 deletions
+27
View File
@@ -315,6 +315,33 @@ suite("what the sentence is allowed to say");
"a day marked not counted says that instead of reading as empty"); "a day marked not counted says that instead of reading as empty");
} }
suite("a day holding only one kind");
{
// The chart is split — other days have several kinds — but this day's food
// is all one. The total is that one figure, so saying it twice is noise.
kinds = [{ id: "d", name: "Dry", colorIndex: 0 }, { id: "f", name: "Fresh", colorIndex: 1 }];
const days = [day(18, { "": 300 }), day(19, { d: 210, f: 90 }), day(20, { d: 300 })];
selected = "2026-09-18";
const unlabelled = read(days).textContent;
eq(unlabelled, "Fri, Sep 18 — 300 g.",
"a day of unlabelled food gives the bare total, on a split chart too");
ok(!/No kind/.test(unlabelled),
"…without the 'No kind' label, which has nothing to distinguish it from");
ok(!/in total/.test(unlabelled), "…and without saying the number twice");
selected = "2026-09-20";
const oneKind = read(days).textContent;
eq(oneKind, "Sun, Sep 20 — Dry 300 g.",
"a day of one named kind keeps the name, which does say something");
ok(!/in total/.test(oneKind), "…but still does not repeat the figure");
selected = "2026-09-19";
ok(/in total/.test(read(days).textContent),
"two kinds on a day still get the total beside them");
}
suite("an unsplit chart gets the day total too"); suite("an unsplit chart gets the day total too");
{ {
// No kinds defined: there is still no hover on a phone, so the figure was // No kinds defined: there is still no hover on a phone, so the figure was
+16 -10
View File
@@ -2131,21 +2131,27 @@
} }
// Series order, so this reads as the stack above it read bottom to top. // Series order, so this reads as the stack above it read bottom to top.
const parts = series const parts = series
.map(s => ({ name: s.name, g: s.of(day) })) .map(s => ({ id: s.id, name: s.name, g: s.of(day) }))
.filter(p => p.g > 0) .filter(p => p.g > 0);
.map(p => `${p.name} ${Math.round(p.g)} g`);
const total = `${Math.round(day.grams)} g`; const total = `${Math.round(day.grams)} g`;
const label = (p) => `${p.name} ${Math.round(p.g)} g`;
// What matters is how many kinds *this day* holds, not how many the window
// does. A chart split across other days can still land on a day whose food
// is all one kind, and there the total is that kind's own figure.
if (parts.length === 0) { if (parts.length === 0) {
el.textContent = `${date} — no food logged.`; el.textContent = `${date} — no food logged.`;
} else if (series.length <= 1) { } else if (parts.length === 1) {
// Unsplit: the one part *is* the total, and naming it twice — "No kind // One part is the whole day, so repeating it as a total says the same
// 340 g · 340 g in total" — would be daft. // number twice. And "No kind" as the sole label says nothing at all —
el.textContent = `${date}${total}.`; // there is nothing for it to distinguish the food from.
el.textContent = parts[0].id === NO_KIND
? `${date}${total}.`
: `${date}${label(parts[0])}.`;
} else { } else {
// The total is worth repeating beside the parts: it is what the bar's // Several kinds: the total earns its place beside them, being what the
// height shows, and it saves adding them up. // bar's height shows and what you would otherwise add up yourself.
el.textContent = `${date}${parts.join(" · ")} · ${total} in total.`; el.textContent = `${date}${parts.map(label).join(" · ")} · ${total} in total.`;
} }
} }