use rstest::*; use steel_decimal::*; // Basic Arithmetic Tests #[rstest] #[case("1.5", "2.3", "3.8")] #[case("10", "5", "15")] #[case("-5.5", "3.2", "-2.3")] #[case("0", "42", "42")] fn test_decimal_add(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_add(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("10", "3", "7")] #[case("5.5", "2.2", "3.3")] #[case("0", "5", "-5")] #[case("-3", "-2", "-1")] fn test_decimal_sub(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_sub(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("2", "3", "6")] #[case("2.5", "4", "10")] #[case("-2", "3", "-6")] #[case("0", "100", "0")] fn test_decimal_mul(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_mul(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("10", "2", "5")] #[case("15", "3", "5")] #[case("7.5", "2.5", "3")] fn test_decimal_div(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_div(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] fn test_decimal_div_by_zero() { let result = decimal_div("10".to_string(), "0".to_string()); assert!(result.is_err()); assert!(result.unwrap_err().contains("Division by zero")); } // Advanced Math Tests #[rstest] #[case("2", "3", "8")] #[case("5", "2", "25")] #[case("10", "0", "1")] fn test_decimal_pow(#[case] base: &str, #[case] exp: &str, #[case] expected: &str) { let result = decimal_pow(base.to_string(), exp.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("16", "4")] #[case("25", "5")] #[case("9", "3")] fn test_decimal_sqrt(#[case] input: &str, #[case] expected: &str) { let result = decimal_sqrt(input.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] fn test_decimal_sqrt_negative() { let result = decimal_sqrt("-4".to_string()); assert!(result.is_err()); assert!(result.unwrap_err().contains("Square root failed")); } // Comparison Tests #[rstest] #[case("5", "3", true)] #[case("3", "5", false)] #[case("5", "5", false)] fn test_decimal_gt(#[case] a: &str, #[case] b: &str, #[case] expected: bool) { let result = decimal_gt(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("3", "5", true)] #[case("5", "3", false)] #[case("5", "5", false)] fn test_decimal_lt(#[case] a: &str, #[case] b: &str, #[case] expected: bool) { let result = decimal_lt(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("5", "5", true)] #[case("5", "3", false)] #[case("3.14", "3.14", true)] fn test_decimal_eq(#[case] a: &str, #[case] b: &str, #[case] expected: bool) { let result = decimal_eq(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("5", "3", true)] #[case("3", "5", false)] #[case("5", "5", true)] fn test_decimal_gte(#[case] a: &str, #[case] b: &str, #[case] expected: bool) { let result = decimal_gte(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("3", "5", true)] #[case("5", "3", false)] #[case("5", "5", true)] fn test_decimal_lte(#[case] a: &str, #[case] b: &str, #[case] expected: bool) { let result = decimal_lte(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } // Utility Tests #[rstest] #[case("-5", "5")] #[case("3.14", "3.14")] #[case("-0", "0")] fn test_decimal_abs(#[case] input: &str, #[case] expected: &str) { let result = decimal_abs(input.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("3", "5", "3")] #[case("10", "7", "7")] #[case("-5", "-2", "-5")] fn test_decimal_min(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_min(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("3", "5", "5")] #[case("10", "7", "10")] #[case("-5", "-2", "-2")] fn test_decimal_max(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_max(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("3.14159", 2, "3.14")] #[case("2.71828", 3, "2.718")] #[case("10.999", 0, "11")] fn test_decimal_round(#[case] input: &str, #[case] places: i32, #[case] expected: &str) { let result = decimal_round(input.to_string(), places).unwrap(); assert_eq!(result, expected); } // Constants Tests #[rstest] fn test_decimal_constants() { assert_eq!(decimal_zero(), "0"); assert_eq!(decimal_one(), "1"); assert!(decimal_pi().starts_with("3.14159")); assert!(decimal_e().starts_with("2.71828")); } // Financial Functions Tests #[rstest] #[case("100", "15", "15")] #[case("1000", "5.5", "55")] #[case("250", "20", "50")] fn test_decimal_percentage(#[case] amount: &str, #[case] percentage: &str, #[case] expected: &str) { let result = decimal_percentage(amount.to_string(), percentage.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] #[case("1000", "0.05", "1", "1050")] #[case("1000", "0.1", "2", "1210")] fn test_decimal_compound(#[case] principal: &str, #[case] rate: &str, #[case] time: &str, #[case] expected: &str) { let result = decimal_compound(principal.to_string(), rate.to_string(), time.to_string()).unwrap(); assert_eq!(result, expected); } // Type Conversion Tests #[rstest] #[case("123.456", "123.456")] #[case("42", "42")] #[case("0.001", "0.001")] fn test_to_decimal(#[case] input: &str, #[case] expected: &str) { let result = to_decimal(input.to_string()).unwrap(); assert_eq!(result, expected); } #[rstest] fn test_to_decimal_invalid() { let result = to_decimal("not_a_number".to_string()); assert!(result.is_err()); assert!(result.unwrap_err().contains("Invalid decimal")); } // Error Handling Tests #[rstest] #[case("invalid", "2")] #[case("1", "invalid")] #[case("abc", "def")] fn test_decimal_add_invalid_input(#[case] a: &str, #[case] b: &str) { let result = decimal_add(a.to_string(), b.to_string()); assert!(result.is_err()); } #[rstest] #[case("invalid")] #[case("not_a_number")] #[case("abc")] fn test_decimal_sqrt_invalid_input(#[case] input: &str) { let result = decimal_sqrt(input.to_string()); assert!(result.is_err()); } // Edge Cases #[rstest] #[case("0.000000001", "0.000000001", "0.000000002")] #[case("999999999999999", "1", "1000000000000000")] fn test_decimal_precision_edge_cases(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_add(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); } // Test scientific notation #[rstest] #[case("1e2", "2e1", "120")] #[case("1.5e2", "2.3e1", "173")] fn test_scientific_notation(#[case] a: &str, #[case] b: &str, #[case] expected: &str) { let result = decimal_add(a.to_string(), b.to_string()).unwrap(); assert_eq!(result, expected); }