From a0673f410f16305ad27774538900ec2be6255704 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Sun, 30 Jan 2022 15:16:41 -0500 Subject: [PATCH] Move parse tests to parse module --- src/lib.rs | 104 --------------------------------------------------- src/parse.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 104 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 819dee9..ce7f7e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,107 +28,3 @@ impl FromStr for CronEntry { parse::parse_entry(entry) } } - -#[cfg(test)] -mod tests { - use super::*; - use std::mem; - use test_case::test_case; - use CronSpecifier::{Any, Range, Several, Specifically}; - - // simple parse checks - #[test_case("* * * * *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] - #[test_case("0 4 * * *", &CronEntry{minute: Specifically(0), hour: Specifically(4), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] - #[test_case("0 4 10 5 4", &CronEntry{minute: Specifically(0), hour: Specifically(4), day_of_month: Specifically(10), month: Specifically(5), day_of_week: Specifically(4)})] - #[test_case("* * 10 5 *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Specifically(10), month: Specifically(5), day_of_week: Any(None)})] - #[test_case("* * * * 7", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Specifically(0)}; "sunday can be seven")] - #[test_case("* 4-6 * * *", &CronEntry{minute: Any(None), hour: Range(4, 6, None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] - #[test_case("* * * * mon-wed", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Range(1, 3, None)})] - #[test_case("* * * * mon-5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Range(1, 5, None)})] - #[test_case("* * * jan-jun *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Range(1, 6, None), day_of_week: Any(None)})] - #[test_case("* * * 1,5 *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Several(vec![Specifically(1), Specifically(5)]), day_of_week: Any(None)})] - #[test_case("* * * * 1,5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Specifically(1), Specifically(5)])})] - #[test_case("* * * * mon-wed,1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Range(1, 3, None), Specifically(1)])})] - #[test_case("* * * * mon-wed,1,3-5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Range(1, 3, None), Specifically(1), Range(3, 5, None)])})] - #[test_case("*/10 * * * *", &CronEntry{minute: Any(Some(10)), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] - #[test_case("* */2 * * SUN", &CronEntry{minute: Any(None), hour: Any(Some(2)), day_of_month: Any(None), month: Any(None), day_of_week: Specifically(0)})] - // days of week - #[test_case("* * * 1 mon", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(1)})] - #[test_case("* * * 2 MON", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(1)})] - #[test_case("* * * 1 tue", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(2)})] - #[test_case("* * * 2 TUE", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(2)})] - #[test_case("* * * 1 wed", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(3)})] - #[test_case("* * * 2 WED", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(3)})] - #[test_case("* * * 1 thu", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(4)})] - #[test_case("* * * 2 THU", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(4)})] - #[test_case("* * * 1 fri", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(5)})] - #[test_case("* * * 2 FRI", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(5)})] - #[test_case("* * * 1 sat", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(6)})] - #[test_case("* * * 2 SAT", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(6)})] - #[test_case("* * * 1 sun", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(0)})] - #[test_case("* * * 2 SUN", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(0)})] - // months - #[test_case("* * * jan 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(0)})] - #[test_case("* * * JAN 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(1)})] - #[test_case("* * * feb 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(0)})] - #[test_case("* * * FEB 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(1)})] - #[test_case("* * * mar 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(3), day_of_week: Specifically(0)})] - #[test_case("* * * MAR 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(3), day_of_week: Specifically(1)})] - #[test_case("* * * apr 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(4), day_of_week: Specifically(0)})] - #[test_case("* * * APR 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(4), day_of_week: Specifically(1)})] - #[test_case("* * * may 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(5), day_of_week: Specifically(0)})] - #[test_case("* * * MAY 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(5), day_of_week: Specifically(1)})] - #[test_case("* * * jun 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(6), day_of_week: Specifically(0)})] - #[test_case("* * * JUN 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(6), day_of_week: Specifically(1)})] - #[test_case("* * * jul 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(7), day_of_week: Specifically(0)})] - #[test_case("* * * JUL 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(7), day_of_week: Specifically(1)})] - #[test_case("* * * aug 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(8), day_of_week: Specifically(0)})] - #[test_case("* * * AUG 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(8), day_of_week: Specifically(1)})] - #[test_case("* * * sep 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(9), day_of_week: Specifically(0)})] - #[test_case("* * * SEP 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(9), day_of_week: Specifically(1)})] - #[test_case("* * * oct 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(10), day_of_week: Specifically(0)})] - #[test_case("* * * OCT 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(10), day_of_week: Specifically(1)})] - #[test_case("* * * nov 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(11), day_of_week: Specifically(0)})] - #[test_case("* * * NOV 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(11), day_of_week: Specifically(1)})] - #[test_case("* * * dec 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(12), day_of_week: Specifically(0)})] - #[test_case("* * * DEC 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(12), day_of_week: Specifically(1)})] - fn test_successful_parse(to_parse: &str, expected: &CronEntry) { - let parse_res = CronEntry::from_str(to_parse); - - match parse_res { - Ok(parsed_entry) => assert_eq!(expected, &parsed_entry), - Err(err) => panic!("Got error: '{}'", err), - } - } - - #[test_case("1 2 3 4 5 6 7", &parse::Error::ExtraData("Extra data found".to_string()))] - #[test_case("* * * *", &parse::Error::NotEnoughData)] - #[test_case("* * * * a", &parse::Error::InvalidSpecifier("Parsing a letter isn't gonna work".to_string()))] - #[test_case("100 * * * *", &parse::Error::InvalidMinute(100))] - #[test_case("* * 35 * *", &parse::Error::InvalidDayOfMonth(35))] - #[test_case("* * * 13 *", &parse::Error::InvalidMonth(13))] - #[test_case("* * * * 8", &parse::Error::InvalidDayOfWeek(8))] - // TODO: Could these errors be better? They're a bit of a result of an implementation detail - #[test_case("* * * * blargh", &parse::Error::InvalidSpecifier("we don't know how to parse this day!".to_string()))] - #[test_case("* * * blargh *", &parse::Error::InvalidSpecifier("we don't know how to parse this month!".to_string()))] - #[test_case("* * * * 3-1", &parse::Error::FlippedRange(3, 1))] - #[test_case("* * * * 3-*", &parse::Error::ExtraData("* doesn't make sense here".to_string()))] - #[test_case("* * * * *-4", &parse::Error::ExtraData("* doesn't make sense here".to_string()))] - #[test_case("* * * 100,5 *", &parse::Error::InvalidMonth(100))] - #[test_case("* * 1,* * *", &parse::Error::InvalidSpecifier("* isn't known here".to_string()))] - #[test_case("* * *,2 * *", &parse::Error::InvalidSpecifier("* isn't known here".to_string()))] - #[test_case("* * * 3,*,4 *", &parse::Error::InvalidSpecifier("* isn't known here".to_string()))] - fn test_failed_parse(to_parse: &str, expected_error: &parse::Error) { - let parse_res = CronEntry::from_str(to_parse); - match parse_res { - Ok(_) => panic!("Parsing unexpectedly succeeded"), - Err(err) => assert_eq!( - mem::discriminant(expected_error), - mem::discriminant(&err), - "Expected error '{}', got '{}'", - expected_error, - err - ), - } - } -} diff --git a/src/parse.rs b/src/parse.rs index d328ef2..123f89b 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -227,3 +227,107 @@ where Ok((remaining, res_tuple)) } } + +#[cfg(test)] +mod tests { + use super::*; + use std::mem; + use test_case::test_case; + use CronSpecifier::{Any, Range, Several, Specifically}; + + // simple parse checks + #[test_case("* * * * *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] + #[test_case("0 4 * * *", &CronEntry{minute: Specifically(0), hour: Specifically(4), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] + #[test_case("0 4 10 5 4", &CronEntry{minute: Specifically(0), hour: Specifically(4), day_of_month: Specifically(10), month: Specifically(5), day_of_week: Specifically(4)})] + #[test_case("* * 10 5 *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Specifically(10), month: Specifically(5), day_of_week: Any(None)})] + #[test_case("* * * * 7", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Specifically(0)}; "sunday can be seven")] + #[test_case("* 4-6 * * *", &CronEntry{minute: Any(None), hour: Range(4, 6, None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] + #[test_case("* * * * mon-wed", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Range(1, 3, None)})] + #[test_case("* * * * mon-5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Range(1, 5, None)})] + #[test_case("* * * jan-jun *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Range(1, 6, None), day_of_week: Any(None)})] + #[test_case("* * * 1,5 *", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Several(vec![Specifically(1), Specifically(5)]), day_of_week: Any(None)})] + #[test_case("* * * * 1,5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Specifically(1), Specifically(5)])})] + #[test_case("* * * * mon-wed,1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Range(1, 3, None), Specifically(1)])})] + #[test_case("* * * * mon-wed,1,3-5", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Several(vec![Range(1, 3, None), Specifically(1), Range(3, 5, None)])})] + #[test_case("*/10 * * * *", &CronEntry{minute: Any(Some(10)), hour: Any(None), day_of_month: Any(None), month: Any(None), day_of_week: Any(None)})] + #[test_case("* */2 * * SUN", &CronEntry{minute: Any(None), hour: Any(Some(2)), day_of_month: Any(None), month: Any(None), day_of_week: Specifically(0)})] + // days of week + #[test_case("* * * 1 mon", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(1)})] + #[test_case("* * * 2 MON", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(1)})] + #[test_case("* * * 1 tue", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(2)})] + #[test_case("* * * 2 TUE", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(2)})] + #[test_case("* * * 1 wed", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(3)})] + #[test_case("* * * 2 WED", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(3)})] + #[test_case("* * * 1 thu", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(4)})] + #[test_case("* * * 2 THU", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(4)})] + #[test_case("* * * 1 fri", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(5)})] + #[test_case("* * * 2 FRI", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(5)})] + #[test_case("* * * 1 sat", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(6)})] + #[test_case("* * * 2 SAT", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(6)})] + #[test_case("* * * 1 sun", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(0)})] + #[test_case("* * * 2 SUN", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(0)})] + // months + #[test_case("* * * jan 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(0)})] + #[test_case("* * * JAN 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(1), day_of_week: Specifically(1)})] + #[test_case("* * * feb 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(0)})] + #[test_case("* * * FEB 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(2), day_of_week: Specifically(1)})] + #[test_case("* * * mar 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(3), day_of_week: Specifically(0)})] + #[test_case("* * * MAR 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(3), day_of_week: Specifically(1)})] + #[test_case("* * * apr 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(4), day_of_week: Specifically(0)})] + #[test_case("* * * APR 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(4), day_of_week: Specifically(1)})] + #[test_case("* * * may 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(5), day_of_week: Specifically(0)})] + #[test_case("* * * MAY 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(5), day_of_week: Specifically(1)})] + #[test_case("* * * jun 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(6), day_of_week: Specifically(0)})] + #[test_case("* * * JUN 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(6), day_of_week: Specifically(1)})] + #[test_case("* * * jul 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(7), day_of_week: Specifically(0)})] + #[test_case("* * * JUL 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(7), day_of_week: Specifically(1)})] + #[test_case("* * * aug 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(8), day_of_week: Specifically(0)})] + #[test_case("* * * AUG 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(8), day_of_week: Specifically(1)})] + #[test_case("* * * sep 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(9), day_of_week: Specifically(0)})] + #[test_case("* * * SEP 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(9), day_of_week: Specifically(1)})] + #[test_case("* * * oct 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(10), day_of_week: Specifically(0)})] + #[test_case("* * * OCT 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(10), day_of_week: Specifically(1)})] + #[test_case("* * * nov 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(11), day_of_week: Specifically(0)})] + #[test_case("* * * NOV 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(11), day_of_week: Specifically(1)})] + #[test_case("* * * dec 0", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(12), day_of_week: Specifically(0)})] + #[test_case("* * * DEC 1", &CronEntry{minute: Any(None), hour: Any(None), day_of_month: Any(None), month: Specifically(12), day_of_week: Specifically(1)})] + fn test_successful_parse(to_parse: &str, expected: &CronEntry) { + let parse_res = parse_entry(to_parse); + + match parse_res { + Ok(parsed_entry) => assert_eq!(expected, &parsed_entry), + Err(err) => panic!("Got error: '{}'", err), + } + } + + #[test_case("1 2 3 4 5 6 7", &Error::ExtraData("Extra data found".to_string()))] + #[test_case("* * * *", &Error::NotEnoughData)] + #[test_case("* * * * a", &Error::InvalidSpecifier("Parsing a letter isn't gonna work".to_string()))] + #[test_case("100 * * * *", &Error::InvalidMinute(100))] + #[test_case("* * 35 * *", &Error::InvalidDayOfMonth(35))] + #[test_case("* * * 13 *", &Error::InvalidMonth(13))] + #[test_case("* * * * 8", &Error::InvalidDayOfWeek(8))] + // TODO: Could these errors be better? They're a bit of a result of an implementation detail + #[test_case("* * * * blargh", &Error::InvalidSpecifier("we don't know how to parse this day!".to_string()))] + #[test_case("* * * blargh *", &Error::InvalidSpecifier("we don't know how to parse this month!".to_string()))] + #[test_case("* * * * 3-1", &Error::FlippedRange(3, 1))] + #[test_case("* * * * 3-*", &Error::ExtraData("* doesn't make sense here".to_string()))] + #[test_case("* * * * *-4", &Error::ExtraData("* doesn't make sense here".to_string()))] + #[test_case("* * * 100,5 *", &Error::InvalidMonth(100))] + #[test_case("* * 1,* * *", &Error::InvalidSpecifier("* isn't known here".to_string()))] + #[test_case("* * *,2 * *", &Error::InvalidSpecifier("* isn't known here".to_string()))] + #[test_case("* * * 3,*,4 *", &Error::InvalidSpecifier("* isn't known here".to_string()))] + fn test_failed_parse(to_parse: &str, expected_error: &Error) { + let parse_res = parse_entry(to_parse); + match parse_res { + Ok(_) => panic!("Parsing unexpectedly succeeded"), + Err(err) => assert_eq!( + mem::discriminant(expected_error), + mem::discriminant(&err), + "Expected error '{}', got '{}'", + expected_error, + err + ), + } + } +}