Test removal of sub-minute time zone offsets in ISO strings

Tests for the normative changes made to Temporal in
https://github.com/tc39/proposal-temporal/pull/1871
This commit is contained in:
Philip Chimento 2021-10-14 11:52:06 -07:00 committed by Rick Waldron
parent 0dec11d949
commit 3dbf940c9b
24 changed files with 311 additions and 3 deletions

View File

@ -0,0 +1,13 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.compare
description: Throws if a ZonedDateTime-like relativeTo string has the wrong UTC offset
features: [Temporal]
---*/
const duration1 = new Temporal.Duration(0, 0, 0, 31);
const duration2 = new Temporal.Duration(0, 1);
const relativeTo = "2000-01-01T00:00+05:30[UTC]";
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, { relativeTo }));

View File

@ -0,0 +1,21 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.compare
description: relativeTo string accepts an inexact UTC offset rounded to hours and minutes
features: [Temporal]
---*/
const duration1 = new Temporal.Duration(0, 0, 0, 31);
const duration2 = new Temporal.Duration(0, 1);
let relativeTo = "2000-01-01T00:00+00:45[+00:44:30.123456789]";
assert.sameValue(Temporal.Duration.compare(duration1, duration2, { relativeTo }), 0, "rounded HH:MM is accepted in string");
relativeTo = "2000-01-01T00:00+00:44:30[+00:44:30.123456789]";
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, { relativeTo }), "no other rounding is accepted for offset");
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
relativeTo = { year: 2000, month: 1, day: 1, offset: "+00:45", timeZone };
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, { relativeTo }), "rounded HH:MM not accepted as offset in property bag");

View File

@ -0,0 +1,12 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.add
description: Throws if a ZonedDateTime-like relativeTo string has the wrong UTC offset
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 1);
const relativeTo = "2000-01-01T00:00+05:30[UTC]";
assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }));

View File

@ -0,0 +1,22 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.add
description: relativeTo string accepts an inexact UTC offset rounded to hours and minutes
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 1);
let relativeTo = "2000-01-01T00:00+00:45[+00:44:30.123456789]";
const result = instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo });
TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "rounded HH:MM is accepted in string");
relativeTo = "2000-01-01T00:00+00:44:30[+00:44:30.123456789]";
assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), "no other rounding is accepted for offset");
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
relativeTo = { year: 2000, month: 1, day: 1, offset: "+00:45", timeZone };
assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), "rounded HH:MM not accepted as offset in property bag");

View File

@ -0,0 +1,12 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.round
description: Throws if a ZonedDateTime-like relativeTo string has the wrong UTC offset
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
const relativeTo = "2000-01-01T00:00+05:30[UTC]";
assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }));

View File

@ -0,0 +1,22 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.round
description: relativeTo string accepts an inexact UTC offset rounded to hours and minutes
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
let relativeTo = "2000-01-01T00:00+00:45[+00:44:30.123456789]";
const result = instance.round({ largestUnit: "years", relativeTo });
TemporalHelpers.assertDuration(result, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, "rounded HH:MM is accepted in string");
relativeTo = "2000-01-01T00:00+00:44:30[+00:44:30.123456789]";
assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), "no other rounding is accepted for offset");
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
relativeTo = { year: 2000, month: 1, day: 1, offset: "+00:45", timeZone };
assert.throws(RangeError, () => instance.round({ largestUnit: "years", relativeTo }), "rounded HH:MM not accepted as offset in property bag");

View File

@ -0,0 +1,12 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.subtract
description: Throws if a ZonedDateTime-like relativeTo string has the wrong UTC offset
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 1);
const relativeTo = "2000-01-01T00:00+05:30[UTC]";
assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }));

View File

@ -0,0 +1,22 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.subtract
description: relativeTo string accepts an inexact UTC offset rounded to hours and minutes
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 1);
let relativeTo = "2000-01-01T00:00+00:45[+00:44:30.123456789]";
const result = instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo });
TemporalHelpers.assertDuration(result, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "rounded HH:MM is accepted in string");
relativeTo = "2000-01-01T00:00+00:44:30[+00:44:30.123456789]";
assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), "no other rounding is accepted for offset");
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
relativeTo = { year: 2000, month: 1, day: 1, offset: "+00:45", timeZone };
assert.throws(RangeError, () => instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo }), "rounded HH:MM not accepted as offset in property bag");

View File

@ -0,0 +1,12 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.total
description: Throws if a ZonedDateTime-like relativeTo string has the wrong UTC offset
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
const relativeTo = "2000-01-01T00:00+05:30[UTC]";
assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }));

View File

@ -0,0 +1,21 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.duration.prototype.total
description: relativeTo string accepts an inexact UTC offset rounded to hours and minutes
features: [Temporal]
---*/
const instance = new Temporal.Duration(1, 0, 0, 0, 24);
let relativeTo = "2000-01-01T00:00+00:45[+00:44:30.123456789]";
const result = instance.total({ unit: "days", relativeTo });
assert.sameValue(result, 367, "rounded HH:MM is accepted in string");
relativeTo = "2000-01-01T00:00+00:44:30[+00:44:30.123456789]";
assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), "no other rounding is accepted for offset");
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
relativeTo = { year: 2000, month: 1, day: 1, offset: "+00:45", timeZone };
assert.throws(RangeError, () => instance.total({ unit: "days", relativeTo }), "rounded HH:MM not accepted as offset in property bag");

View File

@ -17,3 +17,5 @@ function test(timeZoneIdentifier, expected, description) {
test("UTC", "1970-01-01T00:00:00+00:00", "offset of UTC is +00:00");
test("+01:00", "1970-01-01T01:00:00+01:00", "positive offset");
test("-05:00", "1969-12-31T19:00:00-05:00", "negative offset");
test("+00:44:59.123456789", "1970-01-01T00:44:59.123456789+00:45", "sub-minute offset");
test("-00:00:10.987654321", "1969-12-31T23:59:49.012345679+00:00", "sub-minute offset that rounds to zero");

View File

@ -49,5 +49,5 @@ Object.defineProperty(Temporal.TimeZone, "from", {
},
});
assert.sameValue(instant.toString({ timeZone }), "1975-02-02T12:00:00.987654321-02:25:35.135801679");
assert.sameValue(instant.toString({ timeZone }), "1975-02-02T12:00:00.987654321-02:26");
assert.compareArray(actual, expected);

View File

@ -17,3 +17,4 @@ function test(timeZoneIdentifier, expectedOffsetString, description) {
test("UTC", "+00:00", "offset of UTC is +00:00");
test("+01:00", "+01:00", "positive offset");
test("-05:00", "-05:00", "negative offset");
test("+00:44:59.123456789", "+00:44:59.123456789", "sub-minute offset is not rounded");

View File

@ -0,0 +1,43 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.from
description: Fuzzy matching behaviour with UTC offsets in ISO 8601 strings and offset option
includes: [temporalHelpers.js]
features: [Temporal]
---*/
["use", "ignore", "prefer", "reject"].forEach((offset) => {
const result = Temporal.ZonedDateTime.from("1970-01-01T12:00-00:44:30.123456789[-00:44:30.123456789]", { offset });
assert.sameValue(result.epochNanoseconds, 45870_123_456_789n, `accepts the exact offset string (offset=${offset})`);
assert.sameValue(result.offset, "-00:44:30.123456789", "offset property is correct");
});
assert.throws(RangeError, () => Temporal.ZonedDateTime.from("1970-01-01T00:00-00:44:30[-00:44:30.123456789]", { offset: "reject" }), "offset=reject does not accept any other rounding than minutes");
const str = "1970-01-01T12:00-00:45[-00:44:30.123456789]";
["ignore", "prefer", "reject"].forEach((offset) => {
const result = Temporal.ZonedDateTime.from(str, { offset });
assert.sameValue(result.epochNanoseconds, 45870_123_456_789n, `accepts the offset string rounded to minutes (offset=${offset})`);
assert.sameValue(result.offset, "-00:44:30.123456789", "offset property is still the full precision");
TemporalHelpers.assertPlainDateTime(result.toPlainDateTime(), 1970, 1, "M01", 1, 12, 0, 0, 0, 0, 0, "wall time is preserved");
});
const result = Temporal.ZonedDateTime.from(str, { offset: "use" });
assert.sameValue(result.epochNanoseconds, 45900_000_000_000n, "prioritizes the offset string with HH:MM precision when offset=use");
assert.sameValue(result.offset, "-00:44:30.123456789", "offset property is still the full precision");
TemporalHelpers.assertPlainDateTime(result.toPlainDateTime(), 1970, 1, "M01", 1, 12, 0, 29, 876, 543, 211, "wall time is shifted by the difference between exact and rounded offset");
const properties = { year: 1970, month: 1, day: 1, hour: 12, offset: "-00:45", timeZone: "-00:44:30.123456789" };
["ignore", "prefer"].forEach((offset) => {
const result = Temporal.ZonedDateTime.from(properties, { offset });
assert.sameValue(result.epochNanoseconds, 45870_123_456_789n, `no fuzzy matching is done on offset in property bag (offset=${offset})`);
});
const result2 = Temporal.ZonedDateTime.from(properties, { offset: "use" });
assert.sameValue(result2.epochNanoseconds, 45900_000_000_000n, "no fuzzy matching is done on offset in property bag (offset=use)");
assert.throws(RangeError, () => Temporal.ZonedDateTime.from(properties, { offset: "reject" }), "no fuzzy matching is done on offset in property bag (offset=reject)");

View File

@ -0,0 +1,19 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.equals
description: Fuzzy matching behaviour for UTC offset in ISO 8601 string
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
const result = instance.equals("1970-01-01T00:44:30.123456789+00:45[+00:44:30.123456789]");
assert.sameValue(result, true, "UTC offset rounded to minutes is accepted");
assert.throws(RangeError, () => instance.equals("1970-01-01T00:44:30.123456789+00:44:30[+00:44:30.123456789]"), "no other rounding than minutes is accepted");
const properties = { offset: "+00:45", year: 1970, month: 1, day: 1, minute: 44, second: 30, millisecond: 123, microsecond: 456, nanosecond: 123, timeZone };
assert.throws(RangeError, () => instance.equals(properties), "no fuzzy matching is done on offset in property bag");

View File

@ -17,3 +17,4 @@ function test(timeZoneIdentifier, expectedOffsetString, description) {
test("UTC", "+00:00", "offset of UTC is +00:00");
test("+01:00", "+01:00", "positive offset");
test("-05:00", "-05:00", "negative offset");
test("+00:44:59.123456789", "+00:44:59.123456789", "sub-minute offset is not rounded");

View File

@ -16,3 +16,4 @@ function test(timeZoneIdentifier, expectedOffsetString, description) {
test("UTC", "+00:00", "offset of UTC is +00:00");
test("+01:00", "+01:00", "positive offset");
test("-05:00", "-05:00", "negative offset");
test("+00:44:59.123456789", "+00:44:59.123456789", "sub-minute offset is not rounded");

View File

@ -0,0 +1,20 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.since
description: Fuzzy matching behaviour for UTC offset in ISO 8601 string
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
const result = instance.since("1970-01-01T00:44:30.123456789+00:45[+00:44:30.123456789]");
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "UTC offset rounded to minutes is accepted");
assert.throws(RangeError, () => instance.since("1970-01-01T00:44:30.123456789+00:44:30[+00:44:30.123456789]"), "no other rounding than minutes is accepted");
const properties = { offset: "+00:45", year: 1970, month: 1, day: 1, minute: 44, second: 30, millisecond: 123, microsecond: 456, nanosecond: 123, timeZone };
assert.throws(RangeError, () => instance.since(properties), "no fuzzy matching is done on offset in property bag");

View File

@ -37,4 +37,4 @@ const datetime = new Temporal.ZonedDateTime(1001n, tz);
const jsonString = datetime.toJSON();
assert.sameValue(jsonString, "1970-01-01T00:00:00.000000999-00:00:00.000000002[-00:00:00.000000002]");
assert.sameValue(jsonString, "1970-01-01T00:00:00.000000999+00:00[-00:00:00.000000002]");

View File

@ -16,3 +16,5 @@ function test(timeZoneIdentifier, expected, description) {
test("UTC", "1970-01-01T00:00:00+00:00[UTC]", "offset of UTC is +00:00");
test("+01:00", "1970-01-01T01:00:00+01:00[+01:00]", "positive offset");
test("-05:00", "1969-12-31T19:00:00-05:00[-05:00]", "negative offset");
test("+00:44:59.123456789", "1970-01-01T00:44:59.123456789+00:45[+00:44:59.123456789]", "sub-minute offset");
test("-00:00:10.987654321", "1969-12-31T23:59:49.012345679+00:00[-00:00:10.987654321]", "sub-minute offset that rounds to zero");

View File

@ -37,4 +37,4 @@ const datetime = new Temporal.ZonedDateTime(1001n, tz);
const isoString = datetime.toString();
assert.sameValue(isoString, "1970-01-01T00:00:00.000000999-00:00:00.000000002[-00:00:00.000000002]");
assert.sameValue(isoString, "1970-01-01T00:00:00.000000999+00:00[-00:00:00.000000002]");

View File

@ -16,3 +16,5 @@ function test(timeZoneIdentifier, expected, description) {
test("UTC", "1970-01-01T00:00:00+00:00[UTC]", "offset of UTC is +00:00");
test("+01:00", "1970-01-01T01:00:00+01:00[+01:00]", "positive offset");
test("-05:00", "1969-12-31T19:00:00-05:00[-05:00]", "negative offset");
test("+00:44:59.123456789", "1970-01-01T00:44:59.123456789+00:45[+00:44:59.123456789]", "sub-minute offset");
test("-00:00:10.987654321", "1969-12-31T23:59:49.012345679+00:00[-00:00:10.987654321]", "sub-minute offset that rounds to zero");

View File

@ -0,0 +1,20 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.until
description: Fuzzy matching behaviour for UTC offset in ISO 8601 string
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("+00:44:30.123456789");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
const result = instance.until("1970-01-01T00:44:30.123456789+00:45[+00:44:30.123456789]");
TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "UTC offset rounded to minutes is accepted");
assert.throws(RangeError, () => instance.until("1970-01-01T00:44:30.123456789+00:44:30[+00:44:30.123456789]"), "no other rounding than minutes is accepted");
const properties = { offset: "+00:45", year: 1970, month: 1, day: 1, minute: 44, second: 30, millisecond: 123, microsecond: 456, nanosecond: 123, timeZone };
assert.throws(RangeError, () => instance.until(properties), "no fuzzy matching is done on offset in property bag");

View File

@ -0,0 +1,28 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.with
description: Fuzzy matching behaviour with UTC offsets in ISO 8601 strings and offset option
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("-00:44:30.123456789");
const instance = Temporal.ZonedDateTime.from({ year: 1970, month: 1, day: 1, hour: 12, timeZone });
assert.sameValue(instance.offset, "-00:44:30.123456789", "original offset");
const properties = { day: 2, offset: "-00:45" };
["ignore", "prefer"].forEach((offset) => {
const result = instance.with(properties, { offset });
assert.sameValue(result.epochNanoseconds, 132270_123_456_789n, `ignores new offset (offset=${offset})`);
assert.sameValue(result.offset, instance.offset, "offset property is unchanged");
TemporalHelpers.assertPlainDateTime(result.toPlainDateTime(), 1970, 1, "M01", 2, 12, 0, 0, 0, 0, 0, "wall time is not shifted");
});
const result = instance.with(properties, { offset: "use" });
assert.sameValue(result.epochNanoseconds, 132300_000_000_000n, "accepts HH:MM rounded offset (offset=use)");
assert.sameValue(result.offset, instance.offset, "offset property is unchanged");
TemporalHelpers.assertPlainDateTime(result.toPlainDateTime(), 1970, 1, "M01", 2, 12, 0, 29, 876, 543, 211, "wall time is shifted by the difference between exact and rounded offset");
assert.throws(RangeError, () => instance.with(properties, { offset: "reject" }), "no fuzzy matching is done in with()");