waybetter/packages/shell/tests/language.test.ts
CRT 260cd44bbe i18n: supported and community language tiers
Automatic language choices resolve only to supported languages; community
translations are listed apart in Settings and offered as a one-click switch.
waybetter i18n check reads `supported` and generates `tier` into languages.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:48:11 +07:00

61 lines
3.9 KiB
TypeScript

// Language tiers: automatic choices ("follow the site", "follow system") resolve only to supported
// languages through the fallback chain; a language picked explicitly applies whatever its tier;
// Settings → Language lists supported languages first and community translations apart.
import assert from 'node:assert/strict';
import test from 'node:test';
import { communitySuggestion, resolveLocale } from '../src/frame/language.ts';
import { groupLanguages } from '../src/panel/languageModel.ts';
import type { PanelLanguage } from '../src/panel/site.ts';
const available = ['en', 'en-GB', 'de', 'pt', 'zh-Hans', 'zh-Hant', 'fr', 'ar', 'ar-x-fm', 'sv', 'pl'];
const supported = ['en', 'en-GB', 'de', 'pt', 'zh-Hant', 'fr', 'ar'];
test('automatic choices resolve only to supported languages, through the fallback chain', () => {
const auto = (system: string[]) => resolveLocale('system', null, system, available, supported);
assert.equal(auto(['pt-BR']), 'pt');
assert.equal(auto(['en-US']), 'en');
assert.equal(auto(['en-GB']), 'en-GB');
assert.equal(auto(['de-AT', 'en']), 'de');
assert.equal(resolveLocale('site', 'pt-BR', ['de'], available, supported), 'pt');
// A community language stays on English: system, site and the site's own tag alike.
assert.equal(auto(['sv-SE']), 'en');
assert.equal(auto(['pl']), 'en');
assert.equal(resolveLocale('site', 'sv', ['de'], available, supported), 'en', 'the site is Swedish (community): English, not the system language');
assert.equal(resolveLocale('site', null, ['sv'], available, supported), 'en');
// The next preference wins over English when it is supported.
assert.equal(auto(['sv', 'fr']), 'fr');
// Private-use variants and scripts fall back within the supported set.
assert.equal(auto(['ar-x-fm']), 'ar');
assert.equal(auto(['zh-Hant']), 'zh-Hant');
assert.equal(auto(['zh-Hans']), 'en', 'Simplified Chinese is community here');
});
test('with every language supported (the default) nothing changes', () => {
assert.equal(resolveLocale('system', null, ['sv-SE'], available), 'sv');
assert.equal(resolveLocale('site', 'pl', ['de'], available), 'pl');
});
test('an explicit pick always applies, whatever its tier', () => {
for (const code of available) assert.equal(resolveLocale(code, 'de', ['fr'], available, supported), code, code);
assert.equal(resolveLocale('sv-SE', null, ['fr'], available, supported), 'sv', 'a regional tag of a community language');
assert.equal(resolveLocale('xx', null, ['fr'], available, supported), 'fr', 'unknown: the system language');
});
test('a community language the site or system uses is suggested, never applied', () => {
assert.equal(communitySuggestion('site', 'sv', ['de'], available, supported), 'sv');
assert.equal(communitySuggestion('site', null, ['pl-PL'], available, supported), 'pl');
assert.equal(communitySuggestion('system', null, ['sv'], available, supported), 'sv');
assert.equal(communitySuggestion('site', 'pt-BR', ['sv'], available, supported), null, 'supported: nothing to suggest');
assert.equal(communitySuggestion('site', 'xx', ['de'], available, supported), null, 'not offered at all');
assert.equal(communitySuggestion('sv', 'sv', ['sv'], available, supported), null, 'an explicit pick needs no hint');
assert.equal(communitySuggestion('system', null, ['sv'], available), null, 'no tiers');
});
test('Settings groups supported languages first and community ones apart, order kept', () => {
const row = (code: string, tier: PanelLanguage['tier']): PanelLanguage => ({ code, name: code, englishName: code, dir: 'ltr', status: 'machine', tier, coverage: 1 });
const list = [row('en', 'supported'), row('sv', 'community'), row('de', 'supported'), row('pl', 'community')];
const groups = groupLanguages(list);
assert.deepEqual(groups.supported.map(language => language.code), ['en', 'de']);
assert.deepEqual(groups.community.map(language => language.code), ['sv', 'pl']);
assert.deepEqual(groupLanguages([row('en', 'supported')]).community, []);
});