LibJS: Populate pluralCategories in Intl.PluralRules.resolvedOptions

This commit is contained in:
Timothy Flynn 2022-07-07 12:21:27 -04:00 committed by Linus Groh
parent 670bd066a5
commit f11cb7c075
Notes: sideshowbarker 2024-07-17 09:37:23 +09:00
2 changed files with 31 additions and 7 deletions

View file

@ -8,6 +8,7 @@
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/PluralRulesPrototype.h>
#include <LibUnicode/PluralRules.h>
namespace JS::Intl {
@ -58,11 +59,14 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(plural_rules->max_significant_digits())));
// 5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
// FIXME: Implement this when the data is available in LibUnicode.
MarkedVector<Value> plural_categories { vm.heap() };
auto available_categories = Unicode::available_plural_categories(plural_rules->locale(), plural_rules->type());
auto* plural_categories = Array::create_from<Unicode::PluralCategory>(global_object, available_categories, [&](auto category) {
return js_string(vm, Unicode::plural_category_to_string(category));
});
// 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
MUST(options->create_data_property_or_throw(vm.names.pluralCategories, Array::create_from(global_object, plural_categories)));
MUST(options->create_data_property_or_throw(vm.names.pluralCategories, plural_categories));
// 7. Return options.
return options;

View file

@ -79,9 +79,29 @@ describe("correct behavior", () => {
});
test("plural categories", () => {
// FIXME: Write better tests when this is implemented.
const en = new Intl.PluralRules("en");
expect(en.resolvedOptions().pluralCategories).toBeDefined();
expect(en.resolvedOptions().pluralCategories).toEqual([]);
// 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();
const enOrdinal = new Intl.PluralRules("en", { type: "ordinal" }).resolvedOptions();
expect(enOrdinal.pluralCategories).toBeDefined();
expect(contains(enOrdinal.pluralCategories, ["other", "one", "two", "few"])).toBeTrue();
const gaCardinal = new Intl.PluralRules("ga", { type: "cardinal" }).resolvedOptions();
expect(gaCardinal.pluralCategories).toBeDefined();
expect(
contains(gaCardinal.pluralCategories, ["other", "one", "two", "few", "many"])
).toBeTrue();
const gaOrdinal = new Intl.PluralRules("ga", { type: "ordinal" }).resolvedOptions();
expect(gaOrdinal.pluralCategories).toBeDefined();
expect(contains(gaOrdinal.pluralCategories, ["other", "one"])).toBeTrue();
});
});