vanilla 19.0

This commit is contained in:
Ernad Husremovic 2025-10-08 10:49:46 +02:00
parent 991d2234ca
commit d1963a3c3a
3066 changed files with 1651266 additions and 922560 deletions

View file

@ -0,0 +1,186 @@
import { describe, expect, test } from "@odoo/hoot";
import {
formatList,
jsToPyLocale,
normalize,
normalizedMatch,
pyToJsLocale,
} from "@web/core/l10n/utils";
import { user } from "@web/core/user";
import { patchWithCleanup } from "@web/../tests/web_test_helpers";
describe.current.tags("headless");
describe("formatList", () => {
test("defaults to the current user's locale", () => {
patchWithCleanup(user, { lang: "es-ES" });
const list = ["A", "B", "C"];
expect(formatList(list)).toBe("A, B y C");
});
test("defaults to English if the user's locale can't be retrieved", () => {
patchWithCleanup(user, { lang: "" });
const list = ["A", "B", "C"];
expect(formatList(list)).toBe("A, B, and C");
});
test("takes style into account", () => {
const list = ["A", "B", "C"];
expect(formatList(list, { style: "or" })).toBe("A, B, or C");
});
test("uses the specified locale", () => {
const list = ["A", "B", "C"];
expect(formatList(list, { localeCode: "fr-FR" })).toBe("A, B et C");
});
});
describe("jsToPyLocale", () => {
test("2-letter ISO 639 code", () => expect(jsToPyLocale("tg")).toBe("tg"));
test("3-letter ISO 639 code", () => expect(jsToPyLocale("kab")).toBe("kab"));
test("language with region", () => expect(jsToPyLocale("fr-BE")).toBe("fr_BE"));
test("language with region (UN M49 code)", () => expect(jsToPyLocale("es-419")).toBe("es_419"));
test("language with Latin script", () => expect(jsToPyLocale("sr-Latn")).toBe("sr@latin"));
test("language with Cyrillic script", () => expect(jsToPyLocale("sr-Cyrl")).toBe("sr@Cyrl"));
test("language with region and script", () =>
expect(jsToPyLocale("sr-Latn-RS")).toBe("sr_RS@latin"));
test("already converted locale", () => expect(jsToPyLocale("fr_TG")).toBe("fr_TG"));
test("already converted locale with script", () =>
expect(jsToPyLocale("sr@latin")).toBe("sr@latin"));
test("undefined locale", () => expect(jsToPyLocale(undefined)).toBe(""));
test("Tagalog", () => expect(jsToPyLocale("tl-PH")).toBe("tl_PH"));
test("Filipino", () => expect(jsToPyLocale("fil-PH")).toBe("tl_PH"));
});
describe("pyToJsLocale", () => {
test("2-letter ISO 639 code", () => expect(pyToJsLocale("tg")).toBe("tg"));
test("3-letter ISO 639 code", () => expect(pyToJsLocale("kab")).toBe("kab"));
test("language with region", () => expect(pyToJsLocale("fr_BE")).toBe("fr-BE"));
test("language with region (UN M49 code)", () => expect(pyToJsLocale("es_419")).toBe("es-419"));
test("language with Latin script", () => expect(pyToJsLocale("sr@latin")).toBe("sr-Latn"));
test("language with Cyrillic script", () => expect(pyToJsLocale("sr@Cyrl")).toBe("sr-Cyrl"));
test("language with region and script", () =>
expect(pyToJsLocale("sr_RS@latin")).toBe("sr-Latn-RS"));
test("already converted locale", () => expect(pyToJsLocale("fr-TG")).toBe("fr-TG"));
test("already converted locale with script", () =>
expect(pyToJsLocale("sr-Latn")).toBe("sr-Latn"));
test("undefined locale", () => expect(pyToJsLocale(undefined)).toBe(""));
});
describe("normalize", () => {
test("diacritics", () => expect(normalize("ž̷̲̺̌a̷̮̳͆̎l̵̯̔̆g̷̭̗̊̑o̷͓̊̓ ̵̜̬̂̅ţ̴̖͒ẹ̵̚x̷̭̪̓t̷̥̒")).toBe("zalgo text"));
test("diacritics-like", () => expect(normalize("ĦøŧØłð")).toBe("hotold"));
test("French", () => expect(normalize("éàïœùûîêü")).toBe("eaioeuuieu"));
test("normalization forms", () =>
expect(normalize("éÈäÙ".normalize("NFC"))).toBe(normalize("éÈäÙ".normalize("NFD"))));
test("compatibility equivalence", () => expect(normalize("㎩㎭𝐞")).toBe("parade"));
test("case folding", () => expect(normalize("Kevin Großkreutz")).toBe("kevin grosskreutz"));
test("ligatures", () => expect(normalize("ήIJ")).toBe("oeaeij"));
test("empty string", () => expect(normalize("")).toBe(""));
});
describe("normalizedMatch", () => {
test("plain ASCII inputs", () => {
const { start, end, match } = normalizedMatch("Yuchen (yhu)", "yhu");
expect(match).toBe("yhu");
expect(start).toBe(8);
expect(end).toBe(11);
});
test("compatibility equivalence", () => {
const { start, end, match } = normalizedMatch("𝔖𝔥𝔯𝔢𝔨", "SHRE");
expect(match).toBe("𝔖𝔥𝔯𝔢");
expect(start).toBe(0);
expect(end).toBe(8);
expect("𝔖𝔥𝔯𝔢𝔨".slice(start, end)).toBe(match);
});
test("some fancy letters without canonical decomposition", () => {
const { start, end, match } = normalizedMatch("Bjørn Dæhlie", "ORN DAE");
expect(start).toBe(2);
expect(end).toBe(8);
expect(match).toBe("ørn Dæ");
});
describe("ligatures", () => {
test("in source string", () => {
const { start, end, match } = normalizedMatch("Richard Cœur de Lion", "coeur");
expect(start).toBe(8);
expect(end).toBe(12);
expect(match).toBe("Cœur");
});
test("in substring", () => {
const { start, end, match } = normalizedMatch("Džemal Bijedić", "dž");
expect(start).toBe(0);
expect(end).toBe(2);
expect(match).toBe("Dž");
});
test("substring ends in the middle of a ligature", () => {
const { start, end, match } = normalizedMatch("Æthelflæd", "aethelfla");
expect(start).toBe(0);
expect(end).toBe(8);
expect(match).toBe("Æthelflæ");
});
});
describe("full case folding", () => {
test("in source string", () => {
const { start, end, match } = normalizedMatch("Scleßin", "essi");
expect(start).toBe(3);
expect(end).toBe(6);
expect(match).toBe("eßi");
});
test("in substring", () => {
const { start, end, match } = normalizedMatch("Sclessin", "eßi");
expect(start).toBe(3);
expect(end).toBe(7);
expect(match).toBe("essi");
});
});
describe("diacritics", () => {
test("accent on last letter", () => {
const { start, end, match } = normalizedMatch("José Bové", "vé");
expect(start).toBe(7);
expect(end).toBe(9);
expect(match).toBe("vé");
});
test("normalization form is preserved", () => {
const { start, end, match } = normalizedMatch(
"eĥoŝanĝo ĉiuĵaŭde".normalize("NFD"),
"EHOSANGO CIUJAUDE"
);
expect(start).toBe(0);
expect(end).toBe(23);
expect(match).toBe("eĥoŝanĝo ĉiuĵaŭde");
});
test("Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn", () => {
const { start, end, match } = normalizedMatch("N̸̟̤̦̥̦͚̘̟̙͓͚̱͇̱͍̦͓͕̝͈̣̺͔̐͂͑̂̅̇̄̏͐̒̾̋̿̀̐̎̄͗̀͋̈́̉̈́͑̋͊̃̃̃͌̃́̚̚͝͝y̸̢̢̢̧͙̳̫̙̺̝͔̭̲̮͎̦͈͉͚̣̖̞̳͙͚͕̪̘̓̓̇͗͑̈͋͑̅̒̎̄̉̊͌̂̈́̏̚͜ͅͅa̶̧̡͕̝̥̝̳̬̙͔̱͎̠̍͌̓͆̾̔̾͐͌̀̔̀̽̓͐̽͒̌̽̀͗͗͋̉̒̒̎͌͘̚̚͜͝͠ř̴͇͒̀̑̊́̓̈́̎̆̈́̾̅̾̈̃̉̂̄͋̄͑̇̃̽̽͌̐̀̉̃̀͛̂̓̄͑͆̋̌̕͘̚̕͘̕͠͝l̷̢͈̙͕͝a̴̧̨̢̧̧̧̨̨̛̛̰̙̹̭̻̘̤̪͎̯͈͙̻͕̜̹̲͎̜͔̻̟͉̾̾͑́̍͆́͛̍̀͛̂͂͑͒͜͝ţ̵̨̩̞̦̺̯̱̝̻̹̜̩͙̮̤̘̟͉͉̘̩̻̠̻̜͖̗̝͓̝͖͚̜̥͍̠̗̰̦̱͔̤̣̮͔̿̓͒̍̈́̀̔̌̐̉͋̌̋͐̅̈́͘͜ȟ̶̢̧̦͔̞̺̮͎̻̣̪̮̣̱̮̤͇͈͖̮̯̝̩̻̄͂͊̈́͂̀̎́̊͌̒̉̊̓̊̀̂̆̋̚͜͠ǫ̸̤̪̜̲̠͕̮͔̜͔͚̺̠̲͇͓̺̣̣̗̭̠̫̓͗̽͋͘͜͠ţ̸̧̨̨̨̛̛̩̫̫̟̣͍̭̯͕̩͖̝̜̱͖͈̯̺̞̬̮̱̲̦͎̠̤̟̖͓͎̹̦̭̖̲̞̱̹̬̯̗͈̓̈́̎͒̒̔̎͑͐͛̄̊͛́̈́̄̾͛̒̒̑́̎͌̌̏̐̑͗̊̈́̀͌̂̏̀́̚͘͝ȩ̴̨̢̛̛̦̥̤̟̣͇̱̜̥̠̦̻̳̼̣̜̺̼̼̝̳͖͙͍̗̦͕̼̟̟̹̹̝̣̮̜͓̜̼̺̺̈́̍̐̽̔́̾̓̔̅̿̽͊̈͒̊̓̔̏̐̐̽̄̈́͑̌̉̉͘͘p̴̡̡̨̧̛̜̫̠͉̜̯͍̩̠̥̩̣̩̲̦̗͚̗̲͕̾̀͗̊̀̊͛̐̽͌̎̊̎̑̍́̓̒̅̉͗̐̿̊̃͋́͂̍͆͂͘̕͜͠", "nya");
expect(start).toBe(0);
expect(end).toBe(115);
expect(match).toBe("N̸̟̤̦̥̦͚̘̟̙͓͚̱͇̱͍̦͓͕̝͈̣̺͔̐͂͑̂̅̇̄̏͐̒̾̋̿̀̐̎̄͗̀͋̈́̉̈́͑̋͊̃̃̃͌̃́̚̚͝͝y̸̢̢̢̧͙̳̫̙̺̝͔̭̲̮͎̦͈͉͚̣̖̞̳͙͚͕̪̘̓̓̇͗͑̈͋͑̅̒̎̄̉̊͌̂̈́̏̚͜ͅͅa");
});
});
describe("corner cases", () => {
test("empty source string", () => {
const { start, end, match } = normalizedMatch("", "Œdipe Roi");
expect(start).toBe(-1);
expect(end).toBe(-1);
expect(match).toBe("");
});
test("empty substring", () => {
const { start, end, match } = normalizedMatch("泽龙", "");
expect(start).toBe(0);
expect(end).toBe(0);
expect(match).toBe("");
});
test("empty inputs", () => {
const { start, end, match } = normalizedMatch("", "");
expect(start).toBe(0);
expect(end).toBe(0);
expect(match).toBe("");
});
test("matches last character", () => {
const { start, end, match } = normalizedMatch("雨晨", "晨");
expect(start).toBe(1);
expect(end).toBe(2);
expect(match).toBe("晨");
});
});
});