Files
computer-playbook/tests/unit/python/utils/i18n/test_damage.py
T
kevinveenbirkenbachandClaude Opus 5 2d1227d0f1 fix(i18n): count a word per character where a script has no separators
untranslated() asks what share of a translation's words are Latin. WORDS matched runs of letters, and Han, Kana, Thai, Lao, Khmer and Myanmar write without separators, so a whole sentence came back as one token. Two Latin product names inside it carried that token's latin_share past a half, which made the ratio 1.0 and condemned a sound translation.

Measured on a Japanese rendering of "Runs Playwright in Docker with stable browser settings": one token, latin_share 0.516, ratio 1.00 against a threshold of 0.9. The six-word floor removed in 27d59f4bd4 had hidden this, because a separator-less script never reaches six words; dropping it as vacuous missed that it was the only guard those scripts had.

WORDS now takes one character of such a script as one word, with the single-character branch first so the run branch cannot swallow the sentence again. Ten real entries against both patterns: the old one errs on two, the new one on none, and every true positive survives, including Cyrillic welds like CI Деbugging and an English answer in a Japanese catalog.

The ranges are codepoints because a formatter rewrites an escape into the character it names, and the resulting literal blob cannot be reviewed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-21 01:42:32 +02:00

126 lines
5.0 KiB
Python

"""Unit tests for the criteria that condemn an answer carrying its source or
coming back in the wrong script.
The shape is one the gateway produced across twenty languages: the English
source, a markdown rule, then a rendering. Every other criterion passed it,
because the rendering keeps the spans and the names and the separator is made
of characters the markup comparison does not count.
"""
from __future__ import annotations
import unittest
from typing import ClassVar
from utils.i18n.damage import reason
class TestEchoAndContinue(unittest.TestCase):
"""A translation holding its whole source is the server failing, not translating."""
SOURCE: ClassVar[str] = (
"Corporate design injection for NGINX-served apps, unifying light and "
"dark theming from OKLCH design tokens"
)
RENDERING: ClassVar[str] = (
"Corporate-Design-Injection für NGINX-bediente Anwendungen, vereinheitlicht "
"helles und dunkles Theming aus OKLCH-Design-Tokens"
)
def test_an_answer_that_prepends_its_source_is_condemned(self) -> None:
answer = f"{self.SOURCE}\n---\n\n{self.RENDERING}"
self.assertEqual(reason(self.SOURCE, answer, "de"), "echo")
def test_an_answer_that_appends_its_source_is_condemned(self) -> None:
answer = f"{self.RENDERING}\n\n{self.SOURCE}"
self.assertEqual(reason(self.SOURCE, answer, "de"), "echo")
def test_a_rendering_that_drops_the_source_is_kept(self) -> None:
self.assertEqual(reason(self.SOURCE, self.RENDERING, "de"), "")
def test_a_short_source_may_live_inside_a_longer_rendering(self) -> None:
source = "Mail"
self.assertEqual(reason(source, "Mail-Konto des Benutzers", "de"), "")
class TestWrongScript(unittest.TestCase):
"""A language written in another script came back in Latin letters.
The catalogs are mostly one- to four-word labels, and a six-word floor
once stood in front of this criterion, so it never fired on them: a whole
run filled Belarusian with Polish and Abkhaz with Spanish while every
criterion passed.
"""
def test_a_one_word_answer_in_the_wrong_script_is_condemned(self) -> None:
self.assertEqual(reason("Applications", "Aplikacje", "be"), "untranslated")
def test_a_label_answered_in_another_language_is_condemned(self) -> None:
self.assertEqual(reason("Communication", "Comunicación", "ab"), "untranslated")
def test_an_answer_in_the_language_s_own_script_is_kept(self) -> None:
self.assertEqual(reason("Applications", "Праграмы", "be"), "")
def test_a_latin_script_target_is_not_judged_by_script(self) -> None:
self.assertEqual(reason("Applications", "Anwendungen", "de"), "")
def test_a_translation_without_a_word_is_kept(self) -> None:
self.assertEqual(reason("Status", "100 %", "be"), "")
def test_a_separatorless_script_counts_one_word_per_character(self) -> None:
"""Japanese and Chinese write without spaces, so a run-based pattern
returns the whole sentence as one token, and two Latin product names
inside it carry that token past a half and the ratio to 1.0."""
self.assertEqual(
reason(
"Runs Playwright in Docker with stable browser settings",
"安定したブラウザ設定でDockerでPlaywrightを実行",
"ja",
),
"",
)
self.assertEqual(
reason("Run Playwright in Docker", "在Docker中运行Playwright", "zh"), ""
)
def test_a_separatorless_script_answered_in_english_is_still_condemned(
self,
) -> None:
self.assertEqual(
reason(
"Runs Playwright in Docker with stable settings",
"Runs Playwright in Docker with stable browser settings",
"ja",
),
"untranslated",
)
class TestForeignScript(unittest.TestCase):
"""A Latin-script language came back in a script it does not use.
The model answers a language it cannot write with one it can. Chamorro
came back in Han because the ISO code ``ch`` reads as Chinese, Turkish in
Bengali, Avestan in Arabic, and none of it was caught while only the
non-Latin direction was checked.
"""
def test_han_in_a_latin_script_catalog_is_condemned(self) -> None:
self.assertEqual(reason("AI Services", "人工智能服务", "ch"), "foreign-script")
def test_arabic_in_a_latin_script_catalog_is_condemned(self) -> None:
self.assertEqual(reason("Sales", "إدارة", "tr"), "foreign-script")
def test_a_latin_script_answer_is_kept(self) -> None:
self.assertEqual(reason("Applications", "Anwendungen", "de"), "")
def test_a_non_latin_target_is_not_judged_by_this_rule(self) -> None:
self.assertEqual(reason("Applications", "Праграмы", "be"), "")
def test_a_translation_without_a_word_is_kept(self) -> None:
self.assertEqual(reason("Status", "100 %", "ch"), "")
if __name__ == "__main__":
unittest.main()