summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2021-09-09 05:06:46 +0100
committerLinus Groh <mail@linusgroh.de>2021-09-09 09:06:23 +0100
commit092ec0cecf86d5a58469b8f60750c810e6a25df8 (patch)
treee57e7dd6a333a76d54c903cf19cc9483dc7d0bd1 /Userland
parent58e2597dc2e755c1451a0383528375507e86a06b (diff)
downloadserenity-092ec0cecf86d5a58469b8f60750c810e6a25df8.zip
LibJS: Implement Temporal.PlainYearMonth.from
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp30
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.h2
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js83
3 files changed, 115 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp
index 2900d46de9..d532c7887b 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp
@@ -28,6 +28,9 @@ void PlainYearMonthConstructor::initialize(GlobalObject& global_object)
define_direct_property(vm.names.prototype, global_object.temporal_plain_year_month_prototype(), 0);
define_direct_property(vm.names.length, Value(2), Attribute::Configurable);
+
+ u8 attr = Attribute::Writable | Attribute::Configurable;
+ define_native_function(vm.names.from, from, 1, attr);
}
// 9.1.1 Temporal.PlainYearMonth ( isoYear, isoMonth [ , calendarLike [ , referenceISODay ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth
@@ -89,4 +92,31 @@ Value PlainYearMonthConstructor::construct(FunctionObject& new_target)
return create_temporal_year_month(global_object, y, m, *calendar, ref, &new_target);
}
+// 9.2.2 Temporal.PlainYearMonth.from ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth.from
+JS_DEFINE_NATIVE_FUNCTION(PlainYearMonthConstructor::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 [[InitializedTemporalYearMonth]] internal slot, then
+ if (item.is_object() && is<PlainYearMonth>(item.as_object())) {
+ // a. Perform ? ToTemporalOverflow(options).
+ (void)to_temporal_overflow(global_object, *options);
+ if (vm.exception())
+ return {};
+
+ auto& plain_year_month_object = static_cast<PlainYearMonth&>(item.as_object());
+
+ // b. Return ? CreateTemporalYearMonth(item.[[ISOYear]], item.[[ISOMonth]], item.[[Calendar]], item.[[ISODay]]).
+ return create_temporal_year_month(global_object, plain_year_month_object.iso_year(), plain_year_month_object.iso_month(), plain_year_month_object.calendar(), plain_year_month_object.iso_day());
+ }
+
+ // 3. Return ? ToTemporalYearMonth(item, options).
+ return to_temporal_year_month(global_object, item, options);
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.h
index 3669af06ce..16c13d07b6 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.h
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.h
@@ -23,6 +23,8 @@ public:
private:
virtual bool has_constructor() const override { return true; }
+
+ JS_DECLARE_NATIVE_FUNCTION(from);
};
}
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js
new file mode 100644
index 0000000000..a47b44de36
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainYearMonth/PlainYearMonth.from.js
@@ -0,0 +1,83 @@
+describe("correct behavior", () => {
+ test("length is 1", () => {
+ expect(Temporal.PlainYearMonth.from).toHaveLength(1);
+ });
+
+ test("PlainDate instance argument", () => {
+ const plainDate = new Temporal.PlainDate(2021, 7, 6);
+ const plainYearMonth = Temporal.PlainYearMonth.from(plainDate);
+ expect(plainYearMonth.year).toBe(2021);
+ expect(plainYearMonth.month).toBe(7);
+ expect(plainYearMonth.monthCode).toBe("M07");
+ expect(plainYearMonth.daysInYear).toBe(365);
+ expect(plainYearMonth.daysInMonth).toBe(31);
+ expect(plainYearMonth.monthsInYear).toBe(12);
+ expect(plainYearMonth.inLeapYear).toBeFalse();
+ });
+
+ test("PlainYearMonth instance argument", () => {
+ const plainYearMonth_ = new Temporal.PlainYearMonth(2021, 7);
+ const plainYearMonth = Temporal.PlainYearMonth.from(plainYearMonth_);
+ expect(plainYearMonth.year).toBe(2021);
+ expect(plainYearMonth.month).toBe(7);
+ expect(plainYearMonth.monthCode).toBe("M07");
+ expect(plainYearMonth.daysInYear).toBe(365);
+ expect(plainYearMonth.daysInMonth).toBe(31);
+ expect(plainYearMonth.monthsInYear).toBe(12);
+ expect(plainYearMonth.inLeapYear).toBeFalse();
+ });
+
+ test("ZonedDateTime instance argument", () => {
+ const timeZone = new Temporal.TimeZone("UTC");
+ const zonedDateTime = new Temporal.ZonedDateTime(1625614921000000000n, timeZone);
+ const plainYearMonth = Temporal.PlainYearMonth.from(zonedDateTime);
+ expect(plainYearMonth.year).toBe(2021);
+ expect(plainYearMonth.month).toBe(7);
+ expect(plainYearMonth.monthCode).toBe("M07");
+ expect(plainYearMonth.daysInYear).toBe(365);
+ expect(plainYearMonth.daysInMonth).toBe(31);
+ expect(plainYearMonth.monthsInYear).toBe(12);
+ expect(plainYearMonth.inLeapYear).toBeFalse();
+ });
+
+ test("fields object argument", () => {
+ const object = {
+ year: 2021,
+ month: 7,
+ };
+ const plainYearMonth = Temporal.PlainYearMonth.from(object);
+ expect(plainYearMonth.year).toBe(2021);
+ expect(plainYearMonth.month).toBe(7);
+ expect(plainYearMonth.monthCode).toBe("M07");
+ expect(plainYearMonth.daysInYear).toBe(365);
+ expect(plainYearMonth.daysInMonth).toBe(31);
+ expect(plainYearMonth.monthsInYear).toBe(12);
+ expect(plainYearMonth.inLeapYear).toBeFalse();
+ });
+
+ // Un-skip once ParseISODateTime & ParseTemporalYearMonthString are fully implemented
+ test.skip("PlainYearMonth string argument", () => {
+ const plainYearMonth = Temporal.PlainYearMonth.from("2021-07-06T23:42:01Z");
+ expect(plainYearMonth.year).toBe(2021);
+ expect(plainYearMonth.month).toBe(7);
+ expect(plainYearMonth.monthCode).toBe("M07");
+ expect(plainYearMonth.daysInYear).toBe(365);
+ expect(plainYearMonth.daysInMonth).toBe(31);
+ expect(plainYearMonth.monthsInYear).toBe(12);
+ expect(plainYearMonth.inLeapYear).toBeFalse();
+ });
+});
+
+describe("errors", () => {
+ test("missing fields", () => {
+ expect(() => {
+ Temporal.PlainYearMonth.from({});
+ }).toThrowWithMessage(TypeError, "Required property year is missing or undefined");
+ expect(() => {
+ Temporal.PlainYearMonth.from({ year: 0 });
+ }).toThrowWithMessage(TypeError, "Required property month is missing or undefined");
+ expect(() => {
+ Temporal.PlainYearMonth.from({ month: 1 });
+ }).toThrowWithMessage(TypeError, "Required property year is missing or undefined");
+ });
+});