Skip to content
Open
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
8 changes: 8 additions & 0 deletions core/engine/src/builtins/date/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,14 @@ pub(super) fn make_date(day: f64, time: f64) -> f64 {
tv
}

#[cfg(feature = "intl")]
pub(crate) fn timestamp_for_first_of_month_utc(year: i32, month: u8) -> f64 {
debug_assert!((1..=12).contains(&month));
let day = make_day(f64::from(year), f64::from(month - 1), 1.0);
let time = make_time(0.0, 0.0, 0.0, 0.0);
time_clip(make_date(day, time))
}

/// Abstract operation `MakeFullYear ( year )`
///
/// More info:
Expand Down
38 changes: 34 additions & 4 deletions core/engine/src/builtins/temporal/plain_year_month/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ use super::{
to_temporal_duration,
};

#[cfg(feature = "temporal")]
#[cfg(test)]
mod tests;

/// The `Temporal.PlainYearMonth` built-in implementation
///
/// More information:
Expand Down Expand Up @@ -755,12 +759,15 @@ impl PlainYearMonth {
///
/// [spec]: https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth.tolocalestring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toLocaleString
#[allow(
unused_variables,
reason = "`args` and `context` are used when the `intl` feature is enabled"
)]
pub(crate) fn to_locale_string(
this: &JsValue,
_: &[JsValue],
_: &mut Context,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
// TODO: Update for ECMA-402 compliance
let object = this.as_object();
let year_month = object
.as_ref()
Expand All @@ -769,7 +776,30 @@ impl PlainYearMonth {
JsNativeError::typ().with_message("this value must be a PlainYearMonth object.")
})?;

Ok(JsString::from(year_month.inner.to_string()).into())
#[cfg(feature = "intl")]
{
use crate::builtins::{
date::utils::timestamp_for_first_of_month_utc,
intl::date_time_format::{FormatDefaults, FormatType, format_date_time_locale},
};
let locales = args.get_or_undefined(0);
let options = args.get_or_undefined(1);
let timestamp =
timestamp_for_first_of_month_utc(year_month.inner.year(), year_month.inner.month());
format_date_time_locale(
locales,
options,
FormatType::Date,
FormatDefaults::Date,
timestamp,
context,
)
}

#[cfg(not(feature = "intl"))]
{
Ok(JsString::from(year_month.inner.to_string()).into())
}
}

/// 9.3.21 `Temporal.PlainYearMonth.prototype.toJSON ( )`
Expand Down
42 changes: 42 additions & 0 deletions core/engine/src/builtins/temporal/plain_year_month/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::{JsNativeErrorKind, TestAction, run_test_actions};

#[test]
fn to_locale_string_returns_string() {
run_test_actions([
TestAction::assert(
"typeof Temporal.PlainYearMonth.from('2024-03').toLocaleString() === 'string'",
),
TestAction::assert("Temporal.PlainYearMonth.from('2024-03').toLocaleString().length > 0"),
]);
}

#[test]
fn to_locale_string_invalid_receiver_throws() {
run_test_actions([TestAction::assert_native_error(
"Temporal.PlainYearMonth.prototype.toLocaleString.call({})",
JsNativeErrorKind::Type,
"this value must be a PlainYearMonth object.",
)]);
}

#[cfg(feature = "intl")]
#[test]
fn to_locale_string_different_locales_produce_different_output() {
run_test_actions([TestAction::assert(
"Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US') !== \
Temporal.PlainYearMonth.from('2024-03').toLocaleString('de-DE')",
)]);
}

#[cfg(feature = "intl")]
#[test]
fn to_locale_string_options_affect_output() {
run_test_actions([
TestAction::assert(
"typeof Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US', { dateStyle: 'short' }) === 'string'",
),
TestAction::assert(
"Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US', { dateStyle: 'short' }).length > 0",
),
]);
}
Loading