diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx index 2250feb1a..d6eaae482 100644 --- a/frontend/src/components/LeftoverMapPlot.tsx +++ b/frontend/src/components/LeftoverMapPlot.tsx @@ -1,7 +1,6 @@ import type { LeftoverMapAxis, LeftoverMapCoverage, LeftoverPair } from "../api"; import { t, tf } from "../i18n"; import { formatLeftoverMapCoordinatePair } from "../leftoverMapCoordinates"; -import { LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK } from "../leftoverMapRank"; import { leftoverMapCoverageCounts, leftoverMapIncompleteItemCount, @@ -171,8 +170,8 @@ function leftoverMapPlotAxisText( * comparison graphic from already-named leftover expected * with distinct leftover map comparison graphic leftover expected * labels. ADR 0318 captions leftover-map rank on that comparison graphic - * from already-named leftover-map rank with a distinct comparison graphic - * accessible name. + * from already-named leftover-map rank while composing existing localized + * comparison-graphic and rank labels rather than adding SPA translation debt. * Never invent a leftover score. */ export function LeftoverMapPlot({ @@ -469,12 +468,13 @@ export function LeftoverMapPlot({ x={segment.rankX} y={segment.rankY} textAnchor="middle" - aria-label={tf( + aria-label={ variant === "comparison" - ? LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK - : LEFTOVER_MAP_PLOT_SEGMENT_RANK, - { label: segment.rankLabel }, - )} + ? `${t(LEFTOVER_MAP_COMPARE_PLOT_LABEL)}: ${tf(LEFTOVER_MAP_PLOT_SEGMENT_RANK, { + label: segment.rankLabel, + })}` + : tf(LEFTOVER_MAP_PLOT_SEGMENT_RANK, { label: segment.rankLabel }) + } > {segment.rankLabel} diff --git a/frontend/src/leftoverMapRank.ts b/frontend/src/leftoverMapRank.ts index 557b185f0..f294d1d0a 100644 --- a/frontend/src/leftoverMapRank.ts +++ b/frontend/src/leftoverMapRank.ts @@ -7,9 +7,6 @@ export const LEFTOVER_RANK_STRUCTURE_ACTION = export const LEFTOVER_MAP_COMPARE_RANK_LABEL = "Leftover map comparison rank"; -export const LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK = - "leftover map comparison graphic leftover-map rank {label}"; - /** * Format persisted rank evidence without coercion or inference. * diff --git a/frontend/src/leftoverMapRankLocalization.test.ts b/frontend/src/leftoverMapRankLocalization.test.ts new file mode 100644 index 000000000..731e2ef74 --- /dev/null +++ b/frontend/src/leftoverMapRankLocalization.test.ts @@ -0,0 +1,28 @@ +import { afterEach, describe, expect, it } from "vitest"; +import { setLocale, t, tf, type Locale } from "./i18n"; +import { + LEFTOVER_MAP_COMPARE_PLOT_LABEL, + LEFTOVER_MAP_PLOT_SEGMENT_RANK, +} from "./leftoverMapPlotLayout"; + +const EXPECTED = [ + ["ko", "잔여 지도 비교 그림: 잔여 지도 순위 rank 1"], + ["zh", "残差地图比较图形: 残差图秩 rank 1"], + ["ja", "残差マップの比較図: 残差マップ階数 rank 1"], + ["vi", "Đồ họa so sánh bản đồ phần dư: hạng bản đồ phần dư rank 1"], +] as const satisfies readonly (readonly [Exclude, string])[]; + +function comparisonRankAccessibleName(label: string): string { + return `${t(LEFTOVER_MAP_COMPARE_PLOT_LABEL)}: ${tf(LEFTOVER_MAP_PLOT_SEGMENT_RANK, { label })}`; +} + +afterEach(() => { + setLocale("en"); +}); + +describe("grouping-comparison leftover-map rank localization", () => { + it.each(EXPECTED)("keeps the accessible rank caption localized in %s", (locale, expected) => { + setLocale(locale); + expect(comparisonRankAccessibleName("rank 1")).toBe(expected); + }); +}); diff --git a/tests/test_grouping_comparison_graphic_rank_contract.py b/tests/test_grouping_comparison_graphic_rank_contract.py index 63c9cf452..b0b243402 100644 --- a/tests/test_grouping_comparison_graphic_rank_contract.py +++ b/tests/test_grouping_comparison_graphic_rank_contract.py @@ -10,23 +10,20 @@ RANK_SOURCE = ROOT / "frontend" / "src" / "leftoverMapRank.ts" -def test_comparison_graphic_names_the_persisted_rank_with_distinct_copy() -> None: - """Comparison SVG rank captions must not reuse report or strip accessible names.""" +def test_comparison_graphic_names_the_persisted_rank_with_distinct_localized_copy() -> None: + """Comparison rank names compose existing localized graphic and rank vocabulary.""" plot_source = PLOT_SOURCE.read_text(encoding="utf-8") rank_source = RANK_SOURCE.read_text(encoding="utf-8") + assert "LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK" not in rank_source + assert "LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK" not in plot_source + assert 'variant === "comparison"' in plot_source assert ( - 'export const LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK =\n' - ' "leftover map comparison graphic leftover-map rank {label}";' - in rank_source - ) - assert "LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK" in plot_source - assert re.search( - r'variant\s*===\s*"comparison"\s*\?\s*LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK\s*:\s*LEFTOVER_MAP_PLOT_SEGMENT_RANK', - plot_source, - re.DOTALL, + '`${t(LEFTOVER_MAP_COMPARE_PLOT_LABEL)}: ${tf(LEFTOVER_MAP_PLOT_SEGMENT_RANK, {' + in plot_source ) assert "label: segment.rankLabel" in plot_source + assert ': tf(LEFTOVER_MAP_PLOT_SEGMENT_RANK, { label: segment.rankLabel })' in plot_source def test_rank_projection_consumes_only_persisted_fail_closed_evidence() -> None: