LibJS: Implement parsing of TemporalRelativeToString

This commit is contained in:
Linus Groh 2021-11-19 20:53:07 +00:00
parent 98b876ad3f
commit 1583c7257c
Notes: sideshowbarker 2024-07-18 00:56:15 +09:00
12 changed files with 370 additions and 61 deletions

View file

@ -224,9 +224,11 @@
M(TemporalInvalidPlainTime, "Invalid plain time") \
M(TemporalInvalidPlainTimeLikeObject, "Invalid plain time-like object") \
M(TemporalInvalidPlainYearMonth, "Invalid plain year month") \
M(TemporalInvalidRelativeToString, "Invalid relative to string '{}'") \
M(TemporalInvalidTime, "Invalid time") \
M(TemporalInvalidTimeString, "Invalid time string '{}'") \
M(TemporalInvalidTimeZoneName, "Invalid time zone name") \
M(TemporalInvalidTimeZoneString, "Invalid time zone string '{}'") \
M(TemporalInvalidUnitRange, "Invalid unit range, {} is larger than {}") \
M(TemporalInvalidYearMonthString, "Invalid year month string '{}'") \
M(TemporalInvalidZonedDateTimeOffset, "Invalid offset for the provided date and time in the current time zone") \

View file

@ -1325,27 +1325,31 @@ ThrowCompletionOr<TemporalMonthDay> parse_temporal_month_day_string(GlobalObject
}
// 13.42 ParseTemporalRelativeToString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalrelativetostring
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(GlobalObject& global_object, [[maybe_unused]] String const& iso_string)
ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(GlobalObject& global_object, String const& iso_string)
{
auto& vm = global_object.vm();
// 1. Assert: Type(isoString) is String.
// 2. If isoString does not satisfy the syntax of a TemporalRelativeToString (see 13.33), then
// a. Throw a RangeError exception.
// TODO
auto parse_result = parse_iso8601(Production::TemporalRelativeToString, iso_string);
if (!parse_result.has_value()) {
// a. Throw a RangeError exception.
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidRelativeToString, iso_string);
}
// 3. Let result be ! ParseISODateTime(isoString).
auto result = MUST(parse_iso_date_time(global_object, {}));
auto result = MUST(parse_iso_date_time(global_object, *parse_result));
bool z;
Optional<String> offset;
Optional<String> time_zone;
// 4. If isoString satisfies the syntax of a TemporalZonedDateTimeString (see 13.33), then
auto parse_result = parse_iso8601(Production::TemporalZonedDateTimeString, iso_string);
parse_result = parse_iso8601(Production::TemporalZonedDateTimeString, iso_string);
if (parse_result.has_value()) {
// a. Let timeZoneResult be ! ParseTemporalTimeZoneString(isoString).
// TODO: TRY() instead of MUST() as parse_temporal_time_zone_string() still throws more than it parses :^)
auto time_zone_result = TRY(parse_temporal_time_zone_string(global_object, iso_string));
auto time_zone_result = MUST(parse_temporal_time_zone_string(global_object, iso_string));
// b. Let z be timeZoneResult.[[Z]].
z = time_zone_result.z;
@ -1391,23 +1395,27 @@ ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_
}
// 13.44 ParseTemporalTimeZoneString ( isoString ), https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimezonestring
ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject& global_object, [[maybe_unused]] String const& iso_string)
ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject& global_object, String const& iso_string)
{
auto& vm = global_object.vm();
// 1. Assert: Type(isoString) is String.
// 2. If isoString does not satisfy the syntax of a TemporalTimeZoneString (see 13.33), then
// a. Throw a RangeError exception.
auto parse_result = parse_iso8601(Production::TemporalTimeZoneString, iso_string);
if (!parse_result.has_value()) {
// a. Throw a RangeError exception.
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTimeZoneString, iso_string);
}
// 3. Let z, sign, hours, minutes, seconds, fraction and name be the parts of isoString produced respectively by the UTCDesignator, TimeZoneUTCOffsetSign, TimeZoneUTCOffsetHour, TimeZoneUTCOffsetMinute, TimeZoneUTCOffsetSecond, TimeZoneUTCOffsetFractionalPart, and TimeZoneIANAName productions, or undefined if not present.
Optional<StringView> z_part;
Optional<StringView> sign_part;
Optional<StringView> hours_part;
Optional<StringView> minutes_part;
Optional<StringView> seconds_part;
Optional<StringView> fraction_part;
Optional<StringView> name_part;
return vm.throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "ParseTemporalTimeZoneString");
auto z_part = parse_result->utc_designator;
auto sign_part = parse_result->time_zone_utc_offset_sign;
auto hours_part = parse_result->time_zone_utc_offset_hour;
auto minutes_part = parse_result->time_zone_utc_offset_minute;
auto seconds_part = parse_result->time_zone_utc_offset_second;
auto fraction_part = parse_result->time_zone_utc_offset_fractional_part;
auto name_part = parse_result->time_zone_iana_name;
// 4. If z is not undefined, then
if (z_part.has_value()) {
@ -1427,7 +1435,7 @@ ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject
VERIFY(sign_part.has_value());
// b. Set hours to ! ToIntegerOrInfinity(hours).
u8 hours = MUST(Value(js_string(vm, *hours_part)).to_integer_or_infinity(global_object));
u8 hours = *hours_part->to_uint<u8>();
u8 sign;
// c. If sign is the code unit 0x002D (HYPHEN-MINUS) or the code unit 0x2212 (MINUS SIGN), then
@ -1442,10 +1450,10 @@ ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject
}
// e. Set minutes to ! ToIntegerOrInfinity(minutes).
u8 minutes = MUST(Value(js_string(vm, minutes_part.value_or(""sv))).to_integer_or_infinity(global_object));
u8 minutes = *minutes_part.value_or("0"sv).to_uint<u8>();
// f. Set seconds to ! ToIntegerOrInfinity(seconds).
u8 seconds = MUST(Value(js_string(vm, seconds_part.value_or(""sv))).to_integer_or_infinity(global_object));
u8 seconds = *seconds_part.value_or("0"sv).to_uint<u8>();
i32 nanoseconds;
// g. If fraction is not undefined, then
@ -1454,7 +1462,7 @@ ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject
auto fraction = String::formatted("{}000000000", *fraction_part);
// ii. Let nanoseconds be the String value equal to the substring of fraction from 1 to 10.
// iii. Set nanoseconds to ! ToIntegerOrInfinity(nanoseconds).
nanoseconds = MUST(Value(js_string(vm, fraction.substring(1, 10))).to_integer_or_infinity(global_object));
nanoseconds = *fraction.substring(1, 10).to_int<i32>();
}
// h. Else,
else {

View file

@ -132,6 +132,21 @@ bool ISO8601Parser::parse_date_time_separator()
|| m_state.lexer.consume_specific('t');
}
// https://tc39.es/proposal-temporal/#prod-UTCDesignator
bool ISO8601Parser::parse_utc_designator()
{
// UTCDesignator : one of
// Z z
StateTransaction transaction { *this };
auto success = m_state.lexer.consume_specific('Z')
|| m_state.lexer.consume_specific('z');
if (!success)
return false;
m_state.parse_result.utc_designator = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-DateYear
bool ISO8601Parser::parse_date_year()
{
@ -354,12 +369,235 @@ bool ISO8601Parser::parse_time_fraction()
return parse_fraction();
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetSign
bool ISO8601Parser::parse_time_zone_utc_offset_sign()
{
// TimeZoneUTCOffsetSign :
// Sign
StateTransaction transaction { *this };
if (!parse_sign())
return false;
m_state.parse_result.time_zone_utc_offset_sign = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetHour
bool ISO8601Parser::parse_time_zone_utc_offset_hour()
{
// TimeZoneUTCOffsetHour :
// Hour
StateTransaction transaction { *this };
if (!parse_hour())
return false;
m_state.parse_result.time_zone_utc_offset_hour = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetMinute
bool ISO8601Parser::parse_time_zone_utc_offset_minute()
{
// TimeZoneUTCOffsetMinute :
// MinuteSecond
StateTransaction transaction { *this };
if (!parse_minute_second())
return false;
m_state.parse_result.time_zone_utc_offset_minute = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetSecond
bool ISO8601Parser::parse_time_zone_utc_offset_second()
{
// TimeZoneUTCOffsetSecond :
// MinuteSecond
StateTransaction transaction { *this };
if (!parse_minute_second())
return false;
m_state.parse_result.time_zone_utc_offset_second = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetFractionalPart
bool ISO8601Parser::parse_time_zone_utc_offset_fractional_part()
{
// TimeZoneUTCOffsetFractionalPart :
// FractionalPart
StateTransaction transaction { *this };
if (!parse_fractional_part())
return false;
m_state.parse_result.time_zone_utc_offset_fractional_part = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetFraction
bool ISO8601Parser::parse_time_zone_utc_offset_fraction()
{
// TimeZoneUTCOffsetFraction :
// DecimalSeparator TimeZoneUTCOffsetFractionalPart
StateTransaction transaction { *this };
if (!parse_decimal_separator())
return false;
if (!parse_time_zone_utc_offset_fractional_part())
return false;
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffset
bool ISO8601Parser::parse_time_zone_numeric_utc_offset()
{
// TimeZoneNumericUTCOffset :
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute : TimeZoneUTCOffsetSecond TimeZoneUTCOffsetFraction[opt]
// TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute TimeZoneUTCOffsetSecond TimeZoneUTCOffsetFraction[opt]
StateTransaction transaction { *this };
if (!parse_time_zone_utc_offset_sign())
return false;
if (!parse_time_zone_utc_offset_hour())
return false;
if (m_state.lexer.consume_specific(':')) {
if (!parse_time_zone_utc_offset_minute())
return false;
if (m_state.lexer.consume_specific(':')) {
if (!parse_time_zone_utc_offset_second())
return false;
(void)parse_time_zone_utc_offset_fraction();
}
} else if (parse_time_zone_utc_offset_minute()) {
if (parse_time_zone_utc_offset_second())
(void)parse_time_zone_utc_offset_fraction();
}
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffset
bool ISO8601Parser::parse_time_zone_utc_offset()
{
// TimeZoneUTCOffset :
// TimeZoneNumericUTCOffset
// UTCDesignator
return parse_time_zone_numeric_utc_offset()
|| parse_utc_designator();
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetName
bool ISO8601Parser::parse_time_zone_utc_offset_name()
{
// TimeZoneUTCOffsetName :
// Sign Hour
// Sign Hour : MinuteSecond
// Sign Hour MinuteSecond
// Sign Hour : MinuteSecond : MinuteSecond Fraction[opt]
// Sign Hour MinuteSecond MinuteSecond Fraction[opt]
StateTransaction transaction { *this };
if (!parse_sign())
return false;
if (!parse_hour())
return false;
if (m_state.lexer.consume_specific(':')) {
if (!parse_minute_second())
return false;
if (m_state.lexer.consume_specific(':')) {
if (!parse_minute_second())
return false;
(void)parse_fraction();
}
} else if (parse_minute_second()) {
if (parse_minute_second())
(void)parse_fraction();
}
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneIANAName
bool ISO8601Parser::parse_time_zone_iana_name()
{
// TZLeadingChar :
// Alpha
// .
// _
// TZChar :
// Alpha
// .
// -
// _
// TimeZoneIANANameComponent :
// TZLeadingChar TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] TZChar[opt] but not one of . or ..
// TimeZoneIANANameTail :
// TimeZoneIANANameComponent
// TimeZoneIANANameComponent / TimeZoneIANANameTail
// TimeZoneIANAName :
// TimeZoneIANANameTail
StateTransaction transaction { *this };
// TODO: Implement the full production. Currently, anything other than "UTC" would get rejected as unknown anyway.
auto success = (m_state.lexer.consume_specific('U') || m_state.lexer.consume_specific('u'))
&& (m_state.lexer.consume_specific('T') || m_state.lexer.consume_specific('t'))
&& (m_state.lexer.consume_specific('C') || m_state.lexer.consume_specific('c'));
if (!success)
return false;
m_state.parse_result.time_zone_iana_name = transaction.parsed_string_view();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneBracketedName
bool ISO8601Parser::parse_time_zone_bracketed_name()
{
// TimeZoneBracketedName :
// TimeZoneIANAName
// Etc/GMT ASCIISign Hour
// TimeZoneUTCOffsetName
StateTransaction transaction { *this };
if (parse_time_zone_iana_name()) {
// no-op.
} else if (m_state.lexer.consume_specific("Etc/GMT"sv)) {
if (!parse_ascii_sign())
return false;
if (!parse_hour())
return false;
} else if (!parse_time_zone_utc_offset_name()) {
return false;
}
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneBracketedAnnotation
bool ISO8601Parser::parse_time_zone_bracketed_annotation()
{
// TimeZoneBracketedAnnotation :
// [ TimeZoneBracketedName ]
StateTransaction transaction { *this };
if (!m_state.lexer.consume_specific('['))
return false;
if (!parse_time_zone_bracketed_name())
return false;
if (!m_state.lexer.consume_specific(']'))
return false;
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneOffsetRequired
bool ISO8601Parser::parse_time_zone_offset_required()
{
// TimeZoneOffsetRequired :
// TimeZoneUTCOffset TimeZoneBracketedAnnotation[opt]
return false;
StateTransaction transaction { *this };
if (!parse_time_zone_utc_offset())
return false;
(void)parse_time_zone_bracketed_annotation();
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZoneNameRequired
@ -367,7 +605,12 @@ bool ISO8601Parser::parse_time_zone_name_required()
{
// TimeZoneNameRequired :
// TimeZoneUTCOffset[opt] TimeZoneBracketedAnnotation
return false;
StateTransaction transaction { *this };
(void)parse_time_zone_utc_offset();
if (!parse_time_zone_bracketed_annotation())
return false;
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TimeZone
@ -543,6 +786,35 @@ bool ISO8601Parser::parse_temporal_time_string()
|| parse_time();
}
// https://tc39.es/proposal-temporal/#prod-TemporalTimeZoneIdentifier
bool ISO8601Parser::parse_temporal_time_zone_identifier()
{
// TemporalTimeZoneIdentifier :
// TimeZoneNumericUTCOffset
// TimeZoneIANAName
return parse_time_zone_numeric_utc_offset()
|| parse_time_zone_iana_name();
}
// https://tc39.es/proposal-temporal/#prod-TemporalTimeZoneString
bool ISO8601Parser::parse_temporal_time_zone_string()
{
// TemporalTimeZoneString :
// TemporalTimeZoneIdentifier
// Date TimeSpecSeparator[opt] TimeZone Calendar[opt]
StateTransaction transaction { *this };
if (!parse_temporal_time_zone_identifier()) {
if (!parse_date())
return false;
(void)parse_time_spec_separator();
if (!parse_time_zone())
return false;
(void)parse_calendar();
}
transaction.commit();
return true;
}
// https://tc39.es/proposal-temporal/#prod-TemporalYearMonthString
bool ISO8601Parser::parse_temporal_year_month_string()
{
@ -571,15 +843,27 @@ bool ISO8601Parser::parse_temporal_zoned_date_time_string()
return true;
}
// https://tc39.es/proposal-temporal/#prod-TemporalRelativeToString
bool ISO8601Parser::parse_temporal_relative_to_string()
{
// TemporalRelativeToString :
// TemporalDateTimeString
// TemporalZonedDateTimeString
return parse_temporal_date_time_string()
|| parse_temporal_zoned_date_time_string();
}
#define JS_ENUMERATE_ISO8601_PRODUCTION_PARSERS \
__JS_ENUMERATE(TemporalDateString, parse_temporal_date_string) \
__JS_ENUMERATE(TemporalDateTimeString, parse_temporal_date_time_string) \
__JS_ENUMERATE(TemporalMonthDayString, parse_temporal_month_day_string) \
__JS_ENUMERATE(TemporalTimeString, parse_temporal_time_string) \
__JS_ENUMERATE(TemporalYearMonthString, parse_temporal_year_month_string) \
__JS_ENUMERATE(TemporalZonedDateTimeString, parse_temporal_zoned_date_time_string)
}
#define JS_ENUMERATE_ISO8601_PRODUCTION_PARSERS \
__JS_ENUMERATE(TemporalDateString, parse_temporal_date_string) \
__JS_ENUMERATE(TemporalDateTimeString, parse_temporal_date_time_string) \
__JS_ENUMERATE(TemporalMonthDayString, parse_temporal_month_day_string) \
__JS_ENUMERATE(TemporalTimeString, parse_temporal_time_string) \
__JS_ENUMERATE(TemporalTimeZoneString, parse_temporal_time_zone_string) \
__JS_ENUMERATE(TemporalYearMonthString, parse_temporal_year_month_string) \
__JS_ENUMERATE(TemporalZonedDateTimeString, parse_temporal_zoned_date_time_string) \
__JS_ENUMERATE(TemporalRelativeToString, parse_temporal_relative_to_string)
Optional<ParseResult> parse_iso8601(Production production, StringView input)
{
@ -603,5 +887,4 @@ Optional<ParseResult> parse_iso8601(Production production, StringView input)
return parser.parse_result();
}
}

View file

@ -23,6 +23,13 @@ struct ParseResult {
Optional<StringView> time_second;
Optional<StringView> time_fractional_part;
Optional<StringView> calendar_name;
Optional<StringView> utc_designator;
Optional<StringView> time_zone_utc_offset_sign;
Optional<StringView> time_zone_utc_offset_hour;
Optional<StringView> time_zone_utc_offset_minute;
Optional<StringView> time_zone_utc_offset_second;
Optional<StringView> time_zone_utc_offset_fractional_part;
Optional<StringView> time_zone_iana_name;
};
enum class Production {
@ -30,8 +37,10 @@ enum class Production {
TemporalDateTimeString,
TemporalMonthDayString,
TemporalTimeString,
TemporalTimeZoneString,
TemporalYearMonthString,
TemporalZonedDateTimeString,
TemporalRelativeToString,
};
Optional<ParseResult> parse_iso8601(Production, StringView);
@ -60,6 +69,7 @@ public:
[[nodiscard]] bool parse_minute_second();
[[nodiscard]] bool parse_decimal_separator();
[[nodiscard]] bool parse_date_time_separator();
[[nodiscard]] bool parse_utc_designator();
[[nodiscard]] bool parse_date_year();
[[nodiscard]] bool parse_date_month();
[[nodiscard]] bool parse_date_day();
@ -73,6 +83,18 @@ public:
[[nodiscard]] bool parse_time_fractional_part();
[[nodiscard]] bool parse_fraction();
[[nodiscard]] bool parse_time_fraction();
[[nodiscard]] bool parse_time_zone_utc_offset_sign();
[[nodiscard]] bool parse_time_zone_utc_offset_hour();
[[nodiscard]] bool parse_time_zone_utc_offset_minute();
[[nodiscard]] bool parse_time_zone_utc_offset_second();
[[nodiscard]] bool parse_time_zone_utc_offset_fractional_part();
[[nodiscard]] bool parse_time_zone_utc_offset_fraction();
[[nodiscard]] bool parse_time_zone_numeric_utc_offset();
[[nodiscard]] bool parse_time_zone_utc_offset();
[[nodiscard]] bool parse_time_zone_utc_offset_name();
[[nodiscard]] bool parse_time_zone_iana_name();
[[nodiscard]] bool parse_time_zone_bracketed_name();
[[nodiscard]] bool parse_time_zone_bracketed_annotation();
[[nodiscard]] bool parse_time_zone_offset_required();
[[nodiscard]] bool parse_time_zone_name_required();
[[nodiscard]] bool parse_time_zone();
@ -87,8 +109,11 @@ public:
[[nodiscard]] bool parse_temporal_date_time_string();
[[nodiscard]] bool parse_temporal_month_day_string();
[[nodiscard]] bool parse_temporal_time_string();
[[nodiscard]] bool parse_temporal_time_zone_identifier();
[[nodiscard]] bool parse_temporal_time_zone_string();
[[nodiscard]] bool parse_temporal_year_month_string();
[[nodiscard]] bool parse_temporal_zoned_date_time_string();
[[nodiscard]] bool parse_temporal_relative_to_string();
private:
struct State {

View file

@ -3,8 +3,7 @@ describe("correct behavior", () => {
expect(Temporal.Instant.prototype.toZonedDateTimeISO).toHaveLength(1);
});
// TODO: Un-skip when ParseTemporalTimeZoneString is fully implemented
test.skip("basic functionality", () => {
test("basic functionality", () => {
const instant = new Temporal.Instant(1625614921123456789n);
const zonedDateTime = instant.toZonedDateTimeISO("UTC");
expect(zonedDateTime.year).toBe(2021);

View file

@ -58,8 +58,7 @@ describe("correct behavior", () => {
expect(zonedDateTime.timeZone).toBe(timeZone);
});
// TODO: Enable when parse_temporal_time_zone_string() is fully implemented
test.skip("basic functionality - time zone identifier", () => {
test("basic functionality - time zone identifier", () => {
// 4. in the spec
const plainDate = new Temporal.PlainDate(2021, 7, 6);
const zonedDateTime = plainDate.toZonedDateTime("UTC");

View file

@ -95,8 +95,7 @@ describe("correct behavior", () => {
expect(plainDateTime.nanosecond).toBe(999);
});
// Un-skip once ParseISODateTime & ParseTemporalDateString are implemented
test.skip("PlainDateTime string argument", () => {
test("PlainDateTime string argument", () => {
const plainDateTime = Temporal.PlainDateTime.from("2021-07-06T23:42:01Z");
expect(plainDateTime.year).toBe(2021);
expect(plainDateTime.month).toBe(7);

View file

@ -41,8 +41,7 @@ describe("correct behavior", () => {
expect(plainMonthDay.day).toBe(6);
});
// Un-skip once ParseISODateTime, ToTemporalMonthDay & ParseTemporalMonthDayString are fully implemented
test.skip("from date time string", () => {
test("from date time string", () => {
const plainMonthDay = Temporal.PlainMonthDay.from("2021-07-06T23:42:01Z");
expect(plainMonthDay.monthCode).toBe("M07");
expect(plainMonthDay.day).toBe(6);

View file

@ -37,8 +37,7 @@ describe("correct behavior", () => {
expect(createdPlainTime.nanosecond).toBe(0);
});
// Un-skip once ParseISODateTime & ParseTemporalTimeString are implemented
test.skip("PlainTime string argument", () => {
test("PlainTime string argument", () => {
const createdPlainTime = Temporal.PlainTime.from("2021-08-27T18:44:11Z");
expect(createdPlainTime.hour).toBe(18);
expect(createdPlainTime.minute).toBe(44);

View file

@ -62,8 +62,7 @@ describe("correct behavior", () => {
expect(plainYearMonth.monthCode).toBe("M07");
});
// Un-skip once ParseISODateTime & ParseTemporalYearMonthString are fully implemented
test.skip("from date time string", () => {
test("from date time string", () => {
const plainYearMonth = Temporal.PlainYearMonth.from("2021-07-06T23:42:01Z");
expect(plainYearMonth.year).toBe(2021);
expect(plainYearMonth.month).toBe(7);

View file

@ -96,7 +96,7 @@ describe("correct behavior", () => {
});
// FIXME: Enable when parse_iso_date_time is implemented.
test.skip("from string", () => {
test("from string", () => {
const zonedDateTime = Temporal.ZonedDateTime.from(
"2021-11-07T00:20:05.100200300+00:00[UTC][u-ca=iso8601]"
);
@ -106,17 +106,17 @@ describe("correct behavior", () => {
expect(zonedDateTime.timeZone.id).toBe("UTC");
expect(zonedDateTime.calendar).toBeInstanceOf(Temporal.Calendar);
expect(zonedDateTime.calendar.id).toBe("iso8601");
expect(createdZoneDateTime.year).toBe(2021);
expect(createdZoneDateTime.month).toBe(11);
expect(createdZoneDateTime.day).toBe(7);
expect(createdZoneDateTime.hour).toBe(0);
expect(createdZoneDateTime.minute).toBe(20);
expect(createdZoneDateTime.second).toBe(5);
expect(createdZoneDateTime.millisecond).toBe(100);
expect(createdZoneDateTime.microsecond).toBe(200);
expect(createdZoneDateTime.nanosecond).toBe(300);
expect(createdZoneDateTime.offset).toBe("+00:00");
expect(createdZoneDateTime.offsetNanoseconds).toBe(0);
expect(zonedDateTime.year).toBe(2021);
expect(zonedDateTime.month).toBe(11);
expect(zonedDateTime.day).toBe(7);
expect(zonedDateTime.hour).toBe(0);
expect(zonedDateTime.minute).toBe(20);
expect(zonedDateTime.second).toBe(5);
expect(zonedDateTime.millisecond).toBe(100);
expect(zonedDateTime.microsecond).toBe(200);
expect(zonedDateTime.nanosecond).toBe(300);
expect(zonedDateTime.offset).toBe("+00:00");
expect(zonedDateTime.offsetNanoseconds).toBe(0);
});
});

View file

@ -13,8 +13,7 @@ describe("correct behavior", () => {
expect(withTimeZoneZonedDateTime.timeZone).toBe(timeZone);
});
// FIXME: Enable this when time zone string parsing is implemented.
test.skip("from time zone string", () => {
test("from time zone string", () => {
const object = {};
const zonedDateTime = new Temporal.ZonedDateTime(1n, object);
expect(zonedDateTime.timeZone).toBe(object);
@ -32,13 +31,11 @@ describe("errors", () => {
}).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime");
});
// FIXME: Enable this when time zone string parsing is implemented.
test.skip("from invalid time zone string", () => {
test("from invalid time zone string", () => {
const zonedDateTime = new Temporal.ZonedDateTime(1n, {});
// FIXME: Use "toThrowWithMessage" once this has an error message.
expect(() => {
zonedDateTime.withTimeZone("UTCfoobar");
}).toThrow(RangeError);
}).toThrowWithMessage(RangeError, "Invalid time zone string 'UTCfoobar'");
});
});