2026-07-18 16:08:40 -04:00
|
|
|
import { test } from 'node:test';
|
|
|
|
|
import assert from 'node:assert/strict';
|
|
|
|
|
import {
|
2026-10-18 00:19:48 -04:00
|
|
|
translationUnavailableText,
|
2026-07-18 16:08:40 -04:00
|
|
|
normalizeLang,
|
|
|
|
|
sameLanguage,
|
|
|
|
|
languageName,
|
|
|
|
|
isSupportedTargetLang,
|
|
|
|
|
TRANSLATE_TARGET_LANGUAGES,
|
|
|
|
|
} from './langUtils';
|
|
|
|
|
|
|
|
|
|
test('normalizeLang: base subtag, lowercased', () => {
|
|
|
|
|
assert.equal(normalizeLang('en-US'), 'en');
|
|
|
|
|
assert.equal(normalizeLang('ZH'), 'zh');
|
|
|
|
|
assert.equal(normalizeLang('pt_BR'), 'pt');
|
|
|
|
|
assert.equal(normalizeLang(' De '), 'de');
|
|
|
|
|
assert.equal(normalizeLang(''), '');
|
|
|
|
|
assert.equal(normalizeLang(undefined), '');
|
|
|
|
|
assert.equal(normalizeLang(null), '');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('normalizeLang: keeps Chinese script subtag', () => {
|
|
|
|
|
assert.equal(normalizeLang('zh-Hant'), 'zh-hant');
|
|
|
|
|
assert.equal(normalizeLang('zh-Hans-CN'), 'zh-hans');
|
|
|
|
|
assert.equal(normalizeLang('zh-CN'), 'zh'); // region-only collapses to base
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('sameLanguage: compares normalized bases', () => {
|
|
|
|
|
assert.equal(sameLanguage('en', 'en-US'), true);
|
|
|
|
|
assert.equal(sameLanguage('EN', 'en'), true);
|
|
|
|
|
assert.equal(sameLanguage('en', 'de'), false);
|
|
|
|
|
assert.equal(sameLanguage('', 'en'), false); // empty is never "same"
|
|
|
|
|
assert.equal(sameLanguage(undefined, undefined), false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('languageName: resolves common codes', () => {
|
|
|
|
|
// Intl.DisplayNames is available in node; assert it returns a real name (not
|
|
|
|
|
// the bare code) for a known language.
|
|
|
|
|
const de = languageName('de');
|
|
|
|
|
assert.ok(de.length > 0 && de.toLowerCase() !== 'de');
|
|
|
|
|
// Unknown/garbage code falls back to the code itself.
|
|
|
|
|
assert.equal(languageName('zz-not-a-lang'), 'zz-not-a-lang'.split('-')[0]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('isSupportedTargetLang: curated membership', () => {
|
|
|
|
|
assert.equal(isSupportedTargetLang('en'), true);
|
|
|
|
|
assert.equal(isSupportedTargetLang('DE'), true);
|
|
|
|
|
assert.equal(isSupportedTargetLang('pt-BR'), true);
|
|
|
|
|
assert.equal(isSupportedTargetLang('xx'), false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('curated list: unique codes, English present', () => {
|
|
|
|
|
const codes = TRANSLATE_TARGET_LANGUAGES.map((l) => l.code);
|
|
|
|
|
assert.equal(new Set(codes).size, codes.length);
|
|
|
|
|
assert.ok(codes.includes('en'));
|
|
|
|
|
});
|
2026-10-18 00:19:48 -04:00
|
|
|
|
|
|
|
|
test('translationUnavailableText: no "use the desktop app" inside the desktop app (#349)', () => {
|
|
|
|
|
assert.doesNotMatch(translationUnavailableText(true), /desktop app\.$|Lotus desktop app/);
|
|
|
|
|
assert.match(translationUnavailableText(true), /this version of the desktop app/);
|
|
|
|
|
assert.match(translationUnavailableText(false), /this browser/);
|
|
|
|
|
});
|