ソースを参照

LibJS: Implement Intl.ListFormat.prototype.resolvedOptions

Timothy Flynn 3 年 前
コミット
ef94c73a01

+ 26 - 0
Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp

@@ -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;
+}
+
 }
 }

+ 1 - 0
Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.h

@@ -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);
 };
 };
 
 
 }
 }

+ 38 - 0
Userland/Libraries/LibJS/Tests/builtins/Intl/ListFormat/ListFormat.prototype.resolvedOptions.js

@@ -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");
+    });
+});