From 1b71018adbe3d92c9ec9b4cb5329286072fa1567 Mon Sep 17 00:00:00 2001
From: Jesse Alama <jesse@igalia.com>
Date: Fri, 22 Apr 2022 13:45:13 +0200
Subject: [PATCH] Temporal: `PlainDateTime`: Port Demitasse tests for bounds

---
 .../prototype/toPlainDateTime/limits.js       | 39 +++++++++++
 .../Temporal/PlainDateTime/from/limits.js     | 70 +++++++++++++++++++
 .../Temporal/PlainDateTime/limits.js          | 19 +++++
 .../PlainDateTime/prototype/add/limits.js     | 25 +++++++
 .../PlainDateTime/prototype/round/limits.js   | 24 +++++++
 .../prototype/subtract/limits.js              | 24 +++++++
 .../prototype/toPlainDateTime/limits.js       | 39 +++++++++++
 .../prototype/getPlainDateTimeFor/limits.js   | 26 +++++++
 8 files changed, 266 insertions(+)
 create mode 100644 test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js
 create mode 100644 test/built-ins/Temporal/PlainDateTime/from/limits.js
 create mode 100644 test/built-ins/Temporal/PlainDateTime/limits.js
 create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/add/limits.js
 create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/round/limits.js
 create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js
 create mode 100644 test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js
 create mode 100644 test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js

diff --git a/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js b/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js
new file mode 100644
index 0000000000..e26ca7fba5
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDate/prototype/toPlainDateTime/limits.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindate.prototype.toplaindatetime
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const midnight = new Temporal.PlainTime(0, 0);
+const firstNs = new Temporal.PlainTime(0, 0, 0, 0, 0, 1);
+const lastNs = new Temporal.PlainTime(23, 59, 59, 999, 999, 999);
+const min = new Temporal.PlainDate(-271821, 4, 19);
+const max = new Temporal.PlainDate(275760, 9, 13);
+
+assert.throws(
+  RangeError,
+  () => min.toPlainDateTime(midnight),
+  "Cannot go below representable limit for PlainDateTime"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  max.toPlainDateTime(midnight),
+  275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0,
+  "Midnight on maximal representable PlainDate"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  min.toPlainDateTime(firstNs),
+  -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1,
+  "Computing the minimum (earliest) representable PlainDateTime"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  max.toPlainDateTime(lastNs),
+  275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999,
+  "Computing the maximum (latest) representable PlainDateTime"
+);
diff --git a/test/built-ins/Temporal/PlainDateTime/from/limits.js b/test/built-ins/Temporal/PlainDateTime/from/limits.js
new file mode 100644
index 0000000000..1d4f76eac2
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDateTime/from/limits.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime.from
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+["reject", "constrain"].forEach((overflow) => {
+  assert.throws(
+    RangeError,
+    () => Temporal.PlainDateTime.from({ year: -271821, month: 4, day: 19 }, { overflow }),
+    `negative out of bounds (plain object, overflow = ${overflow})`
+  );
+  assert.throws(
+    RangeError,
+    () => Temporal.PlainDateTime.from({ year: 275760, month: 9, day: 14 }, { overflow }),
+    `positive out of bounds (plain object, overflow = ${overflow})`
+  );
+});
+
+TemporalHelpers.assertPlainDateTime(
+  Temporal.PlainDateTime.from({ year: -271821, month: 4, day: 19, nanosecond: 1 }),
+  -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1,
+  "construct from property bag (negative boundary)"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  Temporal.PlainDateTime.from(
+    {
+      year: 275760,
+      month: 9,
+      day: 13,
+      hour: 23,
+      minute: 59,
+      second: 59,
+      millisecond: 999,
+      microsecond: 999,
+      nanosecond: 999
+    }
+  ),
+  275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999,
+  "construct from property bag (positive boundary)"
+);
+
+assert.throws(
+  RangeError,
+  () => Temporal.PlainDateTime.from("-271821-04-19T00:00"),
+  "out-of-bounds ISO string (negative case)"
+);
+
+assert.throws(
+  RangeError,
+  () => Temporal.PlainDateTime.from("+275760-09-14T00:00"),
+  "out-of-bounds ISO string (positive case)"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  Temporal.PlainDateTime.from("-271821-04-19T00:00:00.000000001"),
+  -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1,
+  "boundary ISO string (negative case)"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  Temporal.PlainDateTime.from("+275760-09-13T23:59:59.999999999"),
+  275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999,
+  "boundary ISO string (positive case)"
+);
diff --git a/test/built-ins/Temporal/PlainDateTime/limits.js b/test/built-ins/Temporal/PlainDateTime/limits.js
new file mode 100644
index 0000000000..c820fa7234
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDateTime/limits.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+---*/
+
+assert.throws(
+  RangeError,
+  () => new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 0),
+  "negative year out of bounds"
+);
+assert.throws(
+  RangeError,
+  () => new Temporal.PlainDateTime(275760, 9, 14, 0, 0, 0, 0, 0, 0),
+  "positive year out of bounds"
+);
diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/add/limits.js b/test/built-ins/Temporal/PlainDateTime/prototype/add/limits.js
new file mode 100644
index 0000000000..6110946bab
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDateTime/prototype/add/limits.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime.prototype.add
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+---*/
+
+const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1);
+const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999);
+
+["reject", "constrain"].forEach((overflow) => {
+  assert.throws(
+    RangeError,
+    () => max.add({ nanoseconds: 1 }, { overflow }),
+    `adding 1 nanosecond beyond maximum limit (overflow = ${overflow})`
+  );
+  assert.throws(
+    RangeError,
+    () => min.add({ nanoseconds: -1 }, { overflow }),
+    `adding -1 nanosecond beyond minimum limit (overflow = ${overflow})`
+  );
+
+});
diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/round/limits.js b/test/built-ins/Temporal/PlainDateTime/prototype/round/limits.js
new file mode 100644
index 0000000000..15db01f45a
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDateTime/prototype/round/limits.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime.prototype.round
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+---*/
+
+const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1);
+const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999);
+
+["day", "hour", "minute", "second", "millisecond", "microsecond"].forEach((smallestUnit) => {
+  assert.throws(
+    RangeError,
+    () => min.round({ smallestUnit, roundingMode: "floor" }),
+    `rounding beyond limit (unit = ${smallestUnit}, rounding mode = floor)`
+  );
+  assert.throws(
+    RangeError,
+    () => max.round({ smallestUnit, roundingMode: "ceil" }),
+    `rounding beyond limit (unit = ${smallestUnit}, rounding mode = ceil)`
+  );
+});
diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js
new file mode 100644
index 0000000000..038f97fe78
--- /dev/null
+++ b/test/built-ins/Temporal/PlainDateTime/prototype/subtract/limits.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime.prototype.subtract
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+---*/
+
+const min = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1);
+const max = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999);
+
+["reject", "constrain"].forEach((overflow) => {
+  assert.throws(
+    RangeError,
+    () => min.subtract({ nanoseconds: 1 }, { overflow }),
+    `subtracting 1 nanosecond beyond minimum limit (overflow = ${overflow})`
+  );
+  assert.throws(
+    RangeError,
+    () => max.subtract({ nanoseconds: -1 }, { overflow }),
+    `subtracting -1 nanosecond beyond maximum limit (overflow = ${overflow})`
+  );
+});
diff --git a/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js b/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js
new file mode 100644
index 0000000000..fcde863d64
--- /dev/null
+++ b/test/built-ins/Temporal/PlainTime/prototype/toPlainDateTime/limits.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaintime.prototype.toplaindatetime
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const midnight = new Temporal.PlainTime(0, 0);
+const firstNs = new Temporal.PlainTime(0, 0, 0, 0, 0, 1);
+const lastNs = new Temporal.PlainTime(23, 59, 59, 999, 999, 999);
+const min = new Temporal.PlainDate(-271821, 4, 19);
+const max = new Temporal.PlainDate(275760, 9, 13);
+
+assert.throws(
+  RangeError,
+  () => midnight.toPlainDateTime(min),
+  "Cannot go below representable limit"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  midnight.toPlainDateTime(max),
+  275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0,
+  "Midnight of maximum representable PlainDate"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  firstNs.toPlainDateTime(min),
+  -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1,
+  "Computing the minimum (earliest) representable PlainDateTime"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  lastNs.toPlainDateTime(max),
+  275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999,
+  "Computing the maximum (latest) representable PlainDateTime"
+);
diff --git a/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js b/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js
new file mode 100644
index 0000000000..24a970573d
--- /dev/null
+++ b/test/built-ins/Temporal/TimeZone/prototype/getPlainDateTimeFor/limits.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.plaindatetime.prototype.getplaindatetimefor
+description: Checking limits of representable PlainDateTime
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const min = new Temporal.Instant(-8_640_000_000_000_000_000_000n);
+const offsetMin = new Temporal.TimeZone("-23:59");
+const max = new Temporal.Instant(8_640_000_000_000_000_000_000n);
+const offsetMax = new Temporal.TimeZone("+23:59");
+
+TemporalHelpers.assertPlainDateTime(
+  offsetMin.getPlainDateTimeFor(min, "iso8601"),
+  -271821, 4, "M04", 19, 0, 1, 0, 0, 0, 0,
+  "converting from Instant (negative case)"
+);
+
+TemporalHelpers.assertPlainDateTime(
+  offsetMax.getPlainDateTimeFor(max, "iso8601"),
+  275760, 9, "M09", 13, 23, 59, 0, 0, 0, 0,
+  "converting from Instant (positive case)"
+);