Skip to content

Commit

Permalink
Stub out a components test, and use serde serialization for DateTime …
Browse files Browse the repository at this point in the history
…options (#461)

* Stub out tests and serialization for components::Bag

* Add serialization for the style::Bag

* Fix preference bag attribute to use the conditional feature

* Fix the attributes to properly treat serde as optional

* Address feedback on freely deriving certain traits
  • Loading branch information
gregtatum authored Feb 8, 2021
1 parent ae89da4 commit 85c3a5a
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 43 deletions.
76 changes: 75 additions & 1 deletion components/datetime/src/options/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,14 @@
//! time. Formatted result should be treated as opaque and displayed to the user as-is,
//! and it is strongly recommended to never write tests that expect a particular formatted output.
use super::preferences;
#[cfg(all(not(feature = "serialize_none"), feature = "serde"))]
use serde::{Deserialize, Serialize};

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub struct Bag {
pub era: Option<Text>,
pub year: Option<Numeric>,
Expand All @@ -69,6 +75,10 @@ pub struct Bag {

pub time_zone_name: Option<TimeZoneName>,

#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(skip_serializing, skip_deserializing)
)]
pub preferences: Option<preferences::Bag>,
}

Expand All @@ -93,29 +103,93 @@ impl Default for Bag {
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum Numeric {
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "numeric")
)]
Numeric,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "two-digit")
)]
TwoDigit,
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum Text {
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "long")
)]
Long,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "short")
)]
Short,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "narrow")
)]
Narrow,
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum Month {
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "numeric")
)]
Numeric,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "two-digit")
)]
TwoDigit,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "long")
)]
Long,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "short")
)]
Short,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "narrow")
)]
Narrow,
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum TimeZoneName {
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "long")
)]
Long,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "short")
)]
Short,
}
2 changes: 1 addition & 1 deletion components/datetime/src/options/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::fields;
/// hour_cycle: Some(preferences::HourCycle::H23)
/// };
/// ```
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
pub struct Bag {
pub hour_cycle: Option<HourCycle>,
}
Expand Down
52 changes: 51 additions & 1 deletion components/datetime/src/options/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
//! time. Formatted result should be treated as opaque and displayed to the user as-is,
//! and it is strongly recommended to never write tests that expect a particular formatted output.
use super::preferences;
#[cfg(all(not(feature = "serialize_none"), feature = "serde"))]
use serde::{Deserialize, Serialize};
/// `style::Bag` is a structure to represent the set of styles in which the `DateTime` should
/// be formatted to.
///
Expand Down Expand Up @@ -71,10 +73,18 @@ use super::preferences;
///
/// [`UTS #35: Unicode LDML 4. Dates`]: https://unicode.org/reports/tr35/tr35-dates.html
/// [`Element dateFormats`]: https://unicode.org/reports/tr35/tr35-dates.html#dateFormats
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub struct Bag {
pub date: Option<Date>,
pub time: Option<Time>,
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(skip_serializing, skip_deserializing)
)]
pub preferences: Option<preferences::Bag>,
}

Expand Down Expand Up @@ -114,6 +124,10 @@ impl Default for Bag {
/// [`Element dateFormats`]: https://unicode.org/reports/tr35/tr35-dates.html#dateFormats
/// [`DateTimeFormat`]: super::super::DateTimeFormat
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum Date {
/// Full length, usually with weekday name.
///
Expand All @@ -126,6 +140,10 @@ pub enum Date {
/// "вторник, 21 января 2020 г."; // ru
/// "2020年1月21日火曜日"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "full")
)]
Full,
/// Long length, with wide month name.
///
Expand All @@ -138,6 +156,10 @@ pub enum Date {
/// "10 сентября 2020 г."; // ru
/// "2020年9月10日"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "long")
)]
Long,
/// Medium length.
///
Expand All @@ -150,6 +172,10 @@ pub enum Date {
/// "20 февр. 2020 г."; // ru
/// "2020/02/20"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "medium")
)]
Medium,
/// Short length, usually with numeric month.
///
Expand All @@ -162,6 +188,10 @@ pub enum Date {
/// "30.01.2020"; // ru
/// "2020/01/30"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "short")
)]
Short,
}

Expand Down Expand Up @@ -191,6 +221,10 @@ pub enum Date {
/// [`Element dateFormats`]: https://unicode.org/reports/tr35/tr35-dates.html#timeFormats
/// [`DateTimeFormat`]: super::super::DateTimeFormat
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
derive(Serialize, Deserialize)
)]
pub enum Time {
/// Full length, with spelled out time zone name.
///
Expand All @@ -203,6 +237,10 @@ pub enum Time {
/// "08:25:07 Тихоокеанское стандартное время"; // ru
/// "8時25分07秒 アメリカ太平洋標準時"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "full")
)]
Full,
/// Full length, usually with short time zone code.
///
Expand All @@ -215,6 +253,10 @@ pub enum Time {
/// "08:25:07 GMT-8"; // ru
/// "8:25:07 GMT-8"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "long")
)]
Long,
/// Full length, usually with seconds.
///
Expand All @@ -227,6 +269,10 @@ pub enum Time {
/// "08:25:07"; // ru
/// "8:25:07"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "medium")
)]
Medium,
/// Full length, usually without seconds.
///
Expand All @@ -239,5 +285,9 @@ pub enum Time {
/// "08:25"; // ru
/// "8:25"; // ja
/// ```
#[cfg_attr(
all(not(feature = "serialize_none"), feature = "serde"),
serde(rename = "short")
)]
Short,
}
20 changes: 17 additions & 3 deletions components/datetime/tests/datetime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/master/LICENSE ).
#![cfg(all(not(feature = "serialize_none"), feature = "serde"))]

mod fixtures;
mod patterns;

Expand All @@ -15,11 +17,10 @@ use icu_provider::{
};
use std::{borrow::Cow, fmt::Write};

#[test]
fn test_fixtures() {
fn test_fixture(fixture_name: &str) {
let provider = icu_testdata::get_provider();

for fx in fixtures::get_fixture("styles").unwrap().0 {
for fx in fixtures::get_fixture(fixture_name).unwrap().0 {
let langid = fx.input.locale.parse().unwrap();
let options = fixtures::get_options(&fx.input.options);
let dtf = DateTimeFormat::try_new(langid, &provider, &options).unwrap();
Expand Down Expand Up @@ -93,3 +94,16 @@ fn test_dayperiod_patterns() {
}
}
}

#[test]
fn test_style_fixtures() {
test_fixture("styles");
}

// Expected panic: 'not implemented', components/datetime/src/provider.rs:49:53
// https://github.com/unicode-org/icu4x/issues/272
#[test]
#[should_panic]
fn test_components_fixtures() {
test_fixture("components");
}
23 changes: 6 additions & 17 deletions components/datetime/tests/fixtures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/master/LICENSE ).
#![cfg(all(not(feature = "serialize_none"), feature = "serde"))]

pub mod structs;

use icu_datetime::options::style;
use icu_datetime::DateTimeFormatOptions;
use std::fs::File;
use std::io::BufReader;
Expand All @@ -16,20 +17,8 @@ pub fn get_fixture(name: &str) -> std::io::Result<structs::Fixture> {
}

pub fn get_options(input: &structs::TestOptions) -> DateTimeFormatOptions {
let style = style::Bag {
date: input.style.date.as_ref().map(|date| match date {
structs::TestStyleWidth::Full => style::Date::Full,
structs::TestStyleWidth::Long => style::Date::Long,
structs::TestStyleWidth::Medium => style::Date::Medium,
structs::TestStyleWidth::Short => style::Date::Short,
}),
time: input.style.time.as_ref().map(|time| match time {
structs::TestStyleWidth::Full => style::Time::Full,
structs::TestStyleWidth::Long => style::Time::Long,
structs::TestStyleWidth::Medium => style::Time::Medium,
structs::TestStyleWidth::Short => style::Time::Short,
}),
..Default::default()
};
style.into()
match input {
structs::TestOptions::Style(bag) => (*bag).clone().into(),
structs::TestOptions::Components(bag) => (*bag).clone().into(),
}
}
28 changes: 8 additions & 20 deletions components/datetime/tests/fixtures/structs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/master/LICENSE ).
#![cfg(all(not(feature = "serialize_none"), feature = "serde"))]

use icu_datetime::options::{components, style};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand All @@ -20,26 +23,11 @@ pub struct TestInput {
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TestOptions {
pub style: TestOptionsStyle,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TestOptionsStyle {
pub date: Option<TestStyleWidth>,
pub time: Option<TestStyleWidth>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum TestStyleWidth {
#[serde(rename = "short")]
Short,
#[serde(rename = "medium")]
Medium,
#[serde(rename = "long")]
Long,
#[serde(rename = "full")]
Full,
pub enum TestOptions {
#[serde(rename = "style")]
Style(style::Bag),
#[serde(rename = "components")]
Components(components::Bag),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down
Loading

0 comments on commit 85c3a5a

Please sign in to comment.