Skip to content

Commit f11323d

Browse files
committed
feat(intl): implement Temporal.PlainYearMonth.prototype.toLocaleString
1 parent bf3282f commit f11323d

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

core/engine/src/builtins/date/utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ pub(super) fn make_date(day: f64, time: f64) -> f64 {
442442
tv
443443
}
444444

445+
#[cfg(feature = "intl")]
446+
pub(crate) fn timestamp_for_first_of_month_utc(year: i32, month: u8) -> f64 {
447+
debug_assert!((1..=12).contains(&month));
448+
let day = make_day(f64::from(year), f64::from(month - 1), 1.0);
449+
let time = make_time(0.0, 0.0, 0.0, 0.0);
450+
time_clip(make_date(day, time))
451+
}
452+
445453
/// Abstract operation `MakeFullYear ( year )`
446454
///
447455
/// More info:

core/engine/src/builtins/temporal/plain_year_month/mod.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ use super::{
3333
to_temporal_duration,
3434
};
3535

36+
#[cfg(feature = "temporal")]
37+
#[cfg(test)]
38+
mod tests;
39+
3640
/// The `Temporal.PlainYearMonth` built-in implementation
3741
///
3842
/// More information:
@@ -755,12 +759,15 @@ impl PlainYearMonth {
755759
///
756760
/// [spec]: https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth.tolocalestring
757761
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toLocaleString
762+
#[allow(
763+
unused_variables,
764+
reason = "`args` and `context` are used when the `intl` feature is enabled"
765+
)]
758766
pub(crate) fn to_locale_string(
759767
this: &JsValue,
760-
_: &[JsValue],
761-
_: &mut Context,
768+
args: &[JsValue],
769+
context: &mut Context,
762770
) -> JsResult<JsValue> {
763-
// TODO: Update for ECMA-402 compliance
764771
let object = this.as_object();
765772
let year_month = object
766773
.as_ref()
@@ -769,7 +776,30 @@ impl PlainYearMonth {
769776
JsNativeError::typ().with_message("this value must be a PlainYearMonth object.")
770777
})?;
771778

772-
Ok(JsString::from(year_month.inner.to_string()).into())
779+
#[cfg(feature = "intl")]
780+
{
781+
use crate::builtins::{
782+
date::utils::timestamp_for_first_of_month_utc,
783+
intl::date_time_format::{FormatDefaults, FormatType, format_date_time_locale},
784+
};
785+
let locales = args.get_or_undefined(0);
786+
let options = args.get_or_undefined(1);
787+
let timestamp =
788+
timestamp_for_first_of_month_utc(year_month.inner.year(), year_month.inner.month());
789+
format_date_time_locale(
790+
locales,
791+
options,
792+
FormatType::Date,
793+
FormatDefaults::Date,
794+
timestamp,
795+
context,
796+
)
797+
}
798+
799+
#[cfg(not(feature = "intl"))]
800+
{
801+
Ok(JsString::from(year_month.inner.to_string()).into())
802+
}
773803
}
774804

775805
/// 9.3.21 `Temporal.PlainYearMonth.prototype.toJSON ( )`
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use crate::{JsNativeErrorKind, TestAction, run_test_actions};
2+
3+
#[test]
4+
fn to_locale_string_returns_string() {
5+
run_test_actions([
6+
TestAction::assert(
7+
"typeof Temporal.PlainYearMonth.from('2024-03').toLocaleString() === 'string'",
8+
),
9+
TestAction::assert("Temporal.PlainYearMonth.from('2024-03').toLocaleString().length > 0"),
10+
]);
11+
}
12+
13+
#[test]
14+
fn to_locale_string_invalid_receiver_throws() {
15+
run_test_actions([TestAction::assert_native_error(
16+
"Temporal.PlainYearMonth.prototype.toLocaleString.call({})",
17+
JsNativeErrorKind::Type,
18+
"this value must be a PlainYearMonth object.",
19+
)]);
20+
}
21+
22+
#[cfg(feature = "intl")]
23+
#[test]
24+
fn to_locale_string_different_locales_produce_different_output() {
25+
run_test_actions([TestAction::assert(
26+
"Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US') !== \
27+
Temporal.PlainYearMonth.from('2024-03').toLocaleString('de-DE')",
28+
)]);
29+
}
30+
31+
#[cfg(feature = "intl")]
32+
#[test]
33+
fn to_locale_string_options_affect_output() {
34+
run_test_actions([
35+
TestAction::assert(
36+
"typeof Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US', { dateStyle: 'short' }) === 'string'",
37+
),
38+
TestAction::assert(
39+
"Temporal.PlainYearMonth.from('2024-03').toLocaleString('en-US', { dateStyle: 'short' }).length > 0",
40+
),
41+
]);
42+
}

0 commit comments

Comments
 (0)