From 67b3255fe84324e384a52e19fb5233ccb3665c1d Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Mon, 26 Jul 2021 17:07:59 +0300 Subject: [PATCH] LibJS: Implement Temporal.PlainDate.from --- .../Runtime/Temporal/PlainDateConstructor.cpp | 25 +++++++++++++++++++ .../Runtime/Temporal/PlainDateConstructor.h | 1 + .../Temporal/PlainDate/PlainDate.from.js | 21 ++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp index b6f38b2d6b..b5b52546eb 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp @@ -28,6 +28,7 @@ void PlainDateConstructor::initialize(GlobalObject& global_object) define_direct_property(vm.names.prototype, global_object.temporal_plain_date_prototype(), 0); u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(vm.names.from, from, 1, attr); define_native_function(vm.names.compare, compare, 2, attr); define_direct_property(vm.names.length, Value(3), Attribute::Configurable); @@ -96,6 +97,30 @@ Value PlainDateConstructor::construct(FunctionObject& new_target) return create_temporal_date(global_object, y, m, d, *calendar, &new_target); } +// 3.2.2 Temporal.PlainDate.from ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.from +JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::from) +{ + // 1. Set options to ? GetOptionsObject(options). + auto* options = get_options_object(global_object, vm.argument(1)); + if (vm.exception()) + return {}; + + auto item = vm.argument(0); + // 2. If Type(item) is Object and item has an [[InitializedTemporalDate]] internal slot, then + if (item.is_object() && is(item.as_object())) { + auto& plain_date_item = static_cast(item.as_object()); + // a. Perform ? ToTemporalOverflow(options). + (void)to_temporal_overflow(global_object, *options); + if (vm.exception()) + return {}; + // b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]). + return create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar()); + } + + // 3. Return ? ToTemporalDate(item, options). + return to_temporal_date(global_object, item, options); +} + // 3.2.3 Temporal.PlainDate.compare ( one, two ), https://tc39.es/proposal-temporal/#sec-properties-of-the-temporal-plaindate-constructor JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::compare) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h index e02a3153c4..4a0d6ab6df 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h @@ -24,6 +24,7 @@ public: private: virtual bool has_constructor() const override { return true; } + JS_DECLARE_NATIVE_FUNCTION(from); JS_DECLARE_NATIVE_FUNCTION(compare); }; diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js new file mode 100644 index 0000000000..d6f5730656 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js @@ -0,0 +1,21 @@ +describe("correct behavior", () => { + test("length is 1", () => { + expect(Temporal.PlainDate.from).toHaveLength(1); + }); + + test("PlainDate instance argument", () => { + const plainDate = new Temporal.PlainDate(2021, 7, 26); + const createdPlainDate = Temporal.PlainDate.from(plainDate); + expect(createdPlainDate.year).toBe(2021); + expect(createdPlainDate.month).toBe(7); + expect(createdPlainDate.day).toBe(26); + }); + + // Un-skip once ParseISODateTime & ParseTemporalDateString are implemented + test.skip("PlainDate string argument", () => { + const createdPlainDate = Temporal.PlainDate.from("2021-07-26"); + expect(createdPlainDate.year).toBe(2021); + expect(createdPlainDate.month).toBe(7); + expect(createdPlainDate.day).toBe(26); + }); +});