Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal: Add tests for PlainTime string disambiguation with time zone #3641

Merged
merged 4 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions harness/temporalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1557,4 +1557,56 @@ var TemporalHelpers = {
},
};
},

/*
* An object containing further methods that return arrays of ISO strings, for
* testing parsers.
*/
ISO: {
/*
* PlainTime strings that may be mistaken for PlainMonthDay or
* PlainYearMonth strings, and so require a time designator.
*/
plainTimeStringsAmbiguous() {
const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
// Adding a calendar annotation to one of these strings must not cause
// disambiguation in favour of time.
const stringsWithCalendar = ambiguousStrings.map((s) => s + '[u-ca=iso8601]');
return ambiguousStrings.concat(stringsWithCalendar);
},

/*
* PlainTime strings that are of similar form to PlainMonthDay and
* PlainYearMonth strings, but are not ambiguous due to components that
* aren't valid as months or days.
*/
plainTimeStringsUnambiguous() {
return [
"2021-13", // 13 is not a month
"202113", // ditto
"2021-13[-13:00]", // ditto
"202113[-13:00]", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"0000-00[UTC]", // ditto
"000000[UTC]", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
"2021-12[-12:00]", // HHMM-UU is ambiguous with YYYY-MM, but TZ disambiguates
"202112[UTC]", // HHMMSS is ambiguous with YYYYMM, but TZ disambiguates
];
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
/*---
esid: sec-temporal.plaindate.prototype.toplaindatetime
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const instance = new Temporal.PlainDate(2000, 5, 2);

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`${string} is ambiguous and requires T prefix`
`'${arg}' is ambiguous and requires T prefix`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -32,22 +25,10 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
"space is not accepted as a substitute for T prefix"
`space is not accepted as a substitute for T prefix: '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => instance.toPlainDateTime(arg));
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach(
(arg) => instance.toPlainDateTime(arg));
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
/*---
esid: sec-temporal.plaindate.prototype.tozoneddatetime
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const instance = new Temporal.PlainDate(2000, 5, 2);

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }),
`${string} is ambiguous and requires T prefix`
`'${arg}' is ambiguous and requires T prefix`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -32,22 +25,10 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }),
"space is not accepted as a substitute for T prefix"
`space is not accepted as a substitute for T prefix: '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }));
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach(
(arg) => instance.toZonedDateTime({ plainTime: arg, timeZone: "UTC" }));
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
/*---
esid: sec-temporal.plaindatetime.prototype.withplaintime
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => instance.withPlainTime(arg),
`${string} is ambiguous and requires T prefix`
`'${arg}' is ambiguous and requires T prefix`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -32,22 +25,10 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => instance.withPlainTime(arg),
"space is not accepted as a substitute for T prefix"
`space is not accepted as a substitute for T prefix: '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => instance.withPlainTime(arg));
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach(
(arg) => instance.withPlainTime(arg));
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,23 @@
/*---
esid: sec-temporal.plaintime.compare
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const midnight = new Temporal.PlainTime();

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => Temporal.PlainTime.compare(arg, midnight),
`${string} is ambiguous and requires T prefix (first argument)`
`'${arg}' is ambiguous and requires T prefix (first argument)`
);
assert.throws(
RangeError,
() => Temporal.PlainTime.compare(midnight, arg),
`${string} is ambiguous and requires T prefix (second argument)`
`'${arg}' is ambiguous and requires T prefix (second argument)`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -38,30 +31,17 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => Temporal.PlainTime.compare(arg, midnight),
'space is not accepted as a substitute for T prefix (first argument)'
`space is not accepted as a substitute for T prefix (first argument): '${arg}'`
);
assert.throws(
RangeError,
() => Temporal.PlainTime.compare(midnight, arg),
'space is not accepted as a substitute for T prefix (second argument)'
`space is not accepted as a substitute for T prefix (second argument): '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => {
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach((arg) => {
Temporal.PlainTime.compare(arg, midnight);
Temporal.PlainTime.compare(midnight, arg);
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,16 @@
/*---
esid: sec-temporal.plaintime.from
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => Temporal.PlainTime.from(arg),
`${string} is ambiguous and requires T prefix`
`'${arg}' is ambiguous and requires T prefix`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -30,22 +23,10 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => Temporal.PlainTime.from(arg),
"space is not accepted as a substitute for T prefix"
`space is not accepted as a substitute for T prefix: '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => Temporal.PlainTime.from(arg));
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach(
(arg) => Temporal.PlainTime.from(arg));
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
/*---
esid: sec-temporal.plaintime.prototype.equals
description: ISO 8601 time designator "T" required in cases of ambiguity
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/

const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);

const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"202112", // ambiguity between YYYYMM and HHMMSS
];
ambiguousStrings.forEach((string) => {
TemporalHelpers.ISO.plainTimeStringsAmbiguous().forEach((string) => {
let arg = string;
assert.throws(
RangeError,
() => instance.equals(arg),
`${string} is ambiguous and requires T prefix`
`'${arg}' is ambiguous and requires T prefix`
);
// The same string with a T prefix should not throw:
arg = `T${string}`;
Expand All @@ -32,22 +25,10 @@ ambiguousStrings.forEach((string) => {
assert.throws(
RangeError,
() => instance.equals(arg),
"space is not accepted as a substitute for T prefix"
`space is not accepted as a substitute for T prefix: '${arg}'`
);
});

// None of these should throw without a T prefix, because they are unambiguously time strings:
const unambiguousStrings = [
"2021-13", // 13 is not a month
"202113", // ditto
"0000-00", // 0 is not a month
"000000", // ditto
"1314", // 13 is not a month
"13-14", // ditto
"1232", // 32 is not a day
"0230", // 30 is not a day in February
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
];
unambiguousStrings.forEach((arg) => instance.equals(arg));
TemporalHelpers.ISO.plainTimeStringsUnambiguous().forEach(
(arg) => instance.equals(arg));
Loading