// file: crates/ksp-offchain-transport-lib/unit_tests/decimal.rs // version: 1 #[test] fn decimal_normalizes_fractional_and_scientific_forms_without_f64() -> ksp_core_lib::Result<()> { let cases = [ ("123.4500", "123.45", 12_345_u128, 2_u8), ("1.2345e2", "123.45", 12_345, 2), ("12345e-2", "123.45", 12_345, 2), ("1e3", "1000", 1_000, 0), ("1e-3", "0.001", 1, 3), ]; for (source, expected, coefficient, scale) in cases { let value = match crate::PriceDecimal::parse(source) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; assert_eq!(value.to_canonical_string(), expected); assert_eq!(value.coefficient(), coefficient); assert_eq!(value.scale(), scale); } return std::result::Result::Ok(()); } #[test] fn decimal_rejects_zero_negative_nonfinite_excessive_scale_and_overflow() { let invalid = ["0", "0.000", "-1", "+1", "NaN", "inf", "1e-19", "1e129", "340282366920938463463374607431768211456", " 1", "1 ", ".1", "1."]; for source in invalid { let result = crate::PriceDecimal::parse(source); assert!(result.is_err()); if let std::result::Result::Err(error) = result { assert_eq!(error.code(), crate::ERROR_CODE_PRICE_DECIMAL_INVALID); } } } #[test] fn decimal_serde_is_canonical_string_and_round_trips_exactly() -> ksp_core_lib::Result<()> { let value = match crate::PriceDecimal::parse("123.4500") { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let encoded = match serde_json::to_string(&value) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => { return std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_PRICE_DECIMAL_INVALID, "test serialization failed")); }, }; assert_eq!(encoded, "\"123.45\""); let decoded: crate::PriceDecimal = match serde_json::from_str(encoded.as_str()) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => { return std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_PRICE_DECIMAL_INVALID, "test deserialization failed")); }, }; assert_eq!(decoded, value); assert!(serde_json::from_str::("123.45").is_err()); return std::result::Result::Ok(()); }