mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
Moves ~600 strings in the root screens, settings, pairing, onboarding, accounts, agent history, diagnostics, connection status, home and host workspace lists to the translation API, with all ten translations. - Connection verdicts carry an explicit `dialing` flag instead of matching the "…" ending of an English label - Update-failure copy and connection-path accessibility labels are built from data, not by editing translated text - Workspace status names stay the host's labels, as on desktop; transport errors stay English - The stale-key check keeps a plural family while any of its forms is referenced Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
72 lines
2.8 KiB
JavaScript
72 lines
2.8 KiB
JavaScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
collectExtractionProblems,
|
|
collectIncompletePluralFamilies,
|
|
collectLiveSwitchViolations
|
|
} from './verify-mobile-localization.mjs'
|
|
|
|
describe('verify-mobile-localization', () => {
|
|
it('rejects translations that cannot follow a live language switch', () => {
|
|
const source = [
|
|
"const LABELS = [translate('a.b', 'Module scope')]",
|
|
'export function Row({ items }) {',
|
|
" const onPress = () => Alert.alert(translate('a.d', 'Handler runs at press time'))",
|
|
" useEffect(() => setTitle(translate('a.h', 'Effect')), [])",
|
|
" const label = useMemo(() => translate('a.g', 'Memo'), [])",
|
|
" return items.map((item) => <Text key={item}>{translate('a.c', 'Render callback')}</Text>)",
|
|
'}',
|
|
'export function Subscribed() {',
|
|
' const t = useMobileTranslation()',
|
|
" return <Pressable onPress={() => translate('a.i', 'Pressed')}>{t('a.e', 'Hook')}</Pressable>",
|
|
'}',
|
|
"export function rowLabel() { return translate('a.f', 'Helper') }",
|
|
"export default function () { return <Text>{translate('a.j', 'Screen')}</Text> }"
|
|
].join('\n')
|
|
|
|
expect(collectLiveSwitchViolations('mobile/src/row.tsx', source)).toEqual([
|
|
'mobile/src/row.tsx:1 translates at module scope; translate when rendering instead',
|
|
'mobile/src/row.tsx:5 calls translate() in a component or hook; use `const t = useMobileTranslation()`',
|
|
'mobile/src/row.tsx:6 calls translate() in a component or hook; use `const t = useMobileTranslation()`',
|
|
'mobile/src/row.tsx:13 calls translate() in a component or hook; use `const t = useMobileTranslation()`'
|
|
])
|
|
})
|
|
|
|
it('requires every CLDR category once a locale translates a plural family', () => {
|
|
const english = new Map([
|
|
['files_one', '{{count}} file'],
|
|
['files_other', '{{count}} files']
|
|
])
|
|
|
|
expect(
|
|
collectIncompletePluralFamilies(
|
|
english,
|
|
new Map([
|
|
['files_one', '{{count}} файл'],
|
|
['files_other', '{{count}} файла']
|
|
]),
|
|
'ru'
|
|
)
|
|
).toEqual(['files: missing _few, _many'])
|
|
expect(
|
|
collectIncompletePluralFamilies(english, new Map([['files_other', '{{count}} 件']]), 'ja')
|
|
).toEqual([])
|
|
})
|
|
|
|
it('keeps a plural family while any of its forms is referenced', () => {
|
|
const english = {
|
|
items_one: '{{count}} item',
|
|
items_other: '{{count}} items',
|
|
gone_one: '{{count}} gone',
|
|
gone_other: '{{count}} gone'
|
|
}
|
|
const references = [{ key: 'items_one', fallback: '{{count}} item' }]
|
|
const evidence = { literals: new Set(), dynamicPrefixes: new Set() }
|
|
|
|
expect(collectExtractionProblems(references, english, evidence).unreferenced).toEqual([
|
|
'gone_one',
|
|
'gone_other'
|
|
])
|
|
})
|
|
})
|