fix(measurements): drop the stray space in a unit-less range message

A score, rating, count or ratio has no unit label, so the range
message for a manual pain score read "Enter a value between 0 and 10 ."
with a space before the stop, and the same in every locale. A second
sentence without the unit now answers those types.
This commit is contained in:
Marc-André Bombeck committed 2026-11-12 12:49:18 +01:00
1 parent 048dbbee9f
commit 3ed266e281
12 files changed
+58 -19

No files matched your search

@@ -64,7 +64,11 @@ import { MeasurementList } from "../measurement-list";
import type { UnitDisplay } from "@/hooks/use-unit-display";
import { convertGlucose, toCanonicalMgdl } from "@/lib/glucose";
import { getUnitForType } from "@/lib/measurements/unit-map";
import { editSeedValue, storedValueFor } from "../list/use-measurement-edit";
import {
editSeedValue,
outOfRangeMessage,
storedValueFor,
} from "../list/use-measurement-edit";
import { rowDisplayFor } from "../list/use-measurement-row-display";
/** A metric reader on the given glucose unit, as the list's row display. */
@@ -140,3 +144,28 @@ describe("MeasurementList — blood-glucose display unit", () => {
expect(storedValueFor(display, glucose(95.48), 95.48)).toBe(95.48);
});
});
describe("the out-of-range sentence", () => {
const t = ((key: string, params?: Record<string, unknown>) =>
`${key} ${JSON.stringify(params)}`) as unknown as Parameters<
typeof outOfRangeMessage
>[2];
const reading = (type: string, unit: string) =>
({ id: "m1", type, value: 1, unit, source: "MANUAL" }) as never;
const shows = (unit: string) => ({
rowDisplay: (m: { value: number }) => ({ value: m.value, unit }),
});
it("names the unit where the type has one", () => {
expect(
outOfRangeMessage(shows("kg"), reading("WEIGHT", "kg"), t, String),
).toMatch(/^measurements\.valueOutOfRange \{.*"unit":"kg"/);
});
it("leaves the unit out for a score, which has no label", () => {
// "Enter a value between 0 and 10 ." read with a space before the stop.
expect(
outOfRangeMessage(shows(""), reading("PAIN_NRS", "score"), t, String),
).toBe('measurements.valueOutOfRangeNoUnit {"min":"0","max":"10"}');
});
});
@@ -103,20 +103,20 @@ export function editValueRange(
type Translate = ReturnType<typeof useTranslations>["t"];
/** The sentence for a value outside its band, in the unit the input shows. */
function outOfRangeMessage(
export function outOfRangeMessage(
display: Pick<MeasurementRowDisplay, "rowDisplay">,
measurement: Measurement,
t: Translate,
formatNumber: (value: number) => string,
): string {
const range = editValueRange(display, measurement);
return range
? t("measurements.valueOutOfRange", {
min: formatNumber(range.min),
max: formatNumber(range.max),
unit: range.unit,
})
: t("measurements.invalidValue");
if (!range) return t("measurements.invalidValue");
const bounds = { min: formatNumber(range.min), max: formatNumber(range.max) };
// A score, rating, count or ratio has no unit label, which left a space
// before the full stop.
return range.unit
? t("measurements.valueOutOfRange", { ...bounds, unit: range.unit })
: t("measurements.valueOutOfRangeNoUnit", bounds);
}
/**