Skip to content

Commit 65c59f1

Browse files
ptomatoMs2ger
authored andcommitted
Thorough tests for roundtripping Temporal objects
Adds a thorough test file for each type, testing that it can be constructed using its from() static method, from variations on ISO strings and property bags.
1 parent a7616ea commit 65c59f1

File tree

9 files changed

+404
-1
lines changed

9 files changed

+404
-1
lines changed

polyfill/test/thorough/all.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,33 @@ for test in \
1919
calendarisolike \
2020
dateaddition \
2121
datedifference \
22+
dateroundtrip \
2223
datetimeaddition \
2324
datetimedifference \
2425
datetimerounding \
26+
datetimeroundtrip \
2527
durationaddition \
28+
durationroundtrip \
2629
durationtotal \
2730
instantaddition \
2831
instantdifference \
2932
instantrounding \
33+
instantroundtrip \
3034
monthdayrefyear \
35+
monthdayroundtrip \
3136
startofday \
3237
timeaddition \
3338
timedifference \
3439
timerounding \
40+
timeroundtrip \
3541
yearcycle \
3642
yearmonthaddition \
3743
yearmonthdifference \
44+
yearmonthroundtrip \
3845
zonedaddition \
3946
zoneddifference \
40-
zonedrounding
47+
zonedrounding \
48+
zonedroundtrip
4149
do
4250
echo "== Running $test.mjs =="
4351
$interpreter "$test.mjs" || there_were_errors=1
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { assertTemporalEqual, getProgressBar, makeDateCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const opts = { overflow: 'reject' };
4+
const interestingDates = makeDateCases();
5+
const total = interestingDates.length;
6+
7+
await time(async (start) => {
8+
const progress = getProgressBar(start, total);
9+
10+
for (const [date, dateStr] of interestingDates) {
11+
progress.tick(1, { test: dateStr });
12+
13+
const { year, month, monthCode, day } = date;
14+
15+
const propertyBagMonth = { year, month, day };
16+
assertTemporalEqual(T.PlainDate.from(propertyBagMonth, opts), date, 'from property bag with month');
17+
18+
const propertyBagMonthCode = { year, monthCode, day };
19+
assertTemporalEqual(T.PlainDate.from(propertyBagMonthCode, opts), date, 'from property bag with monthCode');
20+
21+
const propertyBagAll = { year, month, monthCode, day };
22+
assertTemporalEqual(T.PlainDate.from(propertyBagAll, opts), date, 'from property bag with month and monthCode');
23+
24+
assertTemporalEqual(T.PlainDate.from(dateStr), date, 'from ISO string');
25+
26+
const stringCalendar = date.toString({ calendarName: 'always' });
27+
assertTemporalEqual(T.PlainDate.from(stringCalendar), date, 'from ISO string with calendar');
28+
29+
const stringTime = date.toPlainDateTime({ hour: 12 }).toString();
30+
assertTemporalEqual(T.PlainDate.from(stringTime), date, 'from ISO string with time');
31+
32+
const yPart = `${year < 0 ? '-' : '+'}${String(Math.abs(year)).padStart(6, '0')}`;
33+
const monPart = String(month).padStart(2, '0');
34+
const dPart = String(day).padStart(2, '0');
35+
const weirdString = `${yPart}${monPart}${dPart} 123456,7+1234`;
36+
assertTemporalEqual(T.PlainDate.from(weirdString), date, 'from ISO string with weird but allowed formatting');
37+
}
38+
39+
return total;
40+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { assertTemporalEqual, getProgressBar, makeDateTimeCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const opts = { overflow: 'reject' };
4+
const interestingDateTimes = makeDateTimeCases();
5+
const total = interestingDateTimes.length;
6+
7+
await time(async (start) => {
8+
const progress = getProgressBar(start, total);
9+
10+
for (const [dateTime, dateTimeStr] of interestingDateTimes) {
11+
progress.tick(1, { test: dateTimeStr });
12+
13+
const { year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond } = dateTime;
14+
15+
const propertyBagMonth = { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond };
16+
assertTemporalEqual(T.PlainDateTime.from(propertyBagMonth, opts), dateTime, 'from property bag with month');
17+
18+
const propertyBagMonthCode = { year, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond };
19+
assertTemporalEqual(T.PlainDateTime.from(propertyBagMonthCode, opts), dateTime, 'from property bag with monthCode');
20+
21+
const propertyBagAll = { year, month, monthCode, day, hour, minute, second, millisecond, microsecond, nanosecond };
22+
assertTemporalEqual(
23+
T.PlainDateTime.from(propertyBagAll, opts),
24+
dateTime,
25+
'from property bag with month and monthCode'
26+
);
27+
28+
assertTemporalEqual(T.PlainDateTime.from(dateTimeStr), dateTime, 'from ISO string');
29+
30+
const stringCalendar = dateTime.toString({ calendarName: 'always' });
31+
assertTemporalEqual(T.PlainDateTime.from(stringCalendar), dateTime, 'from ISO string with calendar');
32+
33+
const yPart = `${year < 0 ? '-' : '+'}${String(Math.abs(year)).padStart(6, '0')}`;
34+
const monPart = String(month).padStart(2, '0');
35+
const dPart = String(day).padStart(2, '0');
36+
const hPart = String(hour).padStart(2, '0');
37+
const minPart = String(minute).padStart(2, '0');
38+
const sPart = String(second).padStart(2, '0');
39+
const msPart = String(millisecond).padStart(3, '0');
40+
const µsPart = String(microsecond).padStart(3, '0');
41+
const nsPart = String(nanosecond).padStart(3, '0');
42+
const weirdString = `${yPart}${monPart}${dPart} ${hPart}${minPart}${sPart},${msPart}${µsPart}${nsPart}+1234`;
43+
assertTemporalEqual(
44+
T.PlainDateTime.from(weirdString),
45+
dateTime,
46+
'from ISO string with weird but allowed formatting'
47+
);
48+
}
49+
50+
return total;
51+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { assertDurationsEqual, getProgressBar, makeDurationCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const interestingCases = makeDurationCases().concat(makeDurationCases().map(([d, str]) => [d.negated(), `-${str}`]));
4+
const total = interestingCases.length;
5+
6+
await time(async (start) => {
7+
const progress = getProgressBar(start, total);
8+
9+
for (const [duration, durationStr] of interestingCases) {
10+
progress.tick(1, { test: durationStr });
11+
12+
const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration;
13+
14+
const propertyBag = {
15+
years,
16+
months,
17+
weeks,
18+
days,
19+
hours,
20+
minutes,
21+
seconds,
22+
milliseconds,
23+
microseconds,
24+
nanoseconds
25+
};
26+
assertDurationsEqual(T.Duration.from(propertyBag), duration, 'from property bag');
27+
28+
// Durations where the subsecond units overflow don't roundtrip from a string
29+
if (Math.abs(milliseconds) > 999 || Math.abs(microseconds) > 999 || Math.abs(nanoseconds) > 999) continue;
30+
31+
const isoString = duration.toString();
32+
assertDurationsEqual(T.Duration.from(isoString), duration, 'from ISO string');
33+
34+
const sign = duration.sign < 0 ? '-' : '+';
35+
const f = Math.abs;
36+
const fracPart = String(f(milliseconds) * 1000000 + f(microseconds) * 1000 + f(nanoseconds)).padStart(9, '0');
37+
const weirdString = `${sign}p${f(years)}y${f(months)}m${f(weeks)}w${f(days)}dt${f(hours)}h${f(minutes)}m${f(
38+
seconds
39+
)},${fracPart}s`;
40+
assertDurationsEqual(T.Duration.from(weirdString), duration, 'from ISO string with weird but allowed formatting');
41+
}
42+
43+
return total;
44+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { assertTemporalEqual, getProgressBar, makeInstantCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const interestingInstants = makeInstantCases();
4+
const total = interestingInstants.length;
5+
6+
await time(async (start) => {
7+
const progress = getProgressBar(start, total);
8+
9+
for (const [instant, instantStr] of interestingInstants) {
10+
progress.tick(1, { test: instantStr });
11+
12+
assertTemporalEqual(T.Instant.from(instantStr), instant, 'from ISO string');
13+
14+
const stringTimeZone = instant.toString({ fractionalSecondDigits: 9, timeZone: 'UTC' });
15+
assertTemporalEqual(T.Instant.from(stringTimeZone), instant, 'from ISO string with full digits and time zone');
16+
17+
const weirdString =
18+
stringTimeZone[0] + stringTimeZone.slice(1).replace('T', ' ').replace('.', ',').replaceAll(/-:/g, '');
19+
assertTemporalEqual(T.Instant.from(weirdString), instant, 'from ISO string with weird but allowed formatting');
20+
}
21+
22+
return total;
23+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { assertTemporalEqual, getProgressBar, temporalImpl as T, time } from './support.mjs';
2+
3+
const opts = { overflow: 'reject' };
4+
const daysInMonth = [undefined, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
5+
const interestingMonthDays = [];
6+
for (let month = 1; month < 13; month++) {
7+
for (let day = 1; day < daysInMonth[month] + 1; day++) {
8+
const md = T.PlainMonthDay.from({ year: 1972, month, day });
9+
interestingMonthDays.push([md, md.toString()]);
10+
}
11+
}
12+
const total = interestingMonthDays.length;
13+
14+
await time(async (start) => {
15+
const progress = getProgressBar(start, total);
16+
17+
for (const [md, mdStr] of interestingMonthDays) {
18+
progress.tick(1, { test: mdStr });
19+
20+
const { monthCode, day } = md;
21+
const year = 1972;
22+
const month = +monthCode.slice(1);
23+
24+
const propertyBagYearMonth = { year, month, day };
25+
assertTemporalEqual(T.PlainMonthDay.from(propertyBagYearMonth, opts), md, 'from property bag with year and month');
26+
27+
const propertyBagMonthCode = { monthCode, day };
28+
assertTemporalEqual(T.PlainMonthDay.from(propertyBagMonthCode, opts), md, 'from property bag with monthCode');
29+
30+
const propertyBagYearMonthCode = { year, monthCode, day };
31+
assertTemporalEqual(
32+
T.PlainMonthDay.from(propertyBagYearMonthCode, opts),
33+
md,
34+
'from property bag with year and monthCode'
35+
);
36+
37+
const propertyBagAll = { year, month, monthCode, day };
38+
assertTemporalEqual(T.PlainMonthDay.from(propertyBagAll, opts), md, 'from property bag with month and monthCode');
39+
40+
assertTemporalEqual(T.PlainMonthDay.from(mdStr), md, 'from ISO string');
41+
42+
const stringCalendar = md.toString({ calendarName: 'always' });
43+
assertTemporalEqual(T.PlainMonthDay.from(stringCalendar), md, 'from ISO string with calendar');
44+
45+
const stringTime = md.toPlainDate({ year: 1972 }).toPlainDateTime({ hour: 12 }).toString();
46+
assertTemporalEqual(T.PlainMonthDay.from(stringTime), md, 'from ISO string with time');
47+
48+
const monPart = monthCode.slice(1);
49+
const dPart = String(day).padStart(2, '0');
50+
const weirdString = `+222220${monPart}${dPart} 123456,7+1234`;
51+
assertTemporalEqual(T.PlainMonthDay.from(weirdString), md, 'from ISO string with weird but allowed formatting');
52+
53+
const dashString = `--${monPart}-${dPart}`;
54+
assertTemporalEqual(T.PlainMonthDay.from(dashString), md, 'from ISO string with leading double dash');
55+
}
56+
57+
return total;
58+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { assertTemporalEqual, getProgressBar, makeTimeCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const opts = { overflow: 'reject' };
4+
const interestingTimes = makeTimeCases();
5+
const total = interestingTimes.length;
6+
7+
await time(async (start) => {
8+
const progress = getProgressBar(start, total);
9+
10+
for (const [time, timeStr] of interestingTimes) {
11+
progress.tick(1, { test: timeStr });
12+
13+
const { hour, minute, second, millisecond, microsecond, nanosecond } = time;
14+
15+
const propertyBag = { hour, minute, second, millisecond, microsecond, nanosecond };
16+
assertTemporalEqual(T.PlainTime.from(propertyBag, opts), time, 'from property bag');
17+
18+
assertTemporalEqual(T.PlainTime.from(timeStr), time, 'from ISO string');
19+
20+
const stringCalendar = time.toString({ calendarName: 'always' });
21+
assertTemporalEqual(T.PlainTime.from(stringCalendar), time, 'from ISO string with calendar');
22+
23+
const hPart = String(hour).padStart(2, '0');
24+
const minPart = String(minute).padStart(2, '0');
25+
const sPart = String(second).padStart(2, '0');
26+
const msPart = String(millisecond).padStart(3, '0');
27+
const µsPart = String(microsecond).padStart(3, '0');
28+
const nsPart = String(nanosecond).padStart(3, '0');
29+
const weirdString = `t${hPart}${minPart}${sPart},${msPart}${µsPart}${nsPart}+1234`;
30+
assertTemporalEqual(T.PlainTime.from(weirdString), time, 'from ISO string with weird but allowed formatting');
31+
}
32+
33+
return total;
34+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { assertTemporalEqual, getProgressBar, makeYearMonthCases, temporalImpl as T, time } from './support.mjs';
2+
3+
const opts = { overflow: 'reject' };
4+
const interestingYearMonths = makeYearMonthCases();
5+
const total = interestingYearMonths.length;
6+
7+
await time(async (start) => {
8+
const progress = getProgressBar(start, total);
9+
10+
for (const [ym, ymStr] of interestingYearMonths) {
11+
progress.tick(1, { test: ymStr });
12+
13+
const { year, month, monthCode } = ym;
14+
15+
const propertyBagMonth = { year, month };
16+
assertTemporalEqual(T.PlainYearMonth.from(propertyBagMonth, opts), ym, 'from property bag with month');
17+
18+
const propertyBagMonthCode = { year, monthCode };
19+
assertTemporalEqual(T.PlainYearMonth.from(propertyBagMonthCode, opts), ym, 'from property bag with monthCode');
20+
21+
const propertyBagAll = { year, month, monthCode };
22+
assertTemporalEqual(T.PlainYearMonth.from(propertyBagAll, opts), ym, 'from property bag with month and monthCode');
23+
24+
assertTemporalEqual(T.PlainYearMonth.from(ymStr), ym, 'from ISO string');
25+
26+
const stringCalendar = ym.toString({ calendarName: 'always' });
27+
assertTemporalEqual(T.PlainYearMonth.from(stringCalendar), ym, 'from ISO string with calendar');
28+
29+
const stringTime = ym.toPlainDate({ day: 2 }).toPlainDateTime({ hour: 12 }).toString();
30+
assertTemporalEqual(T.PlainYearMonth.from(stringTime), ym, 'from ISO string with day and time');
31+
32+
const yPart = `${year < 0 ? '-' : '+'}${String(Math.abs(year)).padStart(6, '0')}`;
33+
const monPart = String(month).padStart(2, '0');
34+
const weirdString = `${yPart}${monPart}14 123456,7+1234`;
35+
assertTemporalEqual(T.PlainYearMonth.from(weirdString), ym, 'from ISO string with weird but allowed formatting');
36+
}
37+
38+
return total;
39+
});

0 commit comments

Comments
 (0)