mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
LibJS: Implement Temporal.PlainTime.prototype.with
Ticks off one box in #8982 and fixes one test262 case.
This commit is contained in:
parent
b8d683c5fb
commit
d943b8f100
8 changed files with 399 additions and 0 deletions
|
@ -191,12 +191,14 @@
|
|||
M(TemporalInvalidPlainDateTime, "Invalid plain date time") \
|
||||
M(TemporalInvalidPlainMonthDay, "Invalid plain month day") \
|
||||
M(TemporalInvalidPlainTime, "Invalid plain time") \
|
||||
M(TemporalInvalidPlainTimeLikeObject, "Invalid plain time-like object") \
|
||||
M(TemporalInvalidPlainYearMonth, "Invalid plain year month") \
|
||||
M(TemporalInvalidTime, "Invalid time") \
|
||||
M(TemporalInvalidTimeZoneName, "Invalid time zone name") \
|
||||
M(TemporalInvalidUnitRange, "Invalid unit range, {} is larger than {}") \
|
||||
M(TemporalMissingOptionsObject, "Required options object is missing or undefined") \
|
||||
M(TemporalMissingRequiredProperty, "Required property {} is missing or undefined") \
|
||||
M(TemporalPlainTimeWithArgumentMustNotHave, "Argument must not have a defined {} property") \
|
||||
M(TemporalPropertyMustBeFinite, "Property must not be Infinity") \
|
||||
M(TemporalPropertyMustBePositiveInteger, "Property must be a positive integer") \
|
||||
M(ThisHasNotBeenInitialized, "|this| has not been initialized") \
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/DateTimeLexer.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibJS/Runtime/IteratorOperations.h>
|
||||
#include <LibJS/Runtime/PropertyName.h>
|
||||
|
@ -14,8 +15,10 @@
|
|||
#include <LibJS/Runtime/Temporal/Calendar.h>
|
||||
#include <LibJS/Runtime/Temporal/Duration.h>
|
||||
#include <LibJS/Runtime/Temporal/PlainDate.h>
|
||||
#include <LibJS/Runtime/Temporal/PlainDateTime.h>
|
||||
#include <LibJS/Runtime/Temporal/PlainTime.h>
|
||||
#include <LibJS/Runtime/Temporal/TimeZone.h>
|
||||
#include <LibJS/Runtime/Temporal/ZonedDateTime.h>
|
||||
|
||||
namespace JS::Temporal {
|
||||
|
||||
|
@ -597,6 +600,20 @@ Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit)
|
|||
return 1000;
|
||||
}
|
||||
|
||||
// 13.26 RejectTemporalCalendarType ( object ), https://tc39.es/proposal-temporal/#sec-temporal-rejecttemporalcalendartype
|
||||
void reject_temporal_calendar_type(GlobalObject& global_object, Object& object)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. Assert: Type(object) is Object.
|
||||
|
||||
// 2. If object has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
|
||||
if (is<PlainDate>(object) || is<PlainDateTime>(object) || is<PlainMonthDay>(object) || is<PlainTime>(object) || is<PlainYearMonth>(object) || is<ZonedDateTime>(object)) {
|
||||
// a. Throw a TypeError exception.
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::TemporalPlainTimeWithArgumentMustNotHave, "calendar or timeZone");
|
||||
}
|
||||
}
|
||||
|
||||
// 13.27 FormatSecondsStringPart ( second, millisecond, microsecond, nanosecond, precision ), https://tc39.es/proposal-temporal/#sec-temporal-formatsecondsstringpart
|
||||
String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Variant<String, u8> const& precision)
|
||||
{
|
||||
|
|
|
@ -91,6 +91,7 @@ Optional<String> to_smallest_temporal_unit(GlobalObject&, Object& normalized_opt
|
|||
void validate_temporal_unit_range(GlobalObject&, String const& largest_unit, String const& smallest_unit);
|
||||
String larger_of_two_temporal_units(StringView, StringView);
|
||||
Optional<u16> maximum_temporal_duration_rounding_increment(StringView unit);
|
||||
void reject_temporal_calendar_type(GlobalObject&, Object&);
|
||||
String format_seconds_string_part(u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Variant<String, u8> const& precision);
|
||||
double constrain_to_range(double x, double minimum, double maximum);
|
||||
BigInt* round_number_to_increment(GlobalObject&, BigInt const&, u64 increment, StringView rounding_mode);
|
||||
|
|
|
@ -134,6 +134,54 @@ PlainTime* to_temporal_time(GlobalObject& global_object, Value item, Optional<St
|
|||
return create_temporal_time(global_object, result->hour, result->minute, result->second, result->millisecond, result->microsecond, result->nanosecond);
|
||||
}
|
||||
|
||||
// 4.5.3 ToPartialTime ( temporalTimeLike ), https://tc39.es/proposal-temporal/#sec-temporal-topartialtime
|
||||
Optional<PartialUnregulatedTemporalTime> to_partial_time(GlobalObject& global_object, Object& temporal_time_like)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. Assert: Type(temporalTimeLike) is Object.
|
||||
|
||||
// 2. Let result be the Record { [[Hour]]: undefined, [[Minute]]: undefined, [[Second]]: undefined, [[Millisecond]]: undefined, [[Microsecond]]: undefined, [[Nanosecond]]: undefined }.
|
||||
auto result = PartialUnregulatedTemporalTime {};
|
||||
|
||||
// 3. Let any be false.
|
||||
bool any = false;
|
||||
|
||||
// 4. For each row of Table 3, except the header row, in table order, do
|
||||
for (auto& [internal_slot, property] : temporal_time_like_properties<PartialUnregulatedTemporalTime, Optional<double>>(vm)) {
|
||||
// a. Let property be the Property value of the current row.
|
||||
|
||||
// b. Let value be ? Get(temporalTimeLike, property).
|
||||
auto value = temporal_time_like.get(property);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// c. If value is not undefined, then
|
||||
if (!value.is_undefined()) {
|
||||
// i. Set any to true.
|
||||
any = true;
|
||||
|
||||
// ii. Set value to ? ToIntegerThrowOnInfinity(value).
|
||||
auto value_number = to_integer_throw_on_infinity(global_object, value, ErrorType::TemporalPropertyMustBeFinite);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// iii. Set result's internal slot whose name is the Internal Slot value of the current row to value.
|
||||
result.*internal_slot = value_number;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. If any is false, then
|
||||
if (!any) {
|
||||
// a. Throw a TypeError exception.
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::TemporalInvalidPlainTimeLikeObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
// 6. Return result.
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4.5.4 RegulateTime ( hour, minute, second, millisecond, microsecond, nanosecond, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulatetime
|
||||
Optional<TemporalTime> regulate_time(GlobalObject& global_object, double hour, double minute, double second, double millisecond, double microsecond, double nanosecond, StringView overflow)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,15 @@ struct UnregulatedTemporalTime {
|
|||
double nanosecond;
|
||||
};
|
||||
|
||||
struct PartialUnregulatedTemporalTime {
|
||||
Optional<double> hour;
|
||||
Optional<double> minute;
|
||||
Optional<double> second;
|
||||
Optional<double> millisecond;
|
||||
Optional<double> microsecond;
|
||||
Optional<double> nanosecond;
|
||||
};
|
||||
|
||||
// Table 3: Properties of a TemporalTimeLike, https://tc39.es/proposal-temporal/#table-temporal-temporaltimelike-properties
|
||||
|
||||
template<typename StructT, typename ValueT>
|
||||
|
@ -82,6 +91,7 @@ auto temporal_time_like_properties = [](VM& vm) {
|
|||
};
|
||||
|
||||
PlainTime* to_temporal_time(GlobalObject&, Value item, Optional<StringView> overflow = {});
|
||||
Optional<PartialUnregulatedTemporalTime> to_partial_time(GlobalObject&, Object& temporal_time_like);
|
||||
Optional<TemporalTime> regulate_time(GlobalObject&, double hour, double minute, double second, double millisecond, double microsecond, double nanosecond, StringView overflow);
|
||||
bool is_valid_time(double hour, double minute, double second, double millisecond, double microsecond, double nanosecond);
|
||||
DaysAndTime balance_time(i64 hour, i64 minute, i64 second, i64 millisecond, i64 microsecond, i64 nanosecond);
|
||||
|
|
|
@ -38,6 +38,7 @@ void PlainTimePrototype::initialize(GlobalObject& global_object)
|
|||
define_native_accessor(vm.names.nanosecond, nanosecond_getter, {}, Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(vm.names.with, with, 1, attr);
|
||||
define_native_function(vm.names.equals, equals, 1, attr);
|
||||
define_native_function(vm.names.toPlainDateTime, to_plain_date_time, 1, attr);
|
||||
define_native_function(vm.names.getISOFields, get_iso_fields, 0, attr);
|
||||
|
@ -148,6 +149,115 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::nanosecond_getter)
|
|||
return Value(temporal_time->iso_nanosecond());
|
||||
}
|
||||
|
||||
// 4.3.12 Temporal.PlainTime.prototype.with ( temporalTimeLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.with
|
||||
JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with)
|
||||
{
|
||||
// 1. Let temporalTime be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(temporalTime, [[InitializedTemporalTime]]).
|
||||
auto* temporal_time = typed_this(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto temporal_time_like_argument = vm.argument(0);
|
||||
|
||||
// 3. If Type(temporalTimeLike) is not Object, then
|
||||
if (!temporal_time_like_argument.is_object()) {
|
||||
// a. Throw a TypeError exception.
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, temporal_time_like_argument.to_string_without_side_effects());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& temporal_time_like = temporal_time_like_argument.as_object();
|
||||
|
||||
// 4. Perform ? RejectTemporalCalendarType(temporalTimeLike).
|
||||
reject_temporal_calendar_type(global_object, temporal_time_like);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 5. Let calendarProperty be ? Get(temporalTimeLike, "calendar").
|
||||
auto calendar_property = temporal_time_like.get(vm.names.calendar);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 6. If calendarProperty is not undefined, then
|
||||
if (!calendar_property.is_undefined()) {
|
||||
// a. Throw a TypeError exception.
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::TemporalPlainTimeWithArgumentMustNotHave, "calendar");
|
||||
return {};
|
||||
}
|
||||
|
||||
// 7. Let timeZoneProperty be ? Get(temporalTimeLike, "timeZone").
|
||||
auto time_zone_property = temporal_time_like.get(vm.names.timeZone);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 8. If timeZoneProperty is not undefined, then
|
||||
if (!time_zone_property.is_undefined()) {
|
||||
// a. Throw a TypeError exception.
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::TemporalPlainTimeWithArgumentMustNotHave, "timeZone");
|
||||
return {};
|
||||
}
|
||||
|
||||
// 9. Let partialTime be ? ToPartialTime(temporalTimeLike).
|
||||
auto partial_time = to_partial_time(global_object, temporal_time_like);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 10. Set options to ? GetOptionsObject(options).
|
||||
auto* options = get_options_object(global_object, vm.argument(1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 11. Let overflow be ? ToTemporalOverflow(options).
|
||||
auto overflow = to_temporal_overflow(global_object, *options);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 12. If partialTime.[[Hour]] is not undefined, then
|
||||
// a. Let hour be partialTime.[[Hour]].
|
||||
// 13. Else,
|
||||
// a. Let hour be temporalTime.[[ISOHour]].
|
||||
auto hour = partial_time->hour.value_or(temporal_time->iso_hour());
|
||||
|
||||
// 14. If partialTime.[[Minute]] is not undefined, then
|
||||
// a. Let minute be partialTime.[[Minute]].
|
||||
// 15. Else,
|
||||
// a. Let minute be temporalTime.[[ISOMinute]].
|
||||
auto minute = partial_time->minute.value_or(temporal_time->iso_minute());
|
||||
|
||||
// 16. If partialTime.[[Second]] is not undefined, then
|
||||
// a. Let second be partialTime.[[Second]].
|
||||
// 17. Else,
|
||||
// a. Let second be temporalTime.[[ISOSecond]].
|
||||
auto second = partial_time->second.value_or(temporal_time->iso_second());
|
||||
|
||||
// 18. If partialTime.[[Millisecond]] is not undefined, then
|
||||
// a. Let millisecond be partialTime.[[Millisecond]].
|
||||
// 19. Else,
|
||||
// a. Let millisecond be temporalTime.[[ISOMillisecond]].
|
||||
auto millisecond = partial_time->millisecond.value_or(temporal_time->iso_millisecond());
|
||||
|
||||
// 20. If partialTime.[[Microsecond]] is not undefined, then
|
||||
// a. Let microsecond be partialTime.[[Microsecond]].
|
||||
// 21. Else,
|
||||
// a. Let microsecond be temporalTime.[[ISOMicrosecond]].
|
||||
auto microsecond = partial_time->microsecond.value_or(temporal_time->iso_microsecond());
|
||||
|
||||
// 22. If partialTime.[[Nanosecond]] is not undefined, then
|
||||
// a. Let nanosecond be partialTime.[[Nanosecond]].
|
||||
// 23. Else,
|
||||
// a. Let nanosecond be temporalTime.[[ISONanosecond]].
|
||||
auto nanosecond = partial_time->nanosecond.value_or(temporal_time->iso_nanosecond());
|
||||
|
||||
// 24. Let result be ? RegulateTime(hour, minute, second, millisecond, microsecond, nanosecond, overflow).
|
||||
auto result = regulate_time(global_object, hour, minute, second, millisecond, microsecond, nanosecond, *overflow);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
// 25. Return ? CreateTemporalTime(result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]).
|
||||
return create_temporal_time(global_object, result->hour, result->minute, result->second, result->millisecond, result->microsecond, result->nanosecond);
|
||||
}
|
||||
|
||||
// 4.3.16 Temporal.PlainTime.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.equals
|
||||
JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::equals)
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ private:
|
|||
JS_DECLARE_NATIVE_FUNCTION(millisecond_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(microsecond_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(nanosecond_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(with);
|
||||
JS_DECLARE_NATIVE_FUNCTION(equals);
|
||||
JS_DECLARE_NATIVE_FUNCTION(to_plain_date_time);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_iso_fields);
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
const PLAIN_TIME_PROPERTIES = [
|
||||
"hour",
|
||||
"minute",
|
||||
"second",
|
||||
"millisecond",
|
||||
"microsecond",
|
||||
"nanosecond",
|
||||
];
|
||||
|
||||
const REJECTED_CALENDAR_TYPES_THREE_ARGUMENTS = [
|
||||
Temporal.PlainDate,
|
||||
Temporal.PlainDateTime,
|
||||
Temporal.PlainTime,
|
||||
];
|
||||
|
||||
const REJECTED_CALENDAR_TYPES_TWO_ARGUMENTS = [Temporal.PlainMonthDay, Temporal.PlainYearMonth];
|
||||
|
||||
describe("correct behaviour", () => {
|
||||
test("length is 1", () => {
|
||||
expect(Temporal.PlainTime.prototype.with).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("basic functionality", () => {
|
||||
const plainTime = new Temporal.PlainTime(1, 2, 3).with({ hour: 4, foo: 5, second: 6 });
|
||||
expect(plainTime.hour).toBe(4);
|
||||
expect(plainTime.minute).toBe(2);
|
||||
expect(plainTime.second).toBe(6);
|
||||
});
|
||||
|
||||
test("each property is looked up from the object", () => {
|
||||
for (const property of PLAIN_TIME_PROPERTIES) {
|
||||
const plainTime = new Temporal.PlainTime().with({ [property]: 1 });
|
||||
expect(plainTime[property]).toBe(1);
|
||||
}
|
||||
});
|
||||
|
||||
test("each property is coerced to number", () => {
|
||||
for (const property of PLAIN_TIME_PROPERTIES) {
|
||||
const plainTime = new Temporal.PlainTime().with({ [property]: "1" });
|
||||
expect(plainTime[property]).toBe(1);
|
||||
}
|
||||
});
|
||||
|
||||
test("argument can have a calendar property as long as it's undefined", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
calendar: undefined,
|
||||
});
|
||||
}).not.toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
|
||||
});
|
||||
|
||||
test("argument can have a timeZone property as long as it's undefined", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
timeZone: undefined,
|
||||
});
|
||||
}).not.toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
test("this value must be a Temporal.PlainTime object", () => {
|
||||
expect(() => {
|
||||
Temporal.PlainTime.prototype.with.call("foo");
|
||||
}).toThrowWithMessage(TypeError, "Not a Temporal.PlainTime object");
|
||||
});
|
||||
|
||||
test("argument is not an object", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with("foo");
|
||||
}).toThrowWithMessage(TypeError, "foo is not an object");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with(42);
|
||||
}).toThrowWithMessage(TypeError, "42 is not an object");
|
||||
});
|
||||
|
||||
test("options is not an object", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ hour: 1 }, "foo");
|
||||
}).toThrowWithMessage(TypeError, "Options is not an object");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ hour: 1 }, 42);
|
||||
}).toThrowWithMessage(TypeError, "Options is not an object");
|
||||
});
|
||||
|
||||
test("invalid overflow option", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ hour: 1 }, { overflow: "a" });
|
||||
}).toThrowWithMessage(RangeError, "a is not a valid value for option overflow");
|
||||
});
|
||||
|
||||
test("argument is an invalid plain time-like object", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({});
|
||||
}).toThrowWithMessage(TypeError, "Invalid plain time-like object");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ foo: 1, bar: 2 });
|
||||
}).toThrowWithMessage(TypeError, "Invalid plain time-like object");
|
||||
});
|
||||
|
||||
test("error when coercing property to number", () => {
|
||||
for (const property of PLAIN_TIME_PROPERTIES) {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
[property]: {
|
||||
valueOf() {
|
||||
throw new Error("error occurred");
|
||||
},
|
||||
},
|
||||
});
|
||||
}).toThrowWithMessage(Error, "error occurred");
|
||||
}
|
||||
});
|
||||
|
||||
test("property must be finite", () => {
|
||||
for (const property of PLAIN_TIME_PROPERTIES) {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ [property]: Infinity });
|
||||
}).toThrowWithMessage(RangeError, "Property must not be Infinity");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({ [property]: -Infinity });
|
||||
}).toThrowWithMessage(RangeError, "Property must not be Infinity");
|
||||
}
|
||||
});
|
||||
|
||||
test("error when getting property", () => {
|
||||
for (const property of PLAIN_TIME_PROPERTIES) {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
get [property]() {
|
||||
throw new Error("error occurred");
|
||||
},
|
||||
});
|
||||
}).toThrowWithMessage(Error, "error occurred");
|
||||
}
|
||||
});
|
||||
|
||||
test("argument must not have a defined calendar property", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
calendar: null,
|
||||
});
|
||||
}).toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
calendar: 1,
|
||||
});
|
||||
}).toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
|
||||
});
|
||||
|
||||
test("argument must not have a defined timeZone property", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
timeZone: null,
|
||||
});
|
||||
}).toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
timeZone: 1,
|
||||
});
|
||||
}).toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
|
||||
});
|
||||
|
||||
test("error when getting calendar", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
get calendar() {
|
||||
throw new Error("error occurred");
|
||||
},
|
||||
});
|
||||
}).toThrowWithMessage(Error, "error occurred");
|
||||
});
|
||||
|
||||
test("error when getting timeZone", () => {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with({
|
||||
get timeZone() {
|
||||
throw new Error("error occurred");
|
||||
},
|
||||
});
|
||||
}).toThrowWithMessage(Error, "error occurred");
|
||||
});
|
||||
|
||||
test("rejects calendar types", () => {
|
||||
for (const typeWithCalendar of REJECTED_CALENDAR_TYPES_THREE_ARGUMENTS) {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with(new typeWithCalendar(1, 1, 1));
|
||||
}).toThrowWithMessage(
|
||||
TypeError,
|
||||
"Argument must not have a defined calendar or timeZone property"
|
||||
);
|
||||
}
|
||||
|
||||
for (const typeWithCalendar of REJECTED_CALENDAR_TYPES_TWO_ARGUMENTS) {
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with(new typeWithCalendar(1, 1));
|
||||
}).toThrowWithMessage(
|
||||
TypeError,
|
||||
"Argument must not have a defined calendar or timeZone property"
|
||||
);
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
new Temporal.PlainTime().with(new Temporal.ZonedDateTime(1n, {}));
|
||||
}).toThrowWithMessage(
|
||||
TypeError,
|
||||
"Argument must not have a defined calendar or timeZone property"
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue