diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2021-09-06 21:36:54 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-09-06 22:15:39 +0100 |
commit | 4b5aa2102cfae44643180c97d59483cafb57d02b (patch) | |
tree | c3e407b4c2d648bfe1ee572ae6721a1386fe04e6 /Userland/Libraries/LibJS | |
parent | 470499b2a88b88098f2a1e2252cdada61a236002 (diff) | |
download | serenity-4b5aa2102cfae44643180c97d59483cafb57d02b.zip |
LibJS: Implement Temporal.Instant.prototype.since
Diffstat (limited to 'Userland/Libraries/LibJS')
4 files changed, 83 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index ff7a1d11f1..b5faf7e375 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -381,6 +381,7 @@ namespace JS { P(shift) \ P(sign) \ P(sin) \ + P(since) \ P(sinh) \ P(size) \ P(slice) \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp index a56c940df8..e505f515e2 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.cpp @@ -39,6 +39,7 @@ void InstantPrototype::initialize(GlobalObject& global_object) define_native_function(vm.names.add, add, 1, attr); define_native_function(vm.names.subtract, subtract, 1, attr); define_native_function(vm.names.until, until, 1, attr); + define_native_function(vm.names.since, since, 1, attr); define_native_function(vm.names.round, round, 1, attr); define_native_function(vm.names.equals, equals, 1, attr); define_native_function(vm.names.toString, to_string, 0, attr); @@ -243,6 +244,66 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::until) return create_temporal_duration(global_object, 0, 0, 0, 0, result->hours, result->minutes, result->seconds, result->milliseconds, result->microseconds, result->nanoseconds); } +// 8.3.10 Temporal.Instant.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.instant.prototype.since +JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::since) +{ + // 1. Let instant be the this value. + // 2. Perform ? RequireInternalSlot(instant, [[InitializedTemporalInstant]]). + auto* instant = typed_this(global_object); + if (vm.exception()) + return {}; + + // 3. Set other to ? ToTemporalInstant(other). + auto* other = to_temporal_instant(global_object, vm.argument(0)); + if (vm.exception()) + return {}; + + // 4. Set options to ? GetOptionsObject(options). + auto* options = get_options_object(global_object, vm.argument(1)); + if (vm.exception()) + return {}; + + // 5. Let smallestUnit be ? ToSmallestTemporalUnit(options, « "year", "month", "week", "day" », "nanosecond"). + auto smallest_unit = to_smallest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "nanosecond"sv); + if (vm.exception()) + return {}; + + // 6. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits("second", smallestUnit). + auto default_largest_unit = larger_of_two_temporal_units("second"sv, *smallest_unit); + + // 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "year", "month", "week", "day" », "auto", defaultLargestUnit). + auto largest_unit = to_largest_temporal_unit(global_object, *options, { "year"sv, "month"sv, "week"sv, "day"sv }, "auto"sv, move(default_largest_unit)); + if (vm.exception()) + return {}; + + // 8. Perform ? ValidateTemporalUnitRange(largestUnit, smallestUnit). + validate_temporal_unit_range(global_object, *largest_unit, *smallest_unit); + if (vm.exception()) + return {}; + + // 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc"). + auto rounding_mode = to_temporal_rounding_mode(global_object, *options, "trunc"sv); + if (vm.exception()) + return {}; + + // 10. Let maximum be ! MaximumTemporalDurationRoundingIncrement(smallestUnit). + auto maximum = maximum_temporal_duration_rounding_increment(*smallest_unit); + + // 11. Let roundingIncrement be ? ToTemporalRoundingIncrement(options, maximum, false). + auto rounding_increment = to_temporal_rounding_increment(global_object, *options, *maximum, false); + if (vm.exception()) + return {}; + + // 12. Let roundedNs be ! DifferenceInstant(other.[[Nanoseconds]], instant.[[Nanoseconds]], roundingIncrement, smallestUnit, roundingMode). + auto rounded_ns = difference_instant(global_object, other->nanoseconds(), instant->nanoseconds(), rounding_increment, *smallest_unit, *rounding_mode); + + // 13. Let result be ! BalanceDuration(0, 0, 0, 0, 0, 0, roundedNs, largestUnit). + auto result = balance_duration(global_object, 0, 0, 0, 0, 0, 0, *rounded_ns, *largest_unit); + + // 14. Return ? CreateTemporalDuration(0, 0, 0, 0, result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]). + return create_temporal_duration(global_object, 0, 0, 0, 0, result->hours, result->minutes, result->seconds, result->milliseconds, result->microseconds, result->nanoseconds); +} + // 8.3.11 Temporal.Instant.prototype.round ( options ), https://tc39.es/proposal-temporal/#sec-temporal.instant.prototype.round JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::round) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.h index 294df67aa7..013b40dbcf 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/InstantPrototype.h @@ -26,6 +26,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(add); JS_DECLARE_NATIVE_FUNCTION(subtract); JS_DECLARE_NATIVE_FUNCTION(until); + JS_DECLARE_NATIVE_FUNCTION(since); JS_DECLARE_NATIVE_FUNCTION(round); JS_DECLARE_NATIVE_FUNCTION(equals); JS_DECLARE_NATIVE_FUNCTION(to_string); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.since.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.since.js new file mode 100644 index 0000000000..ff527fefff --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.since.js @@ -0,0 +1,20 @@ +describe("correct behavior", () => { + test("length is 1", () => { + expect(Temporal.Instant.prototype.since).toHaveLength(1); + }); + + test("basic functionality", () => { + const instant1 = new Temporal.Instant(1625614920000000000n); + const instant2 = new Temporal.Instant(0n); + expect(instant1.since(instant2).seconds).toBe(1625614920); + expect(instant1.since(instant2, { largestUnit: "hour" }).hours).toBe(27093582); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.Instant object", () => { + expect(() => { + Temporal.Instant.prototype.since.call("foo"); + }).toThrowWithMessage(TypeError, "Not a Temporal.Instant"); + }); +}); |