From dfaa3bf649758896d2d96a3e6a50c534f6262905 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 18 Nov 2024 12:31:28 -0500 Subject: [PATCH] LibJS: Implement Temporal.Duration.prototype.sign/blank --- .../Runtime/Temporal/DurationPrototype.cpp | 29 +++++++++++++++++++ .../Runtime/Temporal/DurationPrototype.h | 3 ++ .../Duration/Duration.prototype.blank.js | 17 +++++++++++ .../Duration/Duration.prototype.sign.js | 17 +++++++++++ 4 files changed, 66 insertions(+) create mode 100644 Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.blank.js create mode 100644 Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.sign.js diff --git a/Libraries/LibJS/Runtime/Temporal/DurationPrototype.cpp b/Libraries/LibJS/Runtime/Temporal/DurationPrototype.cpp index fffe0d4489e..dc9e9b08b5e 100644 --- a/Libraries/LibJS/Runtime/Temporal/DurationPrototype.cpp +++ b/Libraries/LibJS/Runtime/Temporal/DurationPrototype.cpp @@ -31,6 +31,9 @@ void DurationPrototype::initialize(Realm& realm) define_native_accessor(realm, vm.names.unit, unit##_getter, {}, Attribute::Configurable); JS_ENUMERATE_DURATION_UNITS #undef __JS_ENUMERATE + + define_native_accessor(realm, vm.names.sign, sign_getter, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.blank, blank_getter, {}, Attribute::Configurable); } // 7.3.3 get Temporal.Duration.prototype.years, https://tc39.es/proposal-temporal/#sec-get-temporal.duration.prototype.years @@ -56,4 +59,30 @@ void DurationPrototype::initialize(Realm& realm) JS_ENUMERATE_DURATION_UNITS #undef __JS_ENUMERATE +// 7.3.13 get Temporal.Duration.prototype.sign, https://tc39.es/proposal-temporal/#sec-get-temporal.duration.prototype.sign +JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::sign_getter) +{ + // 1. Let duration be the this value. + // 2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]). + auto duration = TRY(typed_this_object(vm)); + + // 3. Return 𝔽(DurationSign(duration)). + return duration_sign(duration); +} + +// 7.3.14 get Temporal.Duration.prototype.blank, https://tc39.es/proposal-temporal/#sec-get-temporal.duration.prototype.blank +JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::blank_getter) +{ + // 1. Let duration be the this value. + // 2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]). + auto duration = TRY(typed_this_object(vm)); + + // 3. If DurationSign(duration) = 0, return true. + if (duration_sign(duration) == 0) + return true; + + // 4. Return false. + return false; +} + } diff --git a/Libraries/LibJS/Runtime/Temporal/DurationPrototype.h b/Libraries/LibJS/Runtime/Temporal/DurationPrototype.h index cdbf221779e..e804d3fdf22 100644 --- a/Libraries/LibJS/Runtime/Temporal/DurationPrototype.h +++ b/Libraries/LibJS/Runtime/Temporal/DurationPrototype.h @@ -27,6 +27,9 @@ private: JS_DECLARE_NATIVE_FUNCTION(unit##_getter); JS_ENUMERATE_DURATION_UNITS #undef __JS_ENUMERATE + + JS_DECLARE_NATIVE_FUNCTION(sign_getter); + JS_DECLARE_NATIVE_FUNCTION(blank_getter); }; } diff --git a/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.blank.js b/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.blank.js new file mode 100644 index 00000000000..284d2837a34 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.blank.js @@ -0,0 +1,17 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const nonBlankDuration = new Temporal.Duration(123); + expect(nonBlankDuration.blank).toBeFalse(); + + const blankDuration = new Temporal.Duration(0); + expect(blankDuration.blank).toBeTrue(); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.Duration object", () => { + expect(() => { + Reflect.get(Temporal.Duration.prototype, "blank", "foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Duration"); + }); +}); diff --git a/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.sign.js b/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.sign.js new file mode 100644 index 00000000000..aeabf47d8ef --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.sign.js @@ -0,0 +1,17 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const positiveDuration = new Temporal.Duration(123); + expect(positiveDuration.sign).toBe(1); + + const negativeDuration = new Temporal.Duration(-123); + expect(negativeDuration.sign).toBe(-1); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.Duration object", () => { + expect(() => { + Reflect.get(Temporal.Duration.prototype, "sign", "foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Duration"); + }); +});