A formatted value took the reader's language even when the notice was said in English for the
log. The platform-namespace contract matched only t("…"), so a domain key passed through msg()
in components/ui/ went unseen. Three comments pointed at localizeDetail's old home.
44 lines
1.8 KiB
TypeScript
44 lines
1.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { readSources } from "../../lib/rawSources.testkit";
|
|
|
|
// The platform layer (`components/ui/`) may not import a feature component or a domain API slice —
|
|
// eslint's `no-restricted-imports` enforces that. It cannot see an i18n KEY, though, and two
|
|
// primitives spoke domain vocabulary through one: `PriorityStepper` labelled itself with
|
|
// `channels.row.*` (and told every caller that it orders the Feed), `Combobox` said `plex.loading`
|
|
// and `plex.filter.moreRefine` on the feed sidebar. A primitive's strings live in a platform
|
|
// namespace; what a value MEANS where it is used arrives as a prop.
|
|
const PLATFORM_NAMESPACES = new Set([
|
|
"common",
|
|
"errors",
|
|
"datatable",
|
|
"keys",
|
|
"palette",
|
|
"sidebar",
|
|
"notifications",
|
|
"time",
|
|
]);
|
|
|
|
const files = readSources(__dirname, "./**/*.{ts,tsx}");
|
|
// `t("ns.…")` and `t(\`ns.…\`)`, and a notice's `msg("ns.…")` (the same key, said when shown) — the
|
|
// namespace is everything before the first dot.
|
|
const KEY = /\b(?:t|msg)\(\s*["`]([A-Za-z]+)\./g;
|
|
|
|
describe("components/ui/ speaks only platform i18n namespaces", () => {
|
|
it("names no feature namespace", () => {
|
|
const sources = Object.entries(files).filter(([p]) => !/\.test\.tsx?$/.test(p));
|
|
expect(sources.length).toBeGreaterThan(20); // the glob matched the layer
|
|
const offenders = sources.flatMap(([p, src]) =>
|
|
[...String(src).matchAll(KEY)]
|
|
.map((m) => m[1]!)
|
|
.filter((ns) => !PLATFORM_NAMESPACES.has(ns))
|
|
.map((ns) => `${p}: ${ns}.*`),
|
|
);
|
|
expect(offenders).toEqual([]);
|
|
});
|
|
|
|
it("sees a feature namespace when one is used", () => {
|
|
expect([...'t("plex.loading")'.matchAll(KEY)].map((m) => m[1])).toEqual(["plex"]);
|
|
expect([...'msg("plex.loading")'.matchAll(KEY)].map((m) => m[1])).toEqual(["plex"]);
|
|
});
|
|
});
|