LibJS: Partially implement Intl.Locale.prototype.collations property

We do not yet parse collation data from the CLDR. This stubs out the
collations property, analogous to Intl.supportedValuesOf.
This commit is contained in:
Timothy Flynn 2022-07-05 12:28:21 -04:00 committed by Linus Groh
parent e9bc35d805
commit 4d32f38a76
7 changed files with 57 additions and 2 deletions

View file

@ -98,6 +98,7 @@ namespace JS {
P(clz32) \
P(codePointAt) \
P(collation) \
P(collations) \
P(compactDisplay) \
P(compareExchange) \
P(compile) \

View file

@ -120,7 +120,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
// 3. Else if key is "collation", then
else if (key == "collation"sv) {
// a. Let list be ! AvailableCollations( ).
// NOTE: We don't yet parse any collation data, but "default" is allowed.
// FIXME: We don't yet parse any collation data, but "default" is allowed. This matches Intl.Locale.prototype.collations.
static constexpr auto collations = AK::Array { "default"sv };
list = collations.span();
}

View file

@ -87,4 +87,24 @@ Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale_obj
return create_array_from_list_or_restricted(global_object, move(list), move(restricted));
}
// 1.1.3 CollationsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-collations-of-locale
Array* collations_of_locale(GlobalObject& global_object, Locale const& locale_object)
{
// 1. Let restricted be loc.[[Collation]].
Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {};
// 2. Let locale be loc.[[Locale]].
auto const& locale = locale_object.locale();
// 3. Assert: locale matches the unicode_locale_id production.
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
// 4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
// FIXME: Retrieve this data from the CLDR when we fully support collation. This matches Intl.supportedValuesOf.
Vector<StringView> list { "default"sv };
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
return create_array_from_list_or_restricted(global_object, move(list), move(restricted));
}
}

View file

@ -75,5 +75,6 @@ private:
};
Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale);
Array* collations_of_locale(GlobalObject& global_object, Locale const& locale);
}

View file

@ -38,6 +38,7 @@ void LocalePrototype::initialize(GlobalObject& global_object)
define_native_accessor(vm.names.calendars, calendars, {}, Attribute::Configurable);
define_native_accessor(vm.names.caseFirst, case_first, {}, Attribute::Configurable);
define_native_accessor(vm.names.collation, collation, {}, Attribute::Configurable);
define_native_accessor(vm.names.collations, collations, {}, Attribute::Configurable);
define_native_accessor(vm.names.hourCycle, hour_cycle, {}, Attribute::Configurable);
define_native_accessor(vm.names.numberingSystem, numbering_system, {}, Attribute::Configurable);
define_native_accessor(vm.names.numeric, numeric, {}, Attribute::Configurable);
@ -202,9 +203,11 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
}
#define JS_ENUMERATE_LOCALE_INFO_PROPERTIES \
__JS_ENUMERATE(calendars)
__JS_ENUMERATE(calendars) \
__JS_ENUMERATE(collations)
// 1.4.16 get Intl.Locale.prototype.calendars, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.calendars
// 1.4.17 get Intl.Locale.prototype.collations, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.collations
#define __JS_ENUMERATE(keyword) \
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \
{ \

View file

@ -29,6 +29,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(calendars);
JS_DECLARE_NATIVE_FUNCTION(case_first);
JS_DECLARE_NATIVE_FUNCTION(collation);
JS_DECLARE_NATIVE_FUNCTION(collations);
JS_DECLARE_NATIVE_FUNCTION(hour_cycle);
JS_DECLARE_NATIVE_FUNCTION(numbering_system);
JS_DECLARE_NATIVE_FUNCTION(numeric);

View file

@ -0,0 +1,29 @@
describe("errors", () => {
test("called on non-Locale object", () => {
expect(() => {
Intl.Locale.prototype.collations;
}).toThrowWithMessage(TypeError, "Not an object of type Intl.Locale");
});
});
describe("normal behavior", () => {
test("basic functionality", () => {
expect(Array.isArray(new Intl.Locale("en").collations)).toBeTrue();
expect(new Intl.Locale("en").collations).toEqual(["default"]);
expect(Array.isArray(new Intl.Locale("ar").collations)).toBeTrue();
expect(new Intl.Locale("ar").collations).toEqual(["default"]);
});
test("extension keyword overrides default data", () => {
expect(new Intl.Locale("en-u-co-compat").collations).toEqual(["compat"]);
expect(new Intl.Locale("en", { collation: "compat" }).collations).toEqual(["compat"]);
expect(new Intl.Locale("ar-u-co-reformed").collations).toEqual(["reformed"]);
expect(new Intl.Locale("ar", { collation: "reformed" }).collations).toEqual(["reformed"]);
// Invalid collations also take precedence.
expect(new Intl.Locale("en-u-co-ladybird").collations).toEqual(["ladybird"]);
expect(new Intl.Locale("en", { collation: "ladybird" }).collations).toEqual(["ladybird"]);
});
});