slack_messaging/blocks/data_visualization/charts/
data_series.rs1use super::DataPoint;
2
3use crate::validators::*;
4
5use serde::Serialize;
6use slack_messaging_derive::Builder;
7
8#[derive(Debug, Clone, Serialize, PartialEq, Builder)]
60pub struct DataSeries {
61 #[builder(validate("required", "text::max_20"))]
62 pub(crate) name: Option<String>,
63
64 #[builder(
65 push_item = "data_point",
66 validate("required", "list::not_empty", "list::max_item_20")
67 )]
68 pub(crate) data: Option<Vec<DataPoint>>,
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::errors::*;
75
76 #[test]
77 fn it_implements_builder() {
78 let expected = DataSeries {
79 name: Some("Sales".to_string()),
80 data: Some(vec![
81 point("Mon", 200),
82 point("Tue", 120),
83 point("Wed", 180),
84 point("Thu", 50),
85 point("Fri", 300),
86 ]),
87 };
88
89 let series = DataSeries::builder()
90 .set_name(Some("Sales"))
91 .set_data(Some(vec![
92 point("Mon", 200),
93 point("Tue", 120),
94 point("Wed", 180),
95 point("Thu", 50),
96 point("Fri", 300),
97 ]))
98 .build()
99 .unwrap();
100
101 assert_eq!(series, expected);
102
103 let series = DataSeries::builder()
104 .name("Sales")
105 .data(vec![
106 point("Mon", 200),
107 point("Tue", 120),
108 point("Wed", 180),
109 point("Thu", 50),
110 point("Fri", 300),
111 ])
112 .build()
113 .unwrap();
114
115 assert_eq!(series, expected);
116 }
117
118 #[test]
119 fn it_implements_push_item_method() {
120 let expected = DataSeries {
121 name: Some("Sales".to_string()),
122 data: Some(vec![
123 point("Mon", 200),
124 point("Tue", 120),
125 ]),
126 };
127
128 let series = DataSeries::builder()
129 .name("Sales")
130 .data_point(point("Mon", 200))
131 .data_point(point("Tue", 120))
132 .build()
133 .unwrap();
134
135 assert_eq!(series, expected);
136 }
137
138 #[test]
139 fn it_requires_name_field() {
140 let err = DataSeries::builder()
141 .data(vec![point("Mon", 200)])
142 .build()
143 .unwrap_err();
144 assert_eq!(err.object(), "DataSeries");
145
146 let errors = err.field("name");
147 assert!(errors.includes(ValidationErrorKind::Required));
148 }
149
150 #[test]
151 fn it_requires_name_field_less_than_20_characters_long() {
152 let err = DataSeries::builder()
153 .name("a".repeat(21))
154 .data(vec![point("Mon", 200)])
155 .build()
156 .unwrap_err();
157 assert_eq!(err.object(), "DataSeries");
158
159 let errors = err.field("name");
160 assert!(errors.includes(ValidationErrorKind::MaxTextLength(20)));
161 }
162
163 #[test]
164 fn it_requires_data_field() {
165 let err = DataSeries::builder()
166 .name("Sales")
167 .build()
168 .unwrap_err();
169 assert_eq!(err.object(), "DataSeries");
170
171 let errors = err.field("data");
172 assert!(errors.includes(ValidationErrorKind::Required));
173 }
174
175 #[test]
176 fn it_requires_data_field_with_min_1_item() {
177 let err = DataSeries::builder()
178 .name("Sales")
179 .data(vec![] as Vec<DataPoint>)
180 .build()
181 .unwrap_err();
182 assert_eq!(err.object(), "DataSeries");
183
184 let errors = err.field("data");
185 assert!(errors.includes(ValidationErrorKind::EmptyArray));
186 }
187
188 #[test]
189 fn it_requires_data_field_with_max_20_items() {
190 let err = DataSeries::builder()
191 .name("Sales")
192 .data(vec![point("Mon", 200); 21])
193 .build()
194 .unwrap_err();
195 assert_eq!(err.object(), "DataSeries");
196
197 let errors = err.field("data");
198 assert!(errors.includes(ValidationErrorKind::MaxArraySize(20)));
199 }
200
201 fn point(label: &str, value: i32) -> DataPoint {
202 (label, value).try_into().unwrap()
203 }
204}