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 index fa806cbb01..6c1205712c 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.since.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.since.js @@ -18,3 +18,173 @@ describe("errors", () => { }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Instant"); }); }); + +describe("rounding modes", () => { + const earlier = new Temporal.Instant( + 217178610_123_456_789n /* 1976-11-18T15:23:30.123456789Z */ + ); + const later = new Temporal.Instant( + 1572345998_271_986_289n /* 2019-10-29T10:46:38.271986289Z */ + ); + const largestUnit = "hours"; + + test("'ceil' rounding mode", () => { + const expected = [ + ["hours", "PT376436H", "-PT376435H"], + ["minutes", "PT376435H24M", "-PT376435H23M"], + ["seconds", "PT376435H23M9S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.148S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "ceil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'expand' rounding mode", () => { + const expected = [ + ["hours", "PT376436H", "-PT376436H"], + ["minutes", "PT376435H24M", "-PT376435H24M"], + ["seconds", "PT376435H23M9S", "-PT376435H23M9S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "expand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'floor' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376436H"], + ["minutes", "PT376435H23M", "-PT376435H24M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M9S"], + ["milliseconds", "PT376435H23M8.148S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "floor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfCeil' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfCeil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfEven' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfEven"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfExpand' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfExpand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfFloor' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfFloor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfTrunc' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfTrunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { largestUnit, smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.until.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.until.js index 64ea328ca9..6c7b824fcd 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.until.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.until.js @@ -18,3 +18,173 @@ describe("errors", () => { }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Instant"); }); }); + +describe("rounding modes", () => { + const earlier = new Temporal.Instant( + 217178610_123_456_789n /* 1976-11-18T15:23:30.123456789Z */ + ); + const later = new Temporal.Instant( + 1572345998_271_986_289n /* 2019-10-29T10:46:38.271986289Z */ + ); + const largestUnit = "hours"; + + test("'ceil' rounding mode", () => { + const expected = [ + ["hours", "PT376436H", "-PT376435H"], + ["minutes", "PT376435H24M", "-PT376435H23M"], + ["seconds", "PT376435H23M9S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.148S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "ceil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'expand' rounding mode", () => { + const expected = [ + ["hours", "PT376436H", "-PT376436H"], + ["minutes", "PT376435H24M", "-PT376435H24M"], + ["seconds", "PT376435H23M9S", "-PT376435H23M9S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "expand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'floor' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376436H"], + ["minutes", "PT376435H23M", "-PT376435H24M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M9S"], + ["milliseconds", "PT376435H23M8.148S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "floor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfCeil' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfCeil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfEven' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfEven"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfExpand' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.14853S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfExpand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfFloor' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.14853S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfFloor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfTrunc' rounding mode", () => { + const expected = [ + ["hours", "PT376435H", "-PT376435H"], + ["minutes", "PT376435H23M", "-PT376435H23M"], + ["seconds", "PT376435H23M8S", "-PT376435H23M8S"], + ["milliseconds", "PT376435H23M8.149S", "-PT376435H23M8.149S"], + ["microseconds", "PT376435H23M8.148529S", "-PT376435H23M8.148529S"], + ["nanoseconds", "PT376435H23M8.1485295S", "-PT376435H23M8.1485295S"], + ]; + + const roundingMode = "halfTrunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { largestUnit, smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { largestUnit, smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.since.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.since.js index 6f3801d4d8..4f5252e0b1 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.since.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.since.js @@ -113,3 +113,230 @@ describe("errors", () => { }).toThrowWithMessage(RangeError, "Cannot compare dates from two different time zones"); }); }); + +describe("rounding modes", () => { + const earlier = new Temporal.ZonedDateTime( + 1546935756_123_456_789n /* 2019-01-08T08:22:36.123456789+00:00 */, + "UTC" + ); + const later = new Temporal.ZonedDateTime( + 1631018380_987_654_289n /* 2021-09-07T12:39:40.987654289+00:00 */, + "UTC" + ); + + test("'ceil' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P2Y"], + ["months", "P32M", "-P31M"], + ["weeks", "P140W", "-P139W"], + ["days", "P974D", "-P973D"], + ["hours", "PT23357H", "-PT23356H"], + ["minutes", "PT23356H18M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M4S"], + ["milliseconds", "PT23356H17M4.865S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "ceil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'expand' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P140W", "-P140W"], + ["days", "P974D", "-P974D"], + ["hours", "PT23357H", "-PT23357H"], + ["minutes", "PT23356H18M", "-PT23356H18M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.865S", "-PT23356H17M4.865S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "expand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'floor' rounding mode", () => { + const expected = [ + ["years", "P2Y", "-P3Y"], + ["months", "P31M", "-P32M"], + ["weeks", "P139W", "-P140W"], + ["days", "P973D", "-P974D"], + ["hours", "PT23356H", "-PT23357H"], + ["minutes", "PT23356H17M", "-PT23356H18M"], + ["seconds", "PT23356H17M4S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.865S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "floor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'trunc' rounding mode", () => { + const expected = [ + ["years", "P2Y", "-P2Y"], + ["months", "P31M", "-P31M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M4S", "-PT23356H17M4S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "trunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfCeil' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfCeil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfEven' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfEven"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfTrunc' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfTrunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfExpand' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfExpand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfFloor' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfFloor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const sincePositive = later.since(earlier, { smallestUnit, roundingMode }); + expect(sincePositive.toString()).toBe(expectedPositive); + + const sinceNegative = earlier.since(later, { smallestUnit, roundingMode }); + expect(sinceNegative.toString()).toBe(expectedNegative); + }); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.until.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.until.js index 8e8fd0d364..d7c2658fab 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.until.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.until.js @@ -113,3 +113,230 @@ describe("errors", () => { }).toThrowWithMessage(RangeError, "Cannot compare dates from two different time zones"); }); }); + +describe("rounding modes", () => { + const earlier = new Temporal.ZonedDateTime( + 1546935756_123_456_789n /* 2019-01-08T08:22:36.123456789+00:00 */, + "UTC" + ); + const later = new Temporal.ZonedDateTime( + 1631018380_987_654_289n /* 2021-09-07T12:39:40.987654289+00:00 */, + "UTC" + ); + + test("'ceil' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P2Y"], + ["months", "P32M", "-P31M"], + ["weeks", "P140W", "-P139W"], + ["days", "P974D", "-P973D"], + ["hours", "PT23357H", "-PT23356H"], + ["minutes", "PT23356H18M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M4S"], + ["milliseconds", "PT23356H17M4.865S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "ceil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'expand' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P140W", "-P140W"], + ["days", "P974D", "-P974D"], + ["hours", "PT23357H", "-PT23357H"], + ["minutes", "PT23356H18M", "-PT23356H18M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.865S", "-PT23356H17M4.865S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "expand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'floor' rounding mode", () => { + const expected = [ + ["years", "P2Y", "-P3Y"], + ["months", "P31M", "-P32M"], + ["weeks", "P139W", "-P140W"], + ["days", "P973D", "-P974D"], + ["hours", "PT23356H", "-PT23357H"], + ["minutes", "PT23356H17M", "-PT23356H18M"], + ["seconds", "PT23356H17M4S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.865S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "floor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'trunc' rounding mode", () => { + const expected = [ + ["years", "P2Y", "-P2Y"], + ["months", "P31M", "-P31M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M4S", "-PT23356H17M4S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "trunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfCeil' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfCeil"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfEven' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfEven"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfTrunc' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864197S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfTrunc"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfExpand' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864198S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfExpand"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); + + test("'halfFloor' rounding mode", () => { + const expected = [ + ["years", "P3Y", "-P3Y"], + ["months", "P32M", "-P32M"], + ["weeks", "P139W", "-P139W"], + ["days", "P973D", "-P973D"], + ["hours", "PT23356H", "-PT23356H"], + ["minutes", "PT23356H17M", "-PT23356H17M"], + ["seconds", "PT23356H17M5S", "-PT23356H17M5S"], + ["milliseconds", "PT23356H17M4.864S", "-PT23356H17M4.864S"], + ["microseconds", "PT23356H17M4.864197S", "-PT23356H17M4.864198S"], + ["nanoseconds", "PT23356H17M4.8641975S", "-PT23356H17M4.8641975S"], + ]; + + const roundingMode = "halfFloor"; + expected.forEach(([smallestUnit, expectedPositive, expectedNegative]) => { + const untilPositive = earlier.until(later, { smallestUnit, roundingMode }); + expect(untilPositive.toString()).toBe(expectedPositive); + + const untilNegative = later.until(earlier, { smallestUnit, roundingMode }); + expect(untilNegative.toString()).toBe(expectedNegative); + }); + }); +});