use uninum::{Number, num};
#[test]
fn arithmetic_with_mixed_borrowing_patterns() {
let number = Number::from(10u64);
let primitive: u64 = 5;
let number_ref = &number;
let primitive_ref = &primitive;
let twenty = Number::from(20u64);
let twenty_ref = &twenty;
let ten = Number::from(10u64);
let ten_ref = &ten;
assert_eq!(number.clone() + primitive, Number::from(15u64));
assert_eq!(number.clone() + primitive_ref, Number::from(15u64));
assert_eq!(number_ref + primitive, Number::from(15u64));
assert_eq!(number_ref + primitive_ref, Number::from(15u64));
assert_eq!(primitive + number.clone(), Number::from(15u64));
assert_eq!(primitive + number_ref, Number::from(15u64));
assert_eq!(primitive_ref + number.clone(), Number::from(15u64));
assert_eq!(primitive_ref + number_ref, Number::from(15u64));
assert_eq!(twenty.clone() - primitive, Number::from(15u64));
assert_eq!(twenty.clone() - primitive_ref, Number::from(15u64));
assert_eq!(twenty_ref - primitive, Number::from(15u64));
assert_eq!(twenty_ref - primitive_ref, Number::from(15u64));
assert_eq!(primitive - number.clone(), Number::from(-5i64));
assert_eq!(primitive - number_ref, Number::from(-5i64));
assert_eq!(primitive_ref - number.clone(), Number::from(-5i64));
assert_eq!(primitive_ref - ten_ref, Number::from(-5i64));
}
#[test]
fn multiplication_with_mixed_borrowing_patterns() {
let number = Number::from(3i64);
let primitive: i32 = 4;
let number_ref = &number;
let primitive_ref = &primitive;
assert_eq!(number.clone() * primitive, Number::from(12i64));
assert_eq!(number.clone() * primitive_ref, Number::from(12i64));
assert_eq!(number_ref * primitive, Number::from(12i64));
assert_eq!(number_ref * primitive_ref, Number::from(12i64));
assert_eq!(primitive * number.clone(), Number::from(12i64));
assert_eq!(primitive * number_ref, Number::from(12i64));
assert_eq!(primitive_ref * number.clone(), Number::from(12i64));
assert_eq!(primitive_ref * number_ref, Number::from(12i64));
}
#[test]
fn division_with_mixed_borrowing_patterns() {
let number = Number::from(20i64);
let primitive: i64 = 5;
let float_number = Number::from(10.0f64);
let float_primitive = 2.5f64;
let number_ref = &number;
let primitive_ref = &primitive;
let float_number_ref = &float_number;
let float_primitive_ref = &float_primitive;
assert_eq!(number.clone() / primitive, Number::from(4i64));
assert_eq!(number.clone() / primitive_ref, Number::from(4i64));
assert_eq!(number_ref / primitive, Number::from(4i64));
assert_eq!(number_ref / primitive_ref, Number::from(4i64));
for quotient in [
primitive / number.clone(),
primitive / number_ref,
primitive_ref / number.clone(),
primitive_ref / number_ref,
] {
#[cfg(feature = "decimal")]
if let Some(decimal) = quotient.try_get_decimal() {
assert_eq!(decimal.to_string(), "0.25");
continue;
}
if let Some(f64_value) = quotient.try_get_f64() {
assert!((f64_value - 0.25).abs() < 1e-12);
} else {
panic!("expected quotient to be representable as Decimal or F64");
}
}
let float_expected = Number::from(4.0);
assert_eq!(float_number.clone() / float_primitive, float_expected);
assert_eq!(float_number.clone() / float_primitive_ref, float_expected);
assert_eq!(float_number_ref / float_primitive, float_expected);
assert_eq!(float_number_ref / float_primitive_ref, float_expected);
let reciprocal = float_primitive / float_number.clone();
#[cfg(feature = "decimal")]
assert!(reciprocal.try_get_decimal().is_some() || reciprocal.try_get_f64().is_some());
#[cfg(not(feature = "decimal"))]
assert!(reciprocal.try_get_f64().is_some());
let reciprocal_ref = float_primitive_ref / float_number_ref;
#[cfg(feature = "decimal")]
assert!(reciprocal_ref.try_get_decimal().is_some() || reciprocal_ref.try_get_f64().is_some());
#[cfg(not(feature = "decimal"))]
assert!(reciprocal_ref.try_get_f64().is_some());
}
#[test]
fn remainder_with_mixed_borrowing_patterns() {
let number = Number::from(17i64);
let primitive: i64 = 5;
let number_ref = &number;
let primitive_ref = &primitive;
assert_eq!(number.clone() % primitive, Number::from(2i64));
assert_eq!(number.clone() % primitive_ref, Number::from(2i64));
assert_eq!(number_ref % primitive, Number::from(2i64));
assert_eq!(number_ref % primitive_ref, Number::from(2i64));
assert_eq!(primitive % number.clone(), Number::from(5i64));
assert_eq!(primitive % number_ref, Number::from(5i64));
assert_eq!(primitive_ref % number.clone(), Number::from(5i64));
assert_eq!(primitive_ref % number_ref, Number::from(5i64));
}
#[test]
fn comparison_between_numbers_and_primitives() {
let number = Number::from(42u64);
let primitive: u64 = 42;
let number_ref = &number;
assert_eq!(number, primitive);
assert_eq!(primitive, number);
assert_eq!(number_ref, primitive);
assert_eq!(primitive, number_ref);
let other = Number::from(100u64);
let other_ref = &other;
assert!(number < 100u64);
assert!(primitive < other);
assert!(number_ref < 100u64);
assert!(primitive < other_ref);
}
#[test]
fn float_operations_cover_reference_paths() {
let number = num!(2.5);
let primitive = 2.0f64;
let number_ref = &number;
let primitive_ref = &primitive;
assert_eq!(number.clone() * primitive, Number::from(5.0));
assert_eq!(number_ref * primitive, Number::from(5.0));
assert_eq!(primitive * number.clone(), Number::from(5.0));
assert_eq!(primitive * number_ref, Number::from(5.0));
assert_eq!(primitive_ref * number.clone(), Number::from(5.0));
assert_eq!(primitive_ref * number_ref, Number::from(5.0));
}