LibJS+LibUnicode: Designate a sort order for Intl.PluralRules categories

This is a normative change in the ECMA-402 spec. See:
62fe5db
This commit is contained in:
Timothy Flynn 2024-12-04 12:47:40 -05:00 committed by Andreas Kling
commit 5e534f4d83
Notes: github-actions[bot] 2024-12-05 08:50:46 +00:00
4 changed files with 12 additions and 22 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022-2023, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2022-2024, Tim Flynn <trflynn89@ladybird.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -90,7 +90,8 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%). // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
auto options = Object::create(realm, realm.intrinsics().object_prototype()); auto options = Object::create(realm, realm.intrinsics().object_prototype());
// 4. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]]. // 4. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected
// locale pr.[[Locale]], sorted according to the following order: "zero", "one", "two", "few", "many", "other".
auto available_categories = plural_rules->formatter().available_plural_categories(); auto available_categories = plural_rules->formatter().available_plural_categories();
auto plural_categories = Array::create_from<Unicode::PluralCategory>(realm, available_categories, [&](auto category) { auto plural_categories = Array::create_from<Unicode::PluralCategory>(realm, available_categories, [&](auto category) {

View file

@ -79,30 +79,17 @@ describe("correct behavior", () => {
}); });
test("plural categories", () => { test("plural categories", () => {
// The spec doesn't dictate an order of elements, and the generated CLDR data is ordered by
// hash map iteration. Instead of using toEqual(), just make sure all elements are the same.
const contains = (actual, expected) => {
if (actual.length !== expected.length) return false;
return expected.every(e => actual.includes(e));
};
const enCardinal = new Intl.PluralRules("en", { type: "cardinal" }).resolvedOptions(); const enCardinal = new Intl.PluralRules("en", { type: "cardinal" }).resolvedOptions();
expect(enCardinal.pluralCategories).toBeDefined(); expect(enCardinal.pluralCategories).toEqual(["one", "other"]);
expect(contains(enCardinal.pluralCategories, ["other", "one"])).toBeTrue();
const enOrdinal = new Intl.PluralRules("en", { type: "ordinal" }).resolvedOptions(); const enOrdinal = new Intl.PluralRules("en", { type: "ordinal" }).resolvedOptions();
expect(enOrdinal.pluralCategories).toBeDefined(); expect(enOrdinal.pluralCategories).toEqual(["one", "two", "few", "other"]);
expect(contains(enOrdinal.pluralCategories, ["other", "one", "two", "few"])).toBeTrue();
const gaCardinal = new Intl.PluralRules("ga", { type: "cardinal" }).resolvedOptions(); const gaCardinal = new Intl.PluralRules("ga", { type: "cardinal" }).resolvedOptions();
expect(gaCardinal.pluralCategories).toBeDefined(); expect(gaCardinal.pluralCategories).toEqual(["one", "two", "few", "many", "other"]);
expect(
contains(gaCardinal.pluralCategories, ["other", "one", "two", "few", "many"])
).toBeTrue();
const gaOrdinal = new Intl.PluralRules("ga", { type: "ordinal" }).resolvedOptions(); const gaOrdinal = new Intl.PluralRules("ga", { type: "ordinal" }).resolvedOptions();
expect(gaOrdinal.pluralCategories).toBeDefined(); expect(gaOrdinal.pluralCategories).toEqual(["one", "other"]);
expect(contains(gaOrdinal.pluralCategories, ["other", "one"])).toBeTrue();
}); });
test("rounding priority", () => { test("rounding priority", () => {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2021-2024, Tim Flynn <trflynn89@ladybird.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -733,6 +733,7 @@ public:
result.append(plural_category_from_string({ category, static_cast<size_t>(length) })); result.append(plural_category_from_string({ category, static_cast<size_t>(length) }));
} }
quick_sort(result);
return result; return result;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2022-2024, Tim Flynn <trflynn89@ladybird.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -18,12 +18,13 @@ PluralForm plural_form_from_string(StringView);
StringView plural_form_to_string(PluralForm); StringView plural_form_to_string(PluralForm);
enum class PluralCategory { enum class PluralCategory {
Other, // NOTE: These are sorted in preferred order for Intl.PluralRules.prototype.resolvedOptions.
Zero, Zero,
One, One,
Two, Two,
Few, Few,
Many, Many,
Other,
// https://unicode.org/reports/tr35/tr35-numbers.html#Explicit_0_1_rules // https://unicode.org/reports/tr35/tr35-numbers.html#Explicit_0_1_rules
ExactlyZero, ExactlyZero,