Files
OmniRoute/tests/unit/compression/output-styles-i18n-matrix.test.ts
abhiisalright 15386495c2 fix(compression): add i18n support for less-code and terse-prose (#10498)
* fix(compression): add i18n support for less-code and terse-prose

Translates less-code output style to pt-BR, vi, ja, and id. Adds missing vi translation to terse-prose caveman mode. Removes less-code from English-only allowlist and updates matrix tests.

Fixes #10426

* docs(compression): add output styles coverage table

Adds the requested Output Styles matrix to the compression guide covering styles, supported languages, and intensity levels.

Fixes #10426
2026-08-18 10:51:08 -03:00

139 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Guard for the output-style × language matrix.
*
* Why this exists: the compression INPUT engines understand 10 languages (rule
* packs under open-sse/services/compression/rules/ + the detector), but the
* OUTPUT styles only instruct in a subset. `less-code` shipped English-only and
* nobody noticed for months, because every other test is per-style. This test
* is per-MATRIX: it pins the expected coverage so a new style cannot silently
* be born English-only, and so an existing style cannot silently lose a locale.
*
* Adding a language to a style: extend BASELINE_LANGUAGES below (the assertion
* is "at least these", so growth never fails the gate).
* Adding a NEW style: it must cover REQUIRED_LANGUAGES, or be listed in
* KNOWN_ENGLISH_ONLY with a tracking issue.
*/
import test from "node:test";
import assert from "node:assert/strict";
import {
OUTPUT_STYLE_CATALOG,
OUTPUT_STYLE_IDS,
outputStyleMeta,
} from "../../../open-sse/services/compression/outputStyles/catalog.ts";
/** Minimum i18n coverage every new non-locale-gated style must ship with. */
const REQUIRED_LANGUAGES = ["pt-BR"];
/**
* Styles that predate this guard and are still English-only.
* Do NOT add entries here without an issue — fix the coverage instead.
*/
const KNOWN_ENGLISH_ONLY: Record<string, string> = {
};
/**
* Frozen per-style coverage. The assertion is a SUPERSET check, so adding a
* language is always allowed; removing one fails the gate.
*/
const BASELINE_LANGUAGES: Record<string, string[]> = {
// terse-prose reuses CAVEMAN_INSTRUCTION_BY_LANGUAGE (outputMode.ts), which
// localizes to pt-BR/ja/id/vi — keep the two in sync when adding a language.
"terse-prose": ["pt-BR", "ja", "id", "vi"],
"less-code": ["pt-BR", "vi", "ja", "id"],
ponytail: ["pt-BR", "vi", "ja", "id"],
"i-have-adhd": ["pt-BR", "vi", "ja", "id"],
// locale-gated to zh: the single-language instruction IS the feature.
"terse-cjk": [],
};
function languagesOf(id: string): string[] {
return Object.keys(outputStyleMeta(id).i18n ?? {});
}
test("every catalog style is covered by the matrix baseline", () => {
for (const id of OUTPUT_STYLE_IDS) {
assert.ok(
id in BASELINE_LANGUAGES,
`style "${id}" is missing from BASELINE_LANGUAGES — add its expected languages ` +
`(and translate it: a new style must cover ${REQUIRED_LANGUAGES.join(", ")})`
);
}
});
test("no style loses a language it already had", () => {
for (const [id, expected] of Object.entries(BASELINE_LANGUAGES)) {
if (!OUTPUT_STYLE_CATALOG[id]) continue; // style removed — covered by the catalog tests
const actual = languagesOf(id);
for (const lang of expected) {
assert.ok(
actual.includes(lang),
`style "${id}" lost its "${lang}" translation (has: ${actual.join(", ") || "none"})`
);
}
}
});
test("a non-locale-gated style ships the required languages, or is a known gap", () => {
for (const id of OUTPUT_STYLE_IDS) {
const meta = outputStyleMeta(id);
// A locale-gated style is only ever offered under its own locale, so a
// single-language instruction is correct by design (e.g. terse-cjk → zh).
if (meta.locale) continue;
if (id in KNOWN_ENGLISH_ONLY) continue;
const actual = languagesOf(id);
for (const lang of REQUIRED_LANGUAGES) {
assert.ok(
actual.includes(lang),
`style "${id}" must ship a "${lang}" translation (has: ${actual.join(", ") || "none"}). ` +
`English-only styles need an entry in KNOWN_ENGLISH_ONLY with a tracking issue.`
);
}
}
});
test("every declared translation has all three intensity levels", () => {
for (const id of OUTPUT_STYLE_IDS) {
const i18n = outputStyleMeta(id).i18n ?? {};
for (const [lang, levels] of Object.entries(i18n)) {
for (const level of ["lite", "full", "ultra"] as const) {
assert.equal(
typeof levels[level],
"string",
`${id}.i18n["${lang}"].${level} must be a string`
);
assert.ok(levels[level].length > 0, `${id}.i18n["${lang}"].${level} must be non-empty`);
}
}
}
});
test("every translated level carries the shared boundaries clause", () => {
// The boundary clause is what keeps code, paths, commands, errors and URLs
// verbatim. A translation that drops it would let the model rewrite them.
const anchor = "Code blocks";
for (const id of OUTPUT_STYLE_IDS) {
const i18n = outputStyleMeta(id).i18n ?? {};
for (const [lang, levels] of Object.entries(i18n)) {
for (const level of ["lite", "full", "ultra"] as const) {
assert.ok(
levels[level].includes(anchor),
`${id}.i18n["${lang}"].${level} is missing the shared boundaries clause`
);
}
}
}
});
test("KNOWN_ENGLISH_ONLY does not hide a style that is actually translated", () => {
// Stale-allowlist guard: once a gap is fixed, its entry must be removed.
for (const id of Object.keys(KNOWN_ENGLISH_ONLY)) {
if (!OUTPUT_STYLE_CATALOG[id]) continue;
assert.equal(
languagesOf(id).length,
0,
`style "${id}" now has translations — remove it from KNOWN_ENGLISH_ONLY`
);
}
});