LibJS: Implement Intl.ListFormat.prototype.resolvedOptions

This commit is contained in:
Timothy Flynn 2021-09-06 15:09:18 -04:00 committed by Linus Groh
parent 5c06a91dfa
commit ef94c73a01
Notes: sideshowbarker 2024-07-18 04:33:08 +09:00
3 changed files with 65 additions and 0 deletions

View file

@ -301,6 +301,7 @@ void ListFormatPrototype::initialize(GlobalObject& global_object)
u8 attr = Attribute::Writable | Attribute::Configurable; u8 attr = Attribute::Writable | Attribute::Configurable;
define_native_function(vm.names.format, format, 1, attr); define_native_function(vm.names.format, format, 1, attr);
define_native_function(vm.names.formatToParts, format_to_parts, 1, attr); define_native_function(vm.names.formatToParts, format_to_parts, 1, attr);
define_native_function(vm.names.resolvedOptions, resolved_options, 0, attr);
} }
// 13.4.3 Intl.ListFormat.prototype.format ( list ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.format // 13.4.3 Intl.ListFormat.prototype.format ( list ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.format
@ -344,4 +345,29 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts)
return format_list_to_parts(global_object, *list_format, string_list); return format_list_to_parts(global_object, *list_format, string_list);
} }
// 3.4.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
{
// 1. Let lf be the this value.
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
auto* list_format = typed_this(global_object);
if (vm.exception())
return {};
// 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
auto* options = Object::create(global_object, global_object.object_prototype());
// 4. For each row of Table 9, except the header row, in table order, do
// a. Let p be the Property value of the current row.
// b. Let v be the value of lf's internal slot whose name is the Internal Slot value of the current row.
// c. Assert: v is not undefined.
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
options->create_data_property_or_throw(vm.names.locale, js_string(vm, list_format->locale()));
options->create_data_property_or_throw(vm.names.type, js_string(vm, list_format->type_string()));
options->create_data_property_or_throw(vm.names.style, js_string(vm, list_format->style_string()));
// 5. Return options.
return options;
}
} }

View file

@ -21,6 +21,7 @@ public:
private: private:
JS_DECLARE_NATIVE_FUNCTION(format); JS_DECLARE_NATIVE_FUNCTION(format);
JS_DECLARE_NATIVE_FUNCTION(format_to_parts); JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
}; };
} }

View file

@ -0,0 +1,38 @@
describe("correct behavior", () => {
test("length is 0", () => {
expect(Intl.ListFormat.prototype.resolvedOptions).toHaveLength(0);
});
test("all valid types", () => {
["conjunction", "disjunction", "unit"].forEach(type => {
const en = new Intl.ListFormat("en", { type: type });
expect(en.resolvedOptions()).toEqual({
locale: "en",
type: type,
style: "long",
});
});
});
test("all valid styles", () => {
["long", "short", "narrow"].forEach(style => {
const en = new Intl.ListFormat("en", { style: style });
expect(en.resolvedOptions()).toEqual({
locale: "en",
type: "conjunction",
style: style,
});
});
});
test("locales with extensions", () => {
const en = new Intl.ListFormat("en-t-en");
expect(en.resolvedOptions().locale).toBe("en");
const es419 = new Intl.ListFormat("es-419-u-1k-aaa");
expect(es419.resolvedOptions().locale).toBe("es-419");
const zhHant = new Intl.ListFormat(["zh-Hant-x-aaa"]);
expect(zhHant.resolvedOptions().locale).toBe("zh-Hant");
});
});