]>
Commit | Line | Data |
---|---|---|
676146fd DC |
1 | use anyhow::bail; |
2 | ||
3 | use super::*; | |
4 | ||
5 | fn test_event(v: &'static str) -> Result<(), Error> { | |
6 | match parse_calendar_event(v) { | |
7 | Ok(event) => println!("CalendarEvent '{}' => {:?}", v, event), | |
8 | Err(err) => bail!("parsing '{}' failed - {}", v, err), | |
9 | } | |
10 | ||
11 | Ok(()) | |
12 | } | |
13 | ||
14 | const fn make_test_time(mday: i32, hour: i32, min: i32) -> i64 { | |
15 | (mday * 3600 * 24 + hour * 3600 + min * 60) as i64 | |
16 | } | |
17 | ||
18 | #[test] | |
19 | fn test_compute_next_event() -> Result<(), Error> { | |
20 | let test_value = |v: &'static str, last: i64, expect: i64| -> Result<i64, Error> { | |
21 | let event = match parse_calendar_event(v) { | |
22 | Ok(event) => event, | |
23 | Err(err) => bail!("parsing '{}' failed - {}", v, err), | |
24 | }; | |
25 | ||
a96e9fb7 | 26 | match event.compute_next_event(last, true) { |
676146fd DC |
27 | Ok(Some(next)) => { |
28 | if next == expect { | |
29 | println!("next {:?} => {}", event, next); | |
30 | } else { | |
31 | bail!( | |
32 | "next {:?} failed\nnext: {:?}\nexpect: {:?}", | |
33 | event, | |
34 | crate::gmtime(next), | |
35 | crate::gmtime(expect), | |
36 | ); | |
37 | } | |
38 | } | |
39 | Ok(None) => bail!("next {:?} failed to find a timestamp", event), | |
40 | Err(err) => bail!("compute next for '{}' failed - {}", v, err), | |
41 | } | |
42 | ||
43 | Ok(expect) | |
44 | }; | |
45 | ||
46 | let test_never = |v: &'static str, last: i64| -> Result<(), Error> { | |
47 | let event = match parse_calendar_event(v) { | |
48 | Ok(event) => event, | |
49 | Err(err) => bail!("parsing '{}' failed - {}", v, err), | |
50 | }; | |
51 | ||
a96e9fb7 | 52 | match event.compute_next_event(last, true)? { |
676146fd DC |
53 | None => Ok(()), |
54 | Some(next) => bail!( | |
55 | "compute next for '{}' succeeded, but expected fail - result {}", | |
56 | v, | |
57 | next | |
58 | ), | |
59 | } | |
60 | }; | |
61 | ||
62 | const MIN: i64 = 60; | |
63 | const HOUR: i64 = 3600; | |
64 | const DAY: i64 = 3600 * 24; | |
65 | ||
66 | const THURSDAY_00_00: i64 = make_test_time(0, 0, 0); | |
67 | const THURSDAY_15_00: i64 = make_test_time(0, 15, 0); | |
68 | ||
69 | const JUL_31_2020: i64 = 1596153600; // Friday, 2020-07-31 00:00:00 | |
70 | const DEC_31_2020: i64 = 1609372800; // Thursday, 2020-12-31 00:00:00 | |
71 | ||
72 | // minute only syntax | |
73 | test_value("0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?; | |
74 | test_value("*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?; | |
75 | ||
76 | test_value("*:0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?; | |
77 | test_value("*:*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?; | |
78 | test_value("*:*:*", THURSDAY_00_00, THURSDAY_00_00 + 1)?; | |
79 | test_value("*:3:5", THURSDAY_00_00, THURSDAY_00_00 + 3 * MIN + 5)?; | |
80 | ||
81 | test_value("mon *:*", THURSDAY_00_00, THURSDAY_00_00 + 4 * DAY)?; | |
82 | test_value( | |
83 | "mon 2:*", | |
84 | THURSDAY_00_00, | |
85 | THURSDAY_00_00 + 4 * DAY + 2 * HOUR, | |
86 | )?; | |
87 | test_value( | |
88 | "mon 2:50", | |
89 | THURSDAY_00_00, | |
90 | THURSDAY_00_00 + 4 * DAY + 2 * HOUR + 50 * MIN, | |
91 | )?; | |
92 | ||
93 | test_value("tue", THURSDAY_00_00, THURSDAY_00_00 + 5 * DAY)?; | |
94 | test_value("wed", THURSDAY_00_00, THURSDAY_00_00 + 6 * DAY)?; | |
95 | test_value("thu", THURSDAY_00_00, THURSDAY_00_00 + 7 * DAY)?; | |
96 | test_value("fri", THURSDAY_00_00, THURSDAY_00_00 + 1 * DAY)?; | |
97 | test_value("sat", THURSDAY_00_00, THURSDAY_00_00 + 2 * DAY)?; | |
98 | test_value("sun", THURSDAY_00_00, THURSDAY_00_00 + 3 * DAY)?; | |
99 | ||
100 | // test repeated ranges | |
101 | test_value("4..10/2:0", THURSDAY_00_00, THURSDAY_00_00 + 4 * HOUR)?; | |
102 | test_value( | |
103 | "4..10/2:0", | |
104 | THURSDAY_00_00 + 5 * HOUR, | |
105 | THURSDAY_00_00 + 6 * HOUR, | |
106 | )?; | |
107 | test_value( | |
108 | "4..10/2:0", | |
109 | THURSDAY_00_00 + 11 * HOUR, | |
110 | THURSDAY_00_00 + 1 * DAY + 4 * HOUR, | |
111 | )?; | |
112 | ||
113 | // test multiple values for a single field | |
114 | // and test that the order does not matter | |
115 | test_value( | |
116 | "5,10:4,8", | |
117 | THURSDAY_00_00, | |
118 | THURSDAY_00_00 + 5 * HOUR + 4 * MIN, | |
119 | )?; | |
120 | test_value( | |
121 | "10,5:8,4", | |
122 | THURSDAY_00_00, | |
123 | THURSDAY_00_00 + 5 * HOUR + 4 * MIN, | |
124 | )?; | |
125 | test_value( | |
126 | "6,4..10:23,5/5", | |
127 | THURSDAY_00_00, | |
128 | THURSDAY_00_00 + 4 * HOUR + 5 * MIN, | |
129 | )?; | |
130 | test_value( | |
131 | "4..10,6:5/5,23", | |
132 | THURSDAY_00_00, | |
133 | THURSDAY_00_00 + 4 * HOUR + 5 * MIN, | |
134 | )?; | |
135 | ||
136 | // test month wrapping | |
137 | test_value("sat", JUL_31_2020, JUL_31_2020 + 1 * DAY)?; | |
138 | test_value("sun", JUL_31_2020, JUL_31_2020 + 2 * DAY)?; | |
139 | test_value("mon", JUL_31_2020, JUL_31_2020 + 3 * DAY)?; | |
140 | test_value("tue", JUL_31_2020, JUL_31_2020 + 4 * DAY)?; | |
141 | test_value("wed", JUL_31_2020, JUL_31_2020 + 5 * DAY)?; | |
142 | test_value("thu", JUL_31_2020, JUL_31_2020 + 6 * DAY)?; | |
143 | test_value("fri", JUL_31_2020, JUL_31_2020 + 7 * DAY)?; | |
144 | ||
145 | // test year wrapping | |
146 | test_value("fri", DEC_31_2020, DEC_31_2020 + 1 * DAY)?; | |
147 | test_value("sat", DEC_31_2020, DEC_31_2020 + 2 * DAY)?; | |
148 | test_value("sun", DEC_31_2020, DEC_31_2020 + 3 * DAY)?; | |
149 | test_value("mon", DEC_31_2020, DEC_31_2020 + 4 * DAY)?; | |
150 | test_value("tue", DEC_31_2020, DEC_31_2020 + 5 * DAY)?; | |
151 | test_value("wed", DEC_31_2020, DEC_31_2020 + 6 * DAY)?; | |
152 | test_value("thu", DEC_31_2020, DEC_31_2020 + 7 * DAY)?; | |
153 | ||
154 | test_value("daily", THURSDAY_00_00, THURSDAY_00_00 + DAY)?; | |
155 | test_value("daily", THURSDAY_00_00 + 1, THURSDAY_00_00 + DAY)?; | |
156 | ||
157 | let n = test_value("5/2:0", THURSDAY_00_00, THURSDAY_00_00 + 5 * HOUR)?; | |
158 | let n = test_value("5/2:0", n, THURSDAY_00_00 + 7 * HOUR)?; | |
159 | let n = test_value("5/2:0", n, THURSDAY_00_00 + 9 * HOUR)?; | |
160 | test_value("5/2:0", n, THURSDAY_00_00 + 11 * HOUR)?; | |
161 | ||
162 | let mut n = test_value("*:*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?; | |
163 | for i in 2..100 { | |
164 | n = test_value("*:*", n, THURSDAY_00_00 + i * MIN)?; | |
165 | } | |
166 | ||
167 | let mut n = test_value("*:0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?; | |
168 | for i in 2..100 { | |
169 | n = test_value("*:0", n, THURSDAY_00_00 + i * HOUR)?; | |
170 | } | |
171 | ||
172 | let mut n = test_value("1:0", THURSDAY_15_00, THURSDAY_00_00 + DAY + HOUR)?; | |
173 | for i in 2..100 { | |
174 | n = test_value("1:0", n, THURSDAY_00_00 + i * DAY + HOUR)?; | |
175 | } | |
176 | ||
177 | // test date functionality | |
178 | ||
179 | test_value("2020-07-31", 0, JUL_31_2020)?; | |
180 | test_value("02-28", 0, (31 + 27) * DAY)?; | |
181 | test_value("02-29", 0, 2 * 365 * DAY + (31 + 28) * DAY)?; // 1972-02-29 | |
182 | test_value("1965/5-01-01", -1, THURSDAY_00_00)?; | |
183 | test_value("2020-7..9-2/2", JUL_31_2020, JUL_31_2020 + 2 * DAY)?; | |
184 | test_value("2020,2021-12-31", JUL_31_2020, DEC_31_2020)?; | |
185 | ||
186 | test_value("monthly", 0, 31 * DAY)?; | |
187 | test_value("quarterly", 0, (31 + 28 + 31) * DAY)?; | |
188 | test_value("semiannually", 0, (31 + 28 + 31 + 30 + 31 + 30) * DAY)?; | |
189 | test_value("yearly", 0, (365) * DAY)?; | |
190 | ||
191 | test_never("2021-02-29", 0)?; | |
192 | test_never("02-30", 0)?; | |
193 | ||
194 | Ok(()) | |
195 | } | |
196 | ||
197 | #[test] | |
198 | fn test_calendar_event_weekday() -> Result<(), Error> { | |
199 | test_event("mon,wed..fri")?; | |
200 | test_event("fri..mon")?; | |
201 | ||
202 | test_event("mon")?; | |
203 | test_event("MON")?; | |
204 | test_event("monDay")?; | |
205 | test_event("tue")?; | |
206 | test_event("Tuesday")?; | |
207 | test_event("wed")?; | |
208 | test_event("wednesday")?; | |
209 | test_event("thu")?; | |
210 | test_event("thursday")?; | |
211 | test_event("fri")?; | |
212 | test_event("friday")?; | |
213 | test_event("sat")?; | |
214 | test_event("saturday")?; | |
215 | test_event("sun")?; | |
216 | test_event("sunday")?; | |
217 | ||
218 | test_event("mon..fri")?; | |
219 | test_event("mon,tue,fri")?; | |
220 | test_event("mon,tue..wednesday,fri..sat")?; | |
221 | ||
222 | Ok(()) | |
223 | } | |
224 | ||
225 | #[test] | |
226 | fn test_time_span_parser() -> Result<(), Error> { | |
227 | let test_value = |ts_str: &str, expect: f64| -> Result<(), Error> { | |
228 | let ts = parse_time_span(ts_str)?; | |
229 | assert_eq!(f64::from(ts), expect, "{}", ts_str); | |
230 | Ok(()) | |
231 | }; | |
232 | ||
233 | test_value("2", 2.0)?; | |
234 | test_value("2s", 2.0)?; | |
235 | test_value("2sec", 2.0)?; | |
236 | test_value("2second", 2.0)?; | |
237 | test_value("2seconds", 2.0)?; | |
238 | ||
239 | test_value(" 2s 2 s 2", 6.0)?; | |
240 | ||
241 | test_value("1msec 1ms", 0.002)?; | |
242 | test_value("1usec 1us 1µs", 0.000_003)?; | |
243 | test_value("1nsec 1ns", 0.000_000_002)?; | |
244 | test_value("1minutes 1minute 1min 1m", 4.0 * 60.0)?; | |
245 | test_value("1hours 1hour 1hr 1h", 4.0 * 3600.0)?; | |
246 | test_value("1days 1day 1d", 3.0 * 86400.0)?; | |
247 | test_value("1weeks 1 week 1w", 3.0 * 86400.0 * 7.0)?; | |
248 | test_value("1months 1month 1M", 3.0 * 86400.0 * 30.44)?; | |
249 | test_value("1years 1year 1y", 3.0 * 86400.0 * 365.25)?; | |
250 | ||
251 | test_value("2h", 7200.0)?; | |
252 | test_value(" 2 h", 7200.0)?; | |
253 | test_value("2hours", 7200.0)?; | |
254 | test_value("48hr", 48.0 * 3600.0)?; | |
255 | test_value( | |
256 | "1y 12month", | |
257 | 365.25 * 24.0 * 3600.0 + 12.0 * 30.44 * 24.0 * 3600.0, | |
258 | )?; | |
259 | test_value("55s500ms", 55.5)?; | |
260 | test_value("300ms20s 5day", 5.0 * 24.0 * 3600.0 + 20.0 + 0.3)?; | |
261 | ||
262 | Ok(()) | |
263 | } |