1#![deny(missing_docs)]
30
31pub use polars;
33
34pub use plotkit_core::series::{IntoCategories, IntoSeries, Series};
36
37#[cfg(test)]
42mod tests {
43 use plotkit_core::series::IntoCategories;
44 use plotkit_core::series::IntoSeries as PlotIntoSeries;
45 use polars::prelude::{
46 DataType, Float64Chunked, IntoSeries as PolarsIntoSeries, NamedFrom, Series,
47 StringChunked,
48 };
49
50 #[test]
53 fn series_from_polars_f64() {
54 let s = Series::new("a".into(), &[1.0_f64, 2.5, 3.0]);
55 let ps = PlotIntoSeries::into_series(&s);
56 assert_eq!(ps.data, vec![1.0, 2.5, 3.0]);
57 }
58
59 #[test]
60 fn series_from_polars_f64_owned() {
61 let s = Series::new("a".into(), &[4.0_f64, 5.0]);
62 let ps = PlotIntoSeries::into_series(s);
63 assert_eq!(ps.data, vec![4.0, 5.0]);
64 }
65
66 #[test]
69 fn series_from_polars_f32() {
70 let s = Series::new("b".into(), &[1.5_f32, 2.5]);
71 let ps = PlotIntoSeries::into_series(&s);
72 assert_eq!(ps.data, vec![1.5_f64, 2.5]);
73 }
74
75 #[test]
78 fn series_from_polars_i32() {
79 let s = Series::new("c".into(), &[10_i32, 20, 30]);
80 let ps = PlotIntoSeries::into_series(&s);
81 assert_eq!(ps.data, vec![10.0, 20.0, 30.0]);
82 }
83
84 #[test]
87 fn series_from_polars_i64() {
88 let s = Series::new("d".into(), &[100_i64, 200]);
89 let ps = PlotIntoSeries::into_series(&s);
90 assert_eq!(ps.data, vec![100.0, 200.0]);
91 }
92
93 #[test]
96 fn series_from_polars_u32() {
97 let s = Series::new("e".into(), &[1_u32, 2, 3]);
98 let ps = PlotIntoSeries::into_series(&s);
99 assert_eq!(ps.data, vec![1.0, 2.0, 3.0]);
100 }
101
102 #[test]
105 fn series_from_polars_u64() {
106 let s = Series::new("f".into(), &[42_u64, 99]);
107 let ps = PlotIntoSeries::into_series(&s);
108 assert_eq!(ps.data, vec![42.0, 99.0]);
109 }
110
111 #[test]
114 fn series_null_values_become_nan() {
115 let ca = Float64Chunked::new("g".into(), &[Some(1.0), None, Some(3.0)]);
116 let s: Series = PolarsIntoSeries::into_series(ca);
117 let ps = PlotIntoSeries::into_series(&s);
118 assert_eq!(ps.data.len(), 3);
119 assert_eq!(ps.data[0], 1.0);
120 assert!(ps.data[1].is_nan());
121 assert_eq!(ps.data[2], 3.0);
122 }
123
124 #[test]
127 fn series_empty_polars() {
128 let s = Series::new_empty("empty".into(), &DataType::Float64);
129 let ps = PlotIntoSeries::into_series(&s);
130 assert!(ps.is_empty());
131 }
132
133 #[test]
136 fn categories_from_polars_str() {
137 let s = Series::new("labels".into(), &["foo", "bar", "baz"]);
138 let cats = IntoCategories::into_categories(&s);
139 assert_eq!(cats.labels, vec!["foo", "bar", "baz"]);
140 }
141
142 #[test]
143 fn categories_null_becomes_null_string() {
144 let ca = StringChunked::new("h".into(), &[Some("a"), None, Some("c")]);
145 let s: Series = PolarsIntoSeries::into_series(ca);
146 let cats = IntoCategories::into_categories(&s);
147 assert_eq!(cats.labels, vec!["a", "null", "c"]);
148 }
149
150 #[test]
151 fn categories_empty_polars() {
152 let s = Series::new_empty("empty".into(), &DataType::String);
153 let cats = IntoCategories::into_categories(&s);
154 assert!(cats.is_empty());
155 }
156
157 #[test]
160 fn series_string_cast_produces_nan() {
161 let s = Series::new("bad".into(), &["not", "numeric"]);
163 let ps = PlotIntoSeries::into_series(&s);
164 assert_eq!(ps.data.len(), 2);
165 assert!(ps.data[0].is_nan());
166 assert!(ps.data[1].is_nan());
167 }
168
169 #[test]
170 #[should_panic(expected = "is not a string type")]
171 fn categories_panics_on_numeric_dtype() {
172 let s = Series::new("bad".into(), &[1.0_f64, 2.0]);
173 let _ = IntoCategories::into_categories(&s);
174 }
175}