oca-ocb-core/odoo-bringout-oca-ocb-web/web/static/tests/l10n/utils.test.js
Ernad Husremovic d1963a3c3a vanilla 19.0
2025-10-08 10:49:46 +02:00

186 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("晨");
});
});
});