percent.rs (1779B)
1 mod common; 2 3 use core::str::FromStr; 4 5 use radroots_core::{Decimal, Percent, decimal, money, percent::ParseError}; 6 7 #[test] 8 fn checked_ratio_paths_report_overflow_and_roundtrip() { 9 assert_eq!( 10 Percent::try_from_ratio(Decimal::MAX), 11 Err(decimal::Error::ArithmeticOverflow) 12 ); 13 for ratio in ["-0.125", "0", "0.5", "1", "2.75"] { 14 let ratio = common::dec(ratio); 15 let percent = Percent::try_from_ratio(ratio).unwrap(); 16 assert_eq!(percent.try_to_ratio().unwrap(), ratio); 17 } 18 } 19 20 #[test] 21 fn parsing_and_accessors_preserve_signed_values() { 22 let percent = Percent::from_str("12.5%").unwrap(); 23 assert_eq!(percent.value(), common::dec("12.5")); 24 assert_eq!(Percent::from_str(" 12.5 ").unwrap(), percent); 25 assert_eq!(Percent::from_str("nope"), Err(ParseError::InvalidNumber)); 26 } 27 28 #[test] 29 fn checked_money_calculation_and_quantization_are_deterministic() { 30 let base = common::money("20.00", "USD"); 31 let percent = Percent::from_str("10").unwrap(); 32 assert_eq!( 33 percent.try_of_money(&base).unwrap().amount(), 34 common::dec("2") 35 ); 36 37 let tiny = common::money("0.05", "USD"); 38 assert_eq!( 39 percent.try_of_money_quantized(&tiny).unwrap().amount(), 40 common::dec("0.01") 41 ); 42 43 let max = radroots_core::Money::try_new(Decimal::MAX, radroots_core::Currency::USD).unwrap(); 44 let two_hundred = Percent::new(common::dec("200")); 45 assert_eq!( 46 two_hundred.try_of_money(&max), 47 Err(money::Error::ArithmeticOverflow) 48 ); 49 } 50 51 #[test] 52 fn display_and_parse_error_messages_are_stable() { 53 assert_eq!(Percent::from_str("12.5%").unwrap().to_string(), "12.5%"); 54 assert_eq!( 55 ParseError::InvalidNumber.to_string(), 56 "invalid percent string" 57 ); 58 }