use crate::AssertThat;
use crate::mode::Mode;
use crate::tracking::AssertionTracking;
use alloc::borrow::ToOwned;
use core::borrow::Borrow;
use indoc::writedoc;
use jiff::Zoned;
use jiff::tz::TimeZone;
use std::fmt::Write;
#[allow(clippy::return_self_not_must_use)]
#[cfg_attr(feature = "fluent", assertr_derive::fluent_aliases)]
pub trait ZonedAssertions {
fn is_in_time_zone(self, expected: impl Borrow<TimeZone>) -> Self;
fn is_in_time_zone_named(self, expected: impl AsRef<str>) -> Self;
}
impl<M: Mode> ZonedAssertions for AssertThat<'_, Zoned, M> {
#[track_caller]
fn is_in_time_zone(self, expected: impl Borrow<TimeZone>) -> Self {
self.track_assertion();
let zdt = self.actual();
let expected = expected.borrow();
if self.actual().time_zone() != expected.borrow() {
let actual = self
.actual()
.time_zone()
.iana_name()
.map_or_else(|| format!("{expected:?}"), ToOwned::to_owned);
let expected = expected
.iana_name()
.map_or_else(|| format!("{expected:?}"), ToOwned::to_owned);
self.fail(|w: &mut String| {
writedoc! {w, r"
Expected: {expected}
Actual: {actual}
Object: {zdt:#?}
"}
});
}
self
}
#[track_caller]
fn is_in_time_zone_named(self, expected: impl AsRef<str>) -> Self {
self.track_assertion();
let expected = expected.as_ref();
let actual = self.actual().time_zone().iana_name();
match actual {
None => self.fail(|w: &mut String| {
writedoc! {w, r"
Expected: '{expected}'
Actual: Zoned without a named time zone.
Object: {:#?}
", self.actual()}
}),
Some(actual) if actual != expected => self.fail(|w: &mut String| {
writedoc! {w, r"
Expected: {expected}
Actual: {actual}
Object: {:#?}
", self.actual()}
}),
_ => {}
}
self
}
}
#[cfg(test)]
mod tests {
mod is_in_time_zone {
use crate::prelude::*;
use indoc::formatdoc;
use jiff::Zoned;
use jiff::tz::TimeZone;
#[test]
fn succeeds_when_matches() {
let zdt: Zoned = "2024-06-19 15:22[America/New_York]".parse().expect("valid");
let tz = TimeZone::get("America/New_York").expect("valid");
assert_that!(zdt).is_in_time_zone(tz);
}
#[test]
fn panics_when_in_different_time_zone() {
let zdt: Zoned = "2024-06-19 15:22[America/New_York]".parse().expect("valid");
let tz = TimeZone::get("Europe/Berlin").expect("valid");
assert_that_panic_by(|| {
assert_that!(zdt).with_location(false).is_in_time_zone(tz);
})
.has_type::<String>()
.is_equal_to(formatdoc! {r#"
-------- assertr --------
Expected: Europe/Berlin
Actual: America/New_York
Object: 2024-06-19T15:22:00-04:00[America/New_York]
-------- assertr --------
"#});
}
}
mod is_in_time_zone_named {
use crate::prelude::*;
use indoc::formatdoc;
use jiff::Zoned;
#[test]
fn succeeds_when_matches() {
let zdt: Zoned = "2024-06-19 15:22[America/New_York]".parse().expect("valid");
assert_that!(zdt).is_in_time_zone_named("America/New_York");
}
#[test]
fn panics_when_in_different_time_zone() {
let zdt: Zoned = "2024-06-19 15:22[America/New_York]".parse().expect("valid");
assert_that_panic_by(|| {
assert_that!(zdt)
.with_location(false)
.is_in_time_zone_named("Europe/Berlin");
})
.has_type::<String>()
.is_equal_to(formatdoc! {r#"
-------- assertr --------
Expected: Europe/Berlin
Actual: America/New_York
Object: 2024-06-19T15:22:00-04:00[America/New_York]
-------- assertr --------
"#});
}
}
}