Skip to content

Commit f885885

Browse files
committed
Polyfill: Update to reflect spec in ValidateTemporalUnitValue
See PRs #3135 and #3139.
1 parent 9e49154 commit f885885

File tree

6 files changed

+51
-39
lines changed

6 files changed

+51
-39
lines changed

polyfill/lib/duration.mjs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,13 @@ export class Duration {
193193
roundTo = ES.GetOptionsObject(roundTo);
194194
}
195195

196-
let largestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'largestUnit', 'datetime', undefined, ['auto']);
196+
let largestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'largestUnit');
197+
ES.ValidateTemporalUnitValue(largestUnit, 'datetime', ['auto']);
197198
let { plainRelativeTo, zonedRelativeTo } = ES.GetTemporalRelativeToOption(roundTo);
198199
const roundingIncrement = ES.GetRoundingIncrementOption(roundTo);
199200
const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand');
200-
let smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'datetime', undefined);
201+
let smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit');
202+
ES.ValidateTemporalUnitValue(smallestUnit, 'datetime');
201203

202204
let smallestUnitPresent = true;
203205
if (!smallestUnit) {
@@ -311,7 +313,8 @@ export class Duration {
311313
totalOf = ES.GetOptionsObject(totalOf);
312314
}
313315
let { plainRelativeTo, zonedRelativeTo } = ES.GetTemporalRelativeToOption(totalOf);
314-
const unit = ES.GetTemporalUnitValuedOption(totalOf, 'unit', 'datetime', ES.REQUIRED);
316+
const unit = ES.GetTemporalUnitValuedOption(totalOf, 'unit', ES.REQUIRED);
317+
ES.ValidateTemporalUnitValue(unit, 'datetime');
315318

316319
if (zonedRelativeTo) {
317320
const duration = ES.ToInternalDurationRecord(this);
@@ -353,7 +356,8 @@ export class Duration {
353356
const resolvedOptions = ES.GetOptionsObject(options);
354357
const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions);
355358
const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc');
356-
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined);
359+
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit');
360+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
357361
if (smallestUnit === 'hour' || smallestUnit === 'minute') {
358362
throw new RangeErrorCtor('smallestUnit must be a time unit other than "hours" or "minutes"');
359363
}

polyfill/lib/ecmascript.mjs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ const TEMPORAL_UNITS = [
317317
];
318318
const SINGULAR_FOR = new MapCtor(TEMPORAL_UNITS);
319319
// Iterable destructuring is acceptable in this first-run code.
320-
const PLURAL_FOR = new MapCtor(Call(ArrayPrototypeMap, TEMPORAL_UNITS, [([p, s]) => [s, p]]));
321320
const UNITS_DESCENDING = Call(ArrayPrototypeMap, TEMPORAL_UNITS, [([, s]) => s]);
322321
const NS_PER_TIME_UNIT = new MapCtor(
323322
Call(ArrayPrototypeFlatMap, TEMPORAL_UNITS, [([, s, , l]) => (l ? [[s, l]] : [])])
@@ -918,38 +917,35 @@ export function ToSecondsStringPrecisionRecord(smallestUnit, precision) {
918917

919918
export const REQUIRED = SymbolCtor('~required~');
920919

921-
export function GetTemporalUnitValuedOption(options, key, unitGroup, requiredOrDefault, extraValues = []) {
922-
const allowedSingular = [];
920+
export function GetTemporalUnitValuedOption(options, key, requiredOrUndefined = undefined) {
921+
const allowedStrings = [];
923922
for (let index = 0; index < TEMPORAL_UNITS.length; index++) {
924923
const unitInfo = TEMPORAL_UNITS[index];
924+
const plural = unitInfo[0];
925925
const singular = unitInfo[1];
926-
const category = unitInfo[2];
927-
if (unitGroup === 'datetime' || unitGroup === category) {
928-
Call(ArrayPrototypePush, allowedSingular, [singular]);
929-
}
930-
}
931-
Call(ArrayPrototypePush, allowedSingular, extraValues);
932-
let defaultVal = requiredOrDefault;
933-
if (defaultVal === REQUIRED) {
934-
defaultVal = undefined;
935-
} else if (defaultVal !== undefined) {
936-
Call(ArrayPrototypePush, allowedSingular, [defaultVal]);
937-
}
938-
const allowedValues = [];
939-
Call(ArrayPrototypePush, allowedValues, allowedSingular);
940-
for (let index = 0; index < allowedSingular.length; index++) {
941-
const singular = allowedSingular[index];
942-
const plural = Call(MapPrototypeGet, PLURAL_FOR, [singular]);
943-
if (plural !== undefined) Call(ArrayPrototypePush, allowedValues, [plural]);
944-
}
945-
let retval = GetOption(options, key, allowedValues, defaultVal);
946-
if (retval === undefined && requiredOrDefault === REQUIRED) {
947-
throw new RangeErrorCtor(`${key} is required`);
926+
Call(ArrayPrototypePush, allowedStrings, [singular, plural]);
948927
}
928+
Call(ArrayPrototypePush, allowedStrings, ['auto']);
929+
let retval = GetOption(options, key, allowedStrings, requiredOrUndefined);
930+
if (retval === undefined) return undefined;
949931
if (Call(MapPrototypeHas, SINGULAR_FOR, [retval])) retval = Call(MapPrototypeGet, SINGULAR_FOR, [retval]);
950932
return retval;
951933
}
952934

935+
export function ValidateTemporalUnitValue(value, unitGroup, extraValues = []) {
936+
if (value === undefined) return;
937+
if (Call(ArrayPrototypeIncludes, extraValues, [value])) return;
938+
for (let index = 0; index < TEMPORAL_UNITS.length; index++) {
939+
const unitInfo = TEMPORAL_UNITS[index];
940+
const singular = unitInfo[0];
941+
const plural = unitInfo[1];
942+
const category = unitInfo[2];
943+
if (value !== singular && value !== plural) continue;
944+
if (unitGroup === 'datetime' || unitGroup === category) return;
945+
}
946+
throw new RangeErrorCtor(`${value} not allowed as a ${unitGroup} unit`);
947+
}
948+
953949
export function GetTemporalRelativeToOption(options) {
954950
// returns: {
955951
// plainRelativeTo: Temporal.PlainDate | undefined
@@ -3640,7 +3636,9 @@ export function GetDifferenceSettings(op, options, group, disallowed, fallbackSm
36403636
[]
36413637
]);
36423638

3643-
let largestUnit = GetTemporalUnitValuedOption(options, 'largestUnit', group, 'auto');
3639+
let largestUnit = GetTemporalUnitValuedOption(options, 'largestUnit');
3640+
ValidateTemporalUnitValue(largestUnit, group, ['auto']);
3641+
if (!largestUnit) largestUnit = 'auto';
36443642
if (Call(ArrayPrototypeIncludes, disallowed, [largestUnit])) {
36453643
throw new RangeErrorCtor(
36463644
`largestUnit must be one of ${Call(ArrayPrototypeJoin, ALLOWED_UNITS, [', '])}, not ${largestUnit}`
@@ -3652,7 +3650,9 @@ export function GetDifferenceSettings(op, options, group, disallowed, fallbackSm
36523650
let roundingMode = GetRoundingModeOption(options, 'trunc');
36533651
if (op === 'since') roundingMode = NegateRoundingMode(roundingMode);
36543652

3655-
const smallestUnit = GetTemporalUnitValuedOption(options, 'smallestUnit', group, fallbackSmallest);
3653+
let smallestUnit = GetTemporalUnitValuedOption(options, 'smallestUnit');
3654+
ValidateTemporalUnitValue(smallestUnit, group);
3655+
if (!smallestUnit) smallestUnit = fallbackSmallest;
36563656
if (Call(ArrayPrototypeIncludes, disallowed, [smallestUnit])) {
36573657
throw new RangeErrorCtor(
36583658
`smallestUnit must be one of ${Call(ArrayPrototypeJoin, ALLOWED_UNITS, [', '])}, not ${smallestUnit}`

polyfill/lib/instant.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ export class Instant {
8181
}
8282
const roundingIncrement = ES.GetRoundingIncrementOption(roundTo);
8383
const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand');
84-
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'time', ES.REQUIRED);
84+
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', ES.REQUIRED);
85+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
8586
const maximumIncrements = {
8687
hour: 24,
8788
minute: 1440,
@@ -107,7 +108,8 @@ export class Instant {
107108
const resolvedOptions = ES.GetOptionsObject(options);
108109
const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions);
109110
const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc');
110-
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined);
111+
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit');
112+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
111113
if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"');
112114
let timeZone = resolvedOptions.timeZone;
113115
if (timeZone !== undefined) timeZone = ES.ToTemporalTimeZoneIdentifier(timeZone);

polyfill/lib/plaindatetime.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ export class PlainDateTime {
212212
}
213213
const roundingIncrement = ES.GetRoundingIncrementOption(roundTo);
214214
const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand');
215-
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'time', ES.REQUIRED, ['day']);
215+
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', ES.REQUIRED);
216+
ES.ValidateTemporalUnitValue(smallestUnit, 'time', ['day']);
216217
const maximumIncrements = {
217218
day: 1,
218219
hour: 24,
@@ -246,7 +247,8 @@ export class PlainDateTime {
246247
const showCalendar = ES.GetTemporalShowCalendarNameOption(resolvedOptions);
247248
const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions);
248249
const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc');
249-
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined);
250+
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit');
251+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
250252
if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"');
251253
const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits);
252254
const result = ES.RoundISODateTime(GetSlot(this, ISO_DATE_TIME), increment, unit, roundingMode);

polyfill/lib/plaintime.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ export class PlainTime {
105105
}
106106
const roundingIncrement = ES.GetRoundingIncrementOption(roundTo);
107107
const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand');
108-
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'time', ES.REQUIRED);
108+
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', ES.REQUIRED);
109+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
109110
const MAX_INCREMENTS = {
110111
hour: 24,
111112
minute: 60,
@@ -130,7 +131,8 @@ export class PlainTime {
130131
const resolvedOptions = ES.GetOptionsObject(options);
131132
const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions);
132133
const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc');
133-
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined);
134+
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit');
135+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
134136
if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"');
135137
const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits);
136138
const time = ES.RoundTime(GetSlot(this, TIME), increment, unit, roundingMode);

polyfill/lib/zoneddatetime.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ export class ZonedDateTime {
262262
}
263263
const roundingIncrement = ES.GetRoundingIncrementOption(roundTo);
264264
const roundingMode = ES.GetRoundingModeOption(roundTo, 'halfExpand');
265-
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', 'time', ES.REQUIRED, ['day']);
265+
const smallestUnit = ES.GetTemporalUnitValuedOption(roundTo, 'smallestUnit', ES.REQUIRED);
266+
ES.ValidateTemporalUnitValue(smallestUnit, 'time', ['day']);
266267
const maximumIncrements = {
267268
day: 1,
268269
hour: 24,
@@ -347,7 +348,8 @@ export class ZonedDateTime {
347348
const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions);
348349
const showOffset = ES.GetTemporalShowOffsetOption(resolvedOptions);
349350
const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc');
350-
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit', 'time', undefined);
351+
const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit');
352+
ES.ValidateTemporalUnitValue(smallestUnit, 'time');
351353
if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"');
352354
const showTimeZone = ES.GetTemporalShowTimeZoneNameOption(resolvedOptions);
353355
const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits);

0 commit comments

Comments
 (0)