From 891dfd9cbbfa6e48ff0a86b6d0295d1fda886f7f Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sun, 30 Jan 2022 00:12:47 +0200 Subject: LibJS: Implement Intl.Segmenter.prototype.resolvedOptions --- .../LibJS/Runtime/Intl/SegmenterPrototype.cpp | 25 +++++++++++++++++++++ .../LibJS/Runtime/Intl/SegmenterPrototype.h | 3 +++ .../Segmenter.prototype.resolvedOptions.js | 26 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Intl/Segmenter/Segmenter.prototype.resolvedOptions.js diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp index 2315a630ea..6f06f03d99 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp @@ -24,6 +24,31 @@ void SegmenterPrototype::initialize(GlobalObject& global_object) // 18.3.2 Intl.Segmenter.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.segmenter.prototype-@@tostringtag define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, "Intl.Segmenter"), Attribute::Configurable); + + u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(vm.names.resolvedOptions, resolved_options, 0, attr); +} + +// 18.3.4 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions +JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options) +{ + // 1. Let segmenter be the this value. + // 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]). + auto* segmenter = TRY(typed_this_object(global_object)); + + // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%). + auto* options = Object::create(global_object, global_object.object_prototype()); + + // 4. For each row of Table 16, 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 segmenter'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). + MUST(options->create_data_property_or_throw(vm.names.locale, js_string(vm, segmenter->locale()))); + MUST(options->create_data_property_or_throw(vm.names.granularity, js_string(vm, segmenter->segmenter_granularity_string()))); + + // 5. Return options. + return options; } } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h b/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h index 815288f3f0..f57084596e 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.h @@ -18,6 +18,9 @@ public: explicit SegmenterPrototype(GlobalObject&); virtual void initialize(GlobalObject&) override; virtual ~SegmenterPrototype() override = default; + +private: + JS_DECLARE_NATIVE_FUNCTION(resolved_options); }; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/Segmenter/Segmenter.prototype.resolvedOptions.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/Segmenter/Segmenter.prototype.resolvedOptions.js new file mode 100644 index 0000000000..5789ba6b1d --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/Segmenter/Segmenter.prototype.resolvedOptions.js @@ -0,0 +1,26 @@ +describe("correct behavior", () => { + test("length is 0", () => { + expect(Intl.Segmenter.prototype.resolvedOptions).toHaveLength(0); + }); + + test("locale only contains relevant extension keys", () => { + const en1 = new Intl.Segmenter("en-u-ca-islamicc"); + expect(en1.resolvedOptions().locale).toBe("en"); + + const en2 = new Intl.Segmenter("en-u-nu-latn"); + expect(en2.resolvedOptions().locale).toBe("en"); + + const en3 = new Intl.Segmenter("en-u-ca-islamicc-nu-latn"); + expect(en3.resolvedOptions().locale).toBe("en"); + }); + + test("granularity", () => { + const en1 = new Intl.Segmenter("en"); + expect(en1.resolvedOptions().granularity).toBe("grapheme"); + + ["grapheme", "word", "sentence"].forEach(granularity => { + const en2 = new Intl.Segmenter("en", { granularity: granularity }); + expect(en2.resolvedOptions().granularity).toBe(granularity); + }); + }); +}); -- cgit v1.2.3