Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { loadStudioCatalogue } from '@object-ui/i18n/namespaces/studio';
import { t, tOptional } from '../i18n';
// The i18n pin's own family list (a test-support module, not a package export).
import { STUDIO_ZH_ONLY_FAMILIES } from '../../../../../i18n/src/__tests__/studio-zh-only-families';

const EN = await loadStudioCatalogue('en');
// Resident before any case, so the zh lookups below read synchronously.
Expand Down Expand Up @@ -152,6 +154,8 @@ const ZH_ONLY_FLOOR: Readonly<Record<string, number>> = Object.freeze({
* here from the retired `check:i18n-designer-parity` gate with slice S7. A
* citation is `{ file, anchor }`, the anchor is TEXT and never a line number,
* and it must occur exactly once in its file or it stops locating anything.
* Its prefixes are held equal to `STUDIO_ZH_ONLY_FAMILIES`, the list the i18n
* pin `studio-namespace.test.ts` allows, so neither can widen alone.
*/
const ZH_ONLY_REASONS = Object.freeze([
{
Expand Down Expand Up @@ -248,6 +252,10 @@ describe('the namespace is the only home (objectstack#25922 slice S7)', () => {
expect(wrong).toEqual([]);
});

it('a reason is given for exactly the families the i18n pin allows', () => {
expect(ZH_ONLY_REASONS.map((f) => f.prefix).sort()).toEqual([...STUDIO_ZH_ONLY_FAMILIES].sort());
});

it.each(ZH_ONLY_REASONS.map((f) => [f.prefix, f] as const))('%s: its citation anchor occurs exactly once', (_prefix, family) => {
const text = readFileSync(path.join(here, family.file), 'utf8');
expect(text.split(family.anchor).length - 1).toBe(1);
Expand Down
11 changes: 3 additions & 8 deletions ui/packages/i18n/src/__tests__/studio-namespace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,13 @@ import {
resolveStudioLanguage,
studioString,
} from '../namespaces/studio/index.js';
// The `zh`-only families, each one-sided on purpose; the list's one home.
import { STUDIO_ZH_ONLY_FAMILIES } from './studio-zh-only-families.js';

/** `tFormat()`'s own placeholder pattern (app-shell `views/metadata-admin/i18n.ts`). */
const PLACEHOLDER = /\{(\w+)\}/g;
const placeholders = (value: string) => [...new Set(Array.from(value.matchAll(PLACEHOLDER), (m) => m[1]))].sort();

/**
* The `zh`-only families, each one-sided on purpose. `ZH_ONLY_REASONS` in
* app-shell's `inspectorStrings.studioNamespace-25922.test.ts` carries the
* reason and the consumer for each, and checks that its citation still locates it.
*/
const ZH_ONLY_FAMILIES = ['engine.flowNode.', 'engine.enum.type.', 'engine.packages.form.help.'];

function flatKeys(node: unknown, prefix = ''): string[] {
if (typeof node !== 'object' || node === null) return [prefix];
return Object.entries(node).flatMap(([k, v]) => flatKeys(v, prefix ? `${prefix}.${k}` : k));
Expand Down Expand Up @@ -69,7 +64,7 @@ describe('studio namespace — scoped parity', () => {

it('a zh-only key belongs to a documented family', () => {
const stray = zhKeys.filter(
(key) => !(key in STUDIO_EN) && !ZH_ONLY_FAMILIES.some((family) => key.startsWith(family)),
(key) => !(key in STUDIO_EN) && !STUDIO_ZH_ONLY_FAMILIES.some((family) => key.startsWith(family)),
);
expect(stray).toEqual([]);
});
Expand Down
15 changes: 15 additions & 0 deletions ui/packages/i18n/src/__tests__/studio-zh-only-families.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* The `studio` namespace's `zh`-only key families, the one list.
*
* Two pins read it: `studio-namespace.test.ts` here, which reds on a `zh`-only
* key outside these prefixes, and app-shell's
* `inspectorStrings.studioNamespace-25922.test.ts`, whose `ZH_ONLY_REASONS`
* carries the reason and consumer for each family and asserts its prefixes
* equal this list. A test-support module, not an export of the package entry:
* `__tests__/` is excluded from the build, so nothing here ships.
*/
export const STUDIO_ZH_ONLY_FAMILIES: readonly string[] = Object.freeze([
'engine.flowNode.',
'engine.enum.type.',
'engine.packages.form.help.',
]);
Loading