use miv::*; #[test] fn valid_numbers_are_parsed_correctly() { assert_valid_num("I", 1); assert_valid_num("II", 2); assert_valid_num("III", 3); assert_valid_num("IV", 4); assert_valid_num("V", 5); assert_valid_num("VI", 6); assert_valid_num("VII", 7); assert_valid_num("VIII", 8); assert_valid_num("IX", 9); assert_valid_num("X", 10); assert_valid_num("XVII", 17); assert_valid_num("XXXIV", 34); assert_valid_num("XXXIX", 39); assert_valid_num("XL", 40); assert_valid_num("XLIX", 49); assert_valid_num("L", 50); assert_valid_num("LXXIX", 79); assert_valid_num("XC", 90); assert_valid_num("XCV", 95); assert_valid_num("C", 100); assert_valid_num("CXV", 115); assert_valid_num("CLII", 152); assert_valid_num("CXCVII", 197); assert_valid_num("CCLIX", 259); assert_valid_num("CD", 400); assert_valid_num("CDLXXVII", 477); assert_valid_num("D", 500); assert_valid_num("DCCCLI", 851); assert_valid_num("CM", 900); assert_valid_num("CMIX", 909); assert_valid_num("M", 1000); assert_valid_num("MMCDXXI", 2421); assert_valid_num("MMMCMXCIX", 3999); } #[test] fn non_roman_strings_are_invalid() { assert_empty_string(""); assert_invalid_character("aaa"); assert_invalid_character("hello"); assert_invalid_character("xii"); assert_invalid_character("іваіллуш"); assert_invalid_character("QXUI"); assert_invalid_character("KDE"); } #[test] fn smaller_numbers_cannot_precede_larger_ones() { assert_invalid_sequence("XXCD"); assert_invalid_sequence("IIVX"); assert_invalid_sequence("VX"); assert_invalid_sequence("VXII"); assert_invalid_sequence("VXII"); } #[test] fn some_numbers_are_not_allowed_to_come_one_after_the_other(){ assert_invalid_sequence("VV"); assert_invalid_sequence("IXIX"); assert_invalid_sequence("IVIV"); assert_invalid_sequence("XCXC"); assert_invalid_sequence("XCL"); assert_invalid_sequence("LXLVII"); assert_invalid_sequence("DCDV"); assert_invalid_sequence("CXXIXV"); assert_invalid_sequence("IVI"); assert_invalid_sequence("IXIV"); assert_invalid_sequence("XCXVI"); assert_invalid_sequence("VIV"); assert_invalid_sequence("DCD"); assert_invalid_sequence("CMD"); assert_invalid_sequence("CDC"); assert_invalid_sequence("XCL"); } #[test] fn over_three_same_numbers_in_a_row_are_invalid() { assert_too_many_repetitions("MMMDXXXXXXX"); assert_too_many_repetitions("VIIII"); assert_too_many_repetitions("CCCC"); } #[test] fn numbers_are_converted_into_valid_roman_strings() { assert_string_from_number(2, "II"); assert_string_from_number(5, "V"); assert_string_from_number(9, "IX"); assert_string_from_number(15, "XV"); assert_string_from_number(19, "XIX"); assert_string_from_number(37, "XXXVII"); assert_string_from_number(40, "XL"); assert_string_from_number(53, "LIII"); assert_string_from_number(60, "LX"); assert_string_from_number(99, "XCIX"); assert_string_from_number(128, "CXXVIII"); } #[test] fn roman_struct_cannot_be_constructed_from_zero() { assert_error(Roman::from_integer(0), Error::NumberZero); } #[test] fn the_largest_valid_number_is_3999() { let roman = Roman::from_integer(3999); assert!(roman.is_ok()); assert_error(Roman::from_integer(4000), Error::NumberTooLarge); } fn assert_invalid_sequence(s: &str) { let res = Roman::from_string(s); assert!(res.is_err()); assert!({ if let Error::InvalidSequence(_, _) = res.unwrap_err() { true } else { false } }); } fn assert_too_many_repetitions(s: &str) { assert_error(Roman::from_string(s), Error::TooManyRepetitions); } fn assert_empty_string(s: &str) { assert_error(Roman::from_string(s), Error::EmptyString); } fn assert_invalid_character(s: &str) { let res = Roman::from_string(s); assert!(res.is_err()); assert!({ if let Error::InvalidCharacter(_) = res.unwrap_err() { true } else { false } }); } fn assert_valid_num(s: &str, value: u16) { assert_eq!(Roman::from_string(s).unwrap().as_int(), value); } fn assert_string_from_number(n: u16, value: &str) { let result = Roman::from_integer(n); assert!(result.is_ok()); let roman_string = result.unwrap().as_string(); assert_eq!(roman_string, String::from(value)); } fn assert_error(res: Result, err: Error) { assert!(res.is_err()); assert_eq!(res.unwrap_err(), err); }