Граничные случаи в библиотеке Globalize возникают в ситуациях, когда входные данные находятся на границе допустимых значений либо содержат культурные особенности конкретной локали. Большинство ошибок интернационализации проявляется именно в таких сценариях:
null и undefined;Тестирование таких случаев позволяет избежать ошибок отображения, парсинга и форматирования.
Globalize полностью зависит от CLDR. Если необходимые данные не загружены, библиотека выбрасывает исключения.
const Globalize = require("globalize");
Globalize.locale("fr");
const formatter = Globalize.numberFormatter();
console.log(formatter(1234.56));
При отсутствии CLDR:
E_MISSING_CLDR
Частая ошибка — загрузка только части модулей CLDR.
const Cldr = require("cldrjs");
Cldr.load(require("cldr-data/main/en/numbers.json"));
Форматирование даты завершится ошибкой:
const dateFormatter = Globalize.dateFormatter();
dateFormatter(new Date());
Ошибка:
E_MISSING_CLDR
Globalize.locale("xx-YY");
Несуществующая локаль:
Некоторые локали наследуют данные от базовых языков.
Globalize.locale("en-CA");
Если специфических данных для en-CA нет, используются
данные en.
Проверка:
const formatter = Globalize.numberFormatter();
console.log(formatter(12345.67));
nullconst formatter = Globalize.numberFormatter();
formatter(null);
Возможные последствия:
0;"null".Поведение зависит от версии Globalize и пользовательской логики.
undefinedformatter(undefined);
Типичная ошибка:
E_INVALID_PAR_TYPE
const parser = Globalize.numberParser();
parser("");
Следует проверять:
NaN;null;formatter(NaN);
Во многих локалях отображается как:
NaN
Но отдельные CLDR-наборы могут использовать локализованные представления.
formatter(Infinity);
Возможный вывод:
∞
formatter(-Infinity);
Проверяется:
formatter(999999999999999999999);
Проблемы:
formatter(0.0000000000000001);
Необходимо проверять:
Разные локали используют разные шаблоны отрицательных значений.
formatter(-1234.56);
Возможные форматы:
-1,234.56
или
(1,234.56)
Некоторые локали используют альтернативные цифровые системы.
Globalize.locale("ar");
const formatter = Globalize.numberFormatter();
console.log(formatter(123456));
Результат:
١٢٣٤٥٦
Локализация часто использует специальные символы Unicode:
Globalize.locale("fr");
console.log(formatter(10000));
Результат может содержать:
10 000
Между числами — не обычный пробел.
RTL-языки требуют отдельного тестирования.
Globalize.locale("he");
Проблемы:
const formatter = Globalize.currencyFormatter("XXX");
formatter(100);
Проверяется:
Некоторые валюты больше не используются.
Globalize.currencyFormatter("DEM");
Следует проверять:
Не все валюты используют две цифры после запятой.
Globalize.currencyFormatter("JPY")(1000.55);
Результат:
¥1,001
Globalize.currencyFormatter("BHD")(10.1234);
Валюта использует три знака после запятой.
formatter(1.005);
JavaScript может вернуть неожиданный результат:
1.00
Причина — IEEE 754.
const formatter = Globalize.numberFormatter({
style: "scientific"
});
formatter(123456789);
Проверяется:
const formatter = Globalize.numberFormatter({
style: "percent"
});
formatter(1);
formatter(0);
formatter(-1);
new Date(-8640000000000000)
new Date(8640000000000000)
Некоторые движки JavaScript форматируют такие значения по-разному.
const invalidDate = new Date("invalid");
Проверка:
formatter(invalidDate);
Ожидается:
new Date(2024, 1, 29)
new Date(2023, 1, 29)
JavaScript автоматически преобразует:
1 марта 2023
Это необходимо учитывать при тестировании.
DST — один из самых сложных граничных случаев.
new Date("2025-03-30T02:30:00")
Во многих временных зонах такой момент времени не существует.
При переходе на зимнее время один и тот же час встречается дважды.
new Date("2025-10-26T02:30:00")
Некоторые зоны используют:
UTC+5:30UTC+5:45UTC+8:45Некоторые локали используют альтернативные календари.
Globalize.locale("ja");
Globalize.locale("ar-SA");
Globalize.locale("de");
const parser = Globalize.numberParser();
parser("1.234,56");
Результат:
1234.56
parser("1,234");
В разных локалях результат отличается:
12341.234parser("123abc");
Необходимо тестировать:
parser("10 000");
parser("10 000");
Вторая строка содержит NBSP.
Некоторые данные содержат скрытые Unicode-символы.
const value = "1\u200B000";
Проверяется устойчивость парсинга.
Правила множественного числа различаются между языками.
const plural = Globalize.pluralGenerator();
plural(1); // one
plural(2); // other
Globalize.locale("ru");
Категории:
plural(1.5);
Некоторые языки имеют отдельные категории для дробных значений.
const formatter = Globalize.messageFormatter(
"{name} has {count} messages"
);
formatter({
count: 5
});
Параметр name отсутствует.
formatter({
count: {}
});
{
count,
plural,
one {# file}
other {# files}
}
Тестируются:
for (let i = 0; i < 100000; i++) {
formatter(i);
}
Проверяются:
В серверных приложениях форматтеры могут использоваться одновременно.
Promise.all([
asyncTask1(),
asyncTask2(),
asyncTask3()
]);
Проверяется:
Globalize.locale().Globalize.locale("en");
const enFormatter = Globalize.numberFormatter();
Globalize.locale("fr");
const frFormatter = Globalize.numberFormatter();
Важно убедиться, что старые formatter-объекты:
Форматтеры содержат внутреннее состояние.
JSON.stringify(formatter);
Проверяется:
Разные версии CLDR могут изменять:
Особенно важны:
Проблемы:
Intl;Date.describe("number formatting", () => {
test("formats large numbers", () => {
const formatter = Globalize.numberFormatter();
expect(formatter(1000000))
.toBe("1,000,000");
});
});
const locales = ["en", "fr", "de", "ru"];
locales.forEach(locale => {
test(`locale ${locale}`, () => {
Globalize.locale(locale);
const formatter = Globalize.numberFormatter();
expect(formatter(1000)).toBeDefined();
});
});
Подходит для проверки больших наборов локализованных строк.
expect(formatter(12345.67))
.toMatchSnapshot();
После обновления CLDR или Globalize необходимо повторно проверять:
Особенно опасны:
parser("1234");
Используются fullwidth-символы Unicode.
Некорректный ICU-шаблон может вызвать ошибки.
"{name"
Необходимо тестировать:
for (let i = 0; i < 100000; i++) {
formatter(Math.random() * Number.MAX_VALUE);
}
Помогает выявлять:
Globalize активно использует внутренние кеши.
const formatter1 = Globalize.numberFormatter();
const formatter2 = Globalize.numberFormatter();
Тестируются:
При серверном рендеринге особенно важны:
При использовании Worker Threads:
const { Worker } = require("worker_threads");
Следует проверять: