diff --git a/tests/it/compute/temporal.rs b/tests/it/compute/temporal.rs index f0e3306c4af..7619e280983 100644 --- a/tests/it/compute/temporal.rs +++ b/tests/it/compute/temporal.rs @@ -3,155 +3,262 @@ use arrow2::compute::temporal::*; use arrow2::datatypes::*; #[test] -fn date64_second() { - let array = - Int64Array::from(&[Some(1514764800000), None, Some(1550636625000)]).to(DataType::Date64); - - let result = second(&array).unwrap(); - let expected = UInt32Array::from(&[Some(0), None, Some(45)]); - assert_eq!(result, expected); +fn temporal_hour() { + for data_type in TestData::available_time_like_types() { + let data = TestData::data(&data_type); + let result = hour(&*data.input).unwrap(); + + assert_eq!( + result, + data.hour.unwrap(), + "\"hour\" failed on type: {:?}", + data_type + ); + } } #[test] -fn date64_minute() { - let array = - Int64Array::from(&[Some(1514764800000), None, Some(1550636625000)]).to(DataType::Date64); - - let result = minute(&array).unwrap(); - let expected = UInt32Array::from(&[Some(0), None, Some(23)]); - assert_eq!(result, expected); +fn temporal_minute() { + for data_type in TestData::available_time_like_types() { + let data = TestData::data(&data_type); + let result = minute(&*data.input).unwrap(); + + assert_eq!( + result, + data.minute.unwrap(), + "\"hour\" failed on type: {:?}", + data_type + ); + } } #[test] -fn date64_hour() { - let array = - Int64Array::from(&[Some(1514764800000), None, Some(1550636625000)]).to(DataType::Date64); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(0), None, Some(4)]); - assert_eq!(result, expected); +fn temporal_second() { + for data_type in TestData::available_time_like_types() { + let data = TestData::data(&data_type); + let result = second(&*data.input).unwrap(); + + assert_eq!( + result, + data.second.unwrap(), + "\"second\" failed on type: {:?}", + data_type + ); + } } #[test] -fn date32_hour() { - let array = Int32Array::from(&[Some(15147), None, Some(15148)]).to(DataType::Date32); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(0), None, Some(0)]); - assert_eq!(result, expected); +fn temporal_nanosecond() { + for data_type in TestData::available_time_like_types() { + let data = TestData::data(&data_type); + let result = nanosecond(&*data.input).unwrap(); + + assert_eq!( + result, + data.nanosecond.unwrap(), + "\"nanosecond\" failed on type: {:?}", + data_type + ); + } } #[test] -fn time32_second_hour() { - let array = Int32Array::from(&[Some(37800), None]).to(DataType::Time32(TimeUnit::Second)); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(10), None]); - assert_eq!(result, expected); +fn temporal_year() { + for data_type in TestData::available_date_like_types() { + let data = TestData::data(&data_type); + let result = year(&*data.input).unwrap(); + + assert_eq!( + result, + data.year.unwrap(), + "\"year\" failed on type: {:?}", + data_type + ); + } } #[test] -fn time64_micro_hour() { - let array = - Int64Array::from(&[Some(37800000000), None]).to(DataType::Time64(TimeUnit::Microsecond)); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(10), None]); - assert_eq!(result, expected); +fn temporal_month() { + for data_type in TestData::available_date_like_types() { + let data = TestData::data(&data_type); + let result = month(&*data.input).unwrap(); + + assert_eq!( + result, + data.month.unwrap(), + "\"month\" failed on type: {:?}", + data_type + ); + } } #[test] -fn naive_timestamp_micro_hour() { - let array = Int64Array::from(&[Some(37800000000), None]) - .to(DataType::Timestamp(TimeUnit::Microsecond, None)); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(10), None]); - assert_eq!(result, expected); +fn temporal_day() { + for data_type in TestData::available_date_like_types() { + let data = TestData::data(&data_type); + let result = day(&*data.input).unwrap(); + + assert_eq!( + result, + data.day.unwrap(), + "\"day\" failed on type: {:?}", + data_type + ); + } } #[test] -fn date64_weekday() { - let array = Int64Array::from(&[Some(1514764800000), None, Some(86400000)]).to(DataType::Date64); - - let result = weekday(&array).unwrap(); - let expected = UInt32Array::from(&[Some(1), None, Some(5)]); - assert_eq!(result, expected); +fn temporal_weekday() { + for data_type in TestData::available_date_like_types() { + let data = TestData::data(&data_type); + let result = weekday(&*data.input).unwrap(); + + assert_eq!( + result, + data.weekday.unwrap(), + "\"weekday\" failed on type: {:?}", + data_type + ); + } } #[test] -fn date64_iso_week() { - let array = Int64Array::from(&[ - Some(1514764800000), - None, - Some(1515456000000), - Some(1514678400000), - ]) - .to(DataType::Date64); - - let result = iso_week(&array).unwrap(); - let expected = UInt32Array::from(&[Some(1), None, Some(2), Some(52)]); - assert_eq!(result, expected); +fn temporal_iso_week() { + for data_type in TestData::available_date_like_types() { + let data = TestData::data(&data_type); + let result = iso_week(&*data.input).unwrap(); + + assert_eq!( + result, + data.iso_week.unwrap(), + "\"iso_week\" failed on type: {:?}", + data_type + ); + } } -#[test] -fn date64_year() { - let array = Int64Array::from(&[Some(1514764800000), None]).to(DataType::Date64); - - let result = year(&array).unwrap(); - let expected = Int32Array::from(&[Some(2018), None]); - assert_eq!(result, expected); +struct TestData { + input: Box, + year: Option, + month: Option, + day: Option, + weekday: Option, + iso_week: Option, + hour: Option, + minute: Option, + second: Option, + nanosecond: Option, } -#[test] -fn naive_timestamp_date32_year() { - let array = Int32Array::from(&[Some(15147), None]).to(DataType::Date32); - - let result = year(&array).unwrap(); - let expected = Int32Array::from(&[Some(2011), None]); - assert_eq!(result, expected); -} - -#[test] -fn naive_timestamp_micro_year() { - let array = Int64Array::from(&[Some(1612025847000000), None]) - .to(DataType::Timestamp(TimeUnit::Microsecond, None)); - - let result = year(&array).unwrap(); - let expected = Int32Array::from(&[Some(2021), None]); - assert_eq!(result, expected); -} - -#[test] -fn date64_month() { - let array = Int64Array::from(&[Some(1514764800000), None]).to(DataType::Date64); - let result = month(&array).unwrap(); - - let expected = UInt32Array::from(&[Some(1), None]); - - assert_eq!(result, expected); -} - -#[test] -fn date64_day() { - let array = Int64Array::from(&[Some(1614764800000), None]).to(DataType::Date64); - let result = day(&array).unwrap(); - - let expected = UInt32Array::from(&[Some(3), None]); - - assert_eq!(result, expected); -} - -#[test] -fn timestamp_micro_hour() { - let array = Int64Array::from(&[Some(1621877130000000), None]).to(DataType::Timestamp( - TimeUnit::Microsecond, - Some("+01:00".to_string()), - )); - - let result = hour(&array).unwrap(); - let expected = UInt32Array::from(&[Some(18), None]); - assert_eq!(result, expected); +impl TestData { + fn data(data_type: &DataType) -> TestData { + match data_type { + DataType::Date64 => TestData { + input: Box::new( + Int64Array::from(&[Some(1514764800000), None, Some(1550636625000)]) + .to(data_type.clone()), + ), + year: Some(Int32Array::from(&[Some(2018), None, Some(2019)])), + month: Some(UInt32Array::from(&[Some(1), None, Some(2)])), + day: Some(UInt32Array::from(&[Some(1), None, Some(20)])), + weekday: Some(UInt32Array::from(&[Some(1), None, Some(3)])), + iso_week: Some(UInt32Array::from(&[Some(1), None, Some(8)])), + hour: Some(UInt32Array::from(&[Some(0), None, Some(4)])), + minute: Some(UInt32Array::from(&[Some(0), None, Some(23)])), + second: Some(UInt32Array::from(&[Some(0), None, Some(45)])), + nanosecond: Some(UInt32Array::from(&[Some(0), None, Some(0)])), + }, + DataType::Date32 => TestData { + input: Box::new(Int32Array::from(&[Some(15147), None]).to(data_type.clone())), + year: Some(Int32Array::from(&[Some(2011), None])), + month: Some(UInt32Array::from(&[Some(6), None])), + day: Some(UInt32Array::from(&[Some(22), None])), + weekday: Some(UInt32Array::from(&[Some(3), None])), + iso_week: Some(UInt32Array::from(&[Some(25), None])), + hour: Some(UInt32Array::from(&[Some(0), None])), + minute: Some(UInt32Array::from(&[Some(0), None])), + second: Some(UInt32Array::from(&[Some(0), None])), + nanosecond: Some(UInt32Array::from(&[Some(0), None])), + }, + DataType::Time32(TimeUnit::Second) => TestData { + input: Box::new(Int32Array::from(&[Some(37800), None]).to(data_type.clone())), + year: None, + month: None, + day: None, + weekday: None, + iso_week: None, + hour: Some(UInt32Array::from(&[Some(10), None])), + minute: Some(UInt32Array::from(&[Some(30), None])), + second: Some(UInt32Array::from(&[Some(0), None])), + nanosecond: Some(UInt32Array::from(&[Some(0), None])), + }, + DataType::Time64(TimeUnit::Microsecond) => TestData { + input: Box::new(Int64Array::from(&[Some(378000000), None]).to(data_type.clone())), + year: None, + month: None, + day: None, + weekday: None, + iso_week: None, + hour: Some(UInt32Array::from(&[Some(0), None])), + minute: Some(UInt32Array::from(&[Some(6), None])), + second: Some(UInt32Array::from(&[Some(18), None])), + nanosecond: Some(UInt32Array::from(&[Some(0), None])), + }, + DataType::Timestamp(TimeUnit::Microsecond, None) => TestData { + input: Box::new( + Int64Array::from(&[Some(1612025847000000), None]).to(data_type.clone()), + ), + year: Some(Int32Array::from(&[Some(2021), None])), + month: Some(UInt32Array::from(&[Some(1), None])), + day: Some(UInt32Array::from(&[Some(30), None])), + weekday: Some(UInt32Array::from(&[Some(6), None])), + iso_week: Some(UInt32Array::from(&[Some(4), None])), + hour: Some(UInt32Array::from(&[Some(16), None])), + minute: Some(UInt32Array::from(&[Some(57), None])), + second: Some(UInt32Array::from(&[Some(27), None])), + nanosecond: Some(UInt32Array::from(&[Some(0), None])), + }, + DataType::Timestamp(TimeUnit::Microsecond, Some(_)) => TestData { + // NOTE We hardcode the timezone as an offset, we ignore + // the zone sent through `data_type` + input: Box::new(Int64Array::from(&[Some(1621877130000000), None]).to( + DataType::Timestamp(TimeUnit::Microsecond, Some("+01:00".to_string())), + )), + year: Some(Int32Array::from(&[Some(2021), None])), + month: Some(UInt32Array::from(&[Some(5), None])), + day: Some(UInt32Array::from(&[Some(24), None])), + weekday: Some(UInt32Array::from(&[Some(1), None])), + iso_week: Some(UInt32Array::from(&[Some(21), None])), + hour: Some(UInt32Array::from(&[Some(18), None])), + minute: Some(UInt32Array::from(&[Some(25), None])), + second: Some(UInt32Array::from(&[Some(30), None])), + nanosecond: Some(UInt32Array::from(&[Some(0), None])), + }, + _ => todo!(), + } + } + + fn available_time_like_types() -> Vec { + vec![ + DataType::Date32, + DataType::Date64, + DataType::Time32(TimeUnit::Second), + DataType::Time64(TimeUnit::Microsecond), + DataType::Timestamp(TimeUnit::Microsecond, None), + // NOTE The timezone value will be ignored + DataType::Timestamp(TimeUnit::Microsecond, Some("+01:00".to_string())), + ] + } + + fn available_date_like_types() -> Vec { + vec![ + DataType::Date32, + DataType::Date64, + DataType::Timestamp(TimeUnit::Microsecond, None), + // NOTE The timezone value will be ignored + DataType::Timestamp(TimeUnit::Microsecond, Some("+01:00".to_string())), + ] + } } #[cfg(feature = "chrono-tz")]