From efaf601db51b9a50b522ec831e7e873fec1a214c Mon Sep 17 00:00:00 2001 From: poplolioi11 <340387725+poplolioi11@users.noreply.github.com> Date: Mon, 26 Oct 2026 15:09:25 +0800 Subject: [PATCH] fix(langneg): normalize fallback variant casing --- fluent-langneg/src/locale.ts | 4 ++- fluent-langneg/test/langneg_test.js | 49 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/fluent-langneg/src/locale.ts b/fluent-langneg/src/locale.ts index 7f4b36db..8b07b7da 100644 --- a/fluent-langneg/src/locale.ts +++ b/fluent-langneg/src/locale.ts @@ -18,7 +18,9 @@ export class LocaleWrapper extends Intl.Locale { if (tag.length > lsrTagLength) { let unicodeExtStart: number | undefined = tag.search(/-[a-zA-Z]-/); if (unicodeExtStart === -1) unicodeExtStart = undefined; - this.variants = tag.substring(lsrTagLength + 1, unicodeExtStart); + this.variants = tag + .substring(lsrTagLength + 1, unicodeExtStart) + .toLowerCase(); } } } diff --git a/fluent-langneg/test/langneg_test.js b/fluent-langneg/test/langneg_test.js index 37129fbb..1fc63d38 100644 --- a/fluent-langneg/test/langneg_test.js +++ b/fluent-langneg/test/langneg_test.js @@ -172,3 +172,52 @@ suite("Language Negotiation", () => { } } }); + +suite("Language variant case", () => { + for (const strategy of ["matching", "lookup"]) { + const options = { + strategy, + defaultLocale: strategy === "lookup" ? "fr" : undefined, + }; + + test(`${strategy} - lowercase variants`, () => { + assert.deepStrictEqual( + negotiateLanguages( + ["en-oxendict"], + ["en-US-fonipa", "en-US-oxendict"], + options + ), + ["en-US-oxendict"] + ); + }); + + test(`${strategy} - uppercase available variant`, () => { + assert.deepStrictEqual( + negotiateLanguages( + ["en-oxendict"], + ["en-US-fonipa", "en-US-OXENDICT"], + options + ), + ["en-US-OXENDICT"] + ); + }); + + test(`${strategy} - uppercase requested variant`, () => { + assert.deepStrictEqual( + negotiateLanguages( + ["en-OXENDICT"], + ["en-US-fonipa", "en-US-oxendict"], + options + ), + ["en-US-oxendict"] + ); + }); + + test(`${strategy} - keeps ignoring an invalid non-ASCII variant`, () => { + assert.deepStrictEqual( + negotiateLanguages(["en"], ["en-Kelvin"], options), + strategy === "lookup" ? ["fr"] : [] + ); + }); + } +});