diff --git a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp index b01108797ae..b48b24f522e 100644 --- a/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp +++ b/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, Tim Flynn + * Copyright (c) 2022-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -90,7 +90,8 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options) // 3. Let options be OrdinaryObjectCreate(%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 plural_categories = Array::create_from(realm, available_categories, [&](auto category) { diff --git a/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.resolvedOptions.js b/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.resolvedOptions.js index 76fc86c7705..204251ac628 100644 --- a/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.resolvedOptions.js +++ b/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.resolvedOptions.js @@ -79,30 +79,17 @@ describe("correct behavior", () => { }); 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(); - expect(enCardinal.pluralCategories).toBeDefined(); - expect(contains(enCardinal.pluralCategories, ["other", "one"])).toBeTrue(); + expect(enCardinal.pluralCategories).toEqual(["one", "other"]); const enOrdinal = new Intl.PluralRules("en", { type: "ordinal" }).resolvedOptions(); - expect(enOrdinal.pluralCategories).toBeDefined(); - expect(contains(enOrdinal.pluralCategories, ["other", "one", "two", "few"])).toBeTrue(); + expect(enOrdinal.pluralCategories).toEqual(["one", "two", "few", "other"]); const gaCardinal = new Intl.PluralRules("ga", { type: "cardinal" }).resolvedOptions(); - expect(gaCardinal.pluralCategories).toBeDefined(); - expect( - contains(gaCardinal.pluralCategories, ["other", "one", "two", "few", "many"]) - ).toBeTrue(); + expect(gaCardinal.pluralCategories).toEqual(["one", "two", "few", "many", "other"]); const gaOrdinal = new Intl.PluralRules("ga", { type: "ordinal" }).resolvedOptions(); - expect(gaOrdinal.pluralCategories).toBeDefined(); - expect(contains(gaOrdinal.pluralCategories, ["other", "one"])).toBeTrue(); + expect(gaOrdinal.pluralCategories).toEqual(["one", "other"]); }); test("rounding priority", () => { diff --git a/Libraries/LibUnicode/NumberFormat.cpp b/Libraries/LibUnicode/NumberFormat.cpp index a45bd39061f..a44d6aba57d 100644 --- a/Libraries/LibUnicode/NumberFormat.cpp +++ b/Libraries/LibUnicode/NumberFormat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024, Tim Flynn + * Copyright (c) 2021-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -733,6 +733,7 @@ public: result.append(plural_category_from_string({ category, static_cast(length) })); } + quick_sort(result); return result; } diff --git a/Libraries/LibUnicode/PluralRules.h b/Libraries/LibUnicode/PluralRules.h index 67a61cebd89..62182bd0d90 100644 --- a/Libraries/LibUnicode/PluralRules.h +++ b/Libraries/LibUnicode/PluralRules.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024, Tim Flynn + * Copyright (c) 2022-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -18,12 +18,13 @@ PluralForm plural_form_from_string(StringView); StringView plural_form_to_string(PluralForm); enum class PluralCategory { - Other, + // NOTE: These are sorted in preferred order for Intl.PluralRules.prototype.resolvedOptions. Zero, One, Two, Few, Many, + Other, // https://unicode.org/reports/tr35/tr35-numbers.html#Explicit_0_1_rules ExactlyZero,