#[cfg(feature = "decimal")]
use std::str::FromStr;
use uninum::{Number, num};
fn generate_test_numbers() -> Vec<Number> {
let numbers = vec![
Number::from(-100i64),
Number::from(-10i64),
Number::from(-1i64),
Number::from(0i64),
Number::from(1i64),
Number::from(10i64),
Number::from(100i64),
Number::from(42u64),
Number::from(42u64),
Number::from(42i64),
Number::from(42i64),
Number::from(u64::from(u32::MAX)),
Number::from(i64::from(i32::MIN)),
Number::from(i64::from(i32::MAX)),
Number::from(u64::MAX),
Number::from(i64::MIN),
Number::from(i64::MAX),
num!(-100.5f64),
num!(-1.5f64),
num!(0.0f64),
num!(-0.0f64),
num!(1.5f64),
num!(100.5f64),
num!(-100.5f64),
num!(-1.5f64),
num!(0.0f64),
num!(-0.0f64),
num!(1.5f64),
num!(100.5f64),
num!(f64::NEG_INFINITY),
num!(f64::INFINITY),
num!(f64::NAN),
num!(f64::NEG_INFINITY),
num!(f64::INFINITY),
num!(f64::NAN),
num!(42.0f64),
num!(42.0f64),
];
#[cfg(feature = "decimal")]
let numbers = {
use rust_decimal::Decimal;
let mut numbers = numbers;
numbers.extend([
Number::from(Decimal::new(-100, 0)),
Number::from(Decimal::new(-1, 0)),
Number::from(Decimal::new(0, 0)),
Number::from(Decimal::new(1, 0)),
Number::from(Decimal::new(42, 0)),
Number::from(Decimal::new(100, 0)),
Number::from(Decimal::new(314159, 5)), ]);
numbers
};
numbers
}
#[test]
fn test_ordering_reflexive_property() {
let numbers = generate_test_numbers();
for a in &numbers {
assert!(
a <= a,
"Reflexive property violated: {a:?} should be <= {a:?}"
);
}
}
#[test]
fn test_ordering_antisymmetric_property() {
let numbers = generate_test_numbers();
for a in &numbers {
for b in &numbers {
if a <= b && b <= a {
assert_eq!(
a, b,
"Antisymmetric property violated: {a:?} <= {b:?} and {b:?} <= {a:?} but {a:?} \
!= {b:?}"
);
}
}
}
}
#[test]
fn test_ordering_transitive_property() {
let numbers = generate_test_numbers();
for a in &numbers {
for b in &numbers {
for c in &numbers {
if a <= b && b <= c {
assert!(
a <= c,
"Transitive property violated: {a:?} <= {b:?} and {b:?} <= {c:?} but \
{a:?} > {c:?}"
);
}
}
}
}
}
#[test]
fn test_ordering_total_property() {
let numbers = generate_test_numbers();
for a in &numbers {
for b in &numbers {
assert!(
a <= b || b <= a,
"Total ordering violated: neither {a:?} <= {b:?} nor {b:?} <= {a:?} is true"
);
}
}
}
#[test]
fn test_ordering_consistency_with_equality() {
let numbers = generate_test_numbers();
for a in &numbers {
for b in &numbers {
if a == b {
assert!(
a <= b,
"Consistency with equality violated: {a:?} == {b:?} but {a:?} > {b:?}"
);
assert!(
b <= a,
"Consistency with equality violated: {a:?} == {b:?} but {b:?} > {a:?}"
);
}
}
}
}
#[test]
fn test_strict_ordering_properties() {
let numbers = generate_test_numbers();
for a in &numbers {
for b in &numbers {
if a < b {
assert_ne!(
a, b,
"Strict ordering violated: {a:?} < {b:?} but {a:?} == {b:?}"
);
assert!(
a <= b,
"Strict ordering violated: {a:?} < {b:?} but {a:?} > {b:?}"
);
}
if a > b {
assert_ne!(
a, b,
"Strict ordering violated: {a:?} > {b:?} but {a:?} == {b:?}"
);
assert!(
a >= b,
"Strict ordering violated: {a:?} > {b:?} but {a:?} < {b:?}"
);
}
}
}
}
#[test]
fn test_ordering_normalizes_nan_and_signed_zero() {
let nan = num!(f64::NAN);
let normal = Number::from(1u64);
use std::cmp::Ordering;
assert_eq!(nan.partial_cmp(&nan), Some(Ordering::Equal));
assert_eq!(nan.partial_cmp(&normal), Some(Ordering::Greater));
assert_eq!(normal.partial_cmp(&nan), Some(Ordering::Less));
assert_eq!(nan.partial_cmp(&f64::NAN), Some(Ordering::Equal));
assert_eq!(nan.partial_cmp(&0i64), Some(Ordering::Greater));
let pos_zero = num!(0.0f64);
let neg_zero = num!(-0.0f64);
assert_eq!(pos_zero.cmp(&neg_zero), Ordering::Equal);
assert_eq!(pos_zero.partial_cmp(&-0.0f64), Some(Ordering::Equal));
assert_eq!(neg_zero.partial_cmp(&0i64), Some(Ordering::Equal));
}
#[test]
fn test_cross_type_ordering_consistency() {
let test_cases = vec![
(Number::from(42u64), Number::from(42i64)),
(Number::from(42u64), num!(42.0f64)),
(Number::from(42i64), num!(42.0f64)),
(Number::from(0u64), Number::from(0i64)),
(num!(0.0f64), num!(-0.0f64)),
(Number::from(10u64), Number::from(20u64)),
(Number::from(-10i64), Number::from(10u64)),
(num!(3.16f64), num!(3.15f64)),
];
for (a, b) in test_cases {
if a == b {
assert!(
a <= b && b <= a,
"Equal cross-type values should have consistent ordering: {a:?} and {b:?}"
);
} else {
assert!(
a < b || b < a,
"Different cross-type values should have consistent strict ordering: {a:?} and \
{b:?}"
);
}
}
}
#[test]
fn test_special_value_ordering() {
let nan = num!(f64::NAN);
let pos_inf = num!(f64::INFINITY);
let neg_inf = num!(f64::NEG_INFINITY);
let normal = num!(1.0f64);
let zero = num!(0.0f64);
assert!(
nan > normal,
"NaN should be ordered greater than normal values"
);
assert!(
nan > pos_inf,
"NaN should be ordered greater than positive infinity"
);
assert!(
nan > neg_inf,
"NaN should be ordered greater than negative infinity"
);
assert!(nan > zero, "NaN should be ordered greater than zero");
assert_eq!(nan, nan, "NaN should equal itself");
assert!(nan <= nan, "NaN should be <= itself");
assert!(nan >= nan, "NaN should be >= itself");
assert!(
neg_inf < normal,
"Negative infinity should be less than normal values"
);
assert!(
normal < pos_inf,
"Normal values should be less than positive infinity"
);
assert!(
neg_inf < pos_inf,
"Negative infinity should be less than positive infinity"
);
assert!(neg_inf < zero, "Negative infinity should be less than zero");
assert!(zero < pos_inf, "Zero should be less than positive infinity");
let nan_f64_2 = num!(f64::NAN);
let pos_inf_f64_2 = num!(f64::INFINITY);
let neg_inf_f64_2 = num!(f64::NEG_INFINITY);
assert_eq!(nan, nan_f64_2, "NaN values should be equal to each other");
assert_eq!(
pos_inf, pos_inf_f64_2,
"Positive infinity should be equal to itself"
);
assert_eq!(
neg_inf, neg_inf_f64_2,
"Negative infinity should be equal to itself"
);
}
#[test]
fn test_zero_ordering_consistency() {
let zero_values = vec![
Number::from(0u64),
Number::from(0i64),
Number::from(0u64),
Number::from(0i64),
num!(0.0f64),
num!(-0.0f64),
num!(0.0f64),
num!(-0.0f64),
];
#[cfg(feature = "decimal")]
let zero_values = {
use rust_decimal::Decimal;
let mut zero_values = zero_values;
zero_values.push(Number::from(Decimal::new(0, 0)));
zero_values
};
for a in &zero_values {
for b in &zero_values {
assert_eq!(a, b, "All zero values should be equal: {a:?} and {b:?}");
assert!(
a <= b,
"All zero values should be <= each other: {a:?} and {b:?}"
);
assert!(
a >= b,
"All zero values should be >= each other: {a:?} and {b:?}"
);
}
}
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_ordering_respects_exact_value() {
use rust_decimal::Decimal;
use std::cmp::Ordering;
let a = Number::from(Decimal::from_str("0.1000000000000000000000000000").unwrap());
let b = Number::from(Decimal::from_str("0.1000000000000000000000000001").unwrap());
assert_ne!(
a, b,
"Decimal equality should distinguish nearby fractional values"
);
assert_ne!(
a.cmp(&b),
Ordering::Equal,
"Decimal ordering should distinguish nearby fractional values"
);
}
#[test]
fn test_large_number_ordering() {
let _large_numbers = [
Number::from(u64::MAX),
Number::from(u64::MAX - 1),
Number::from(i64::MAX),
Number::from(i64::MAX - 1),
num!(u64::MAX as f64),
num!((u64::MAX - 1) as f64),
];
let a_u = Number::from(u64::MAX - 1);
let b_u = Number::from(u64::MAX);
assert!(a_u < b_u);
let a_i = Number::from(i64::MAX - 1);
let b_i = Number::from(i64::MAX);
assert!(a_i < b_i);
let large_u64 = Number::from((i64::MAX as u64) + 1);
let max_i64 = Number::from(i64::MAX);
assert!(
max_i64 < large_u64,
"i64::MAX should be less than (i64::MAX + 1) as u64"
);
}
#[test]
fn test_ordering_with_primitives() {
let num = Number::from(42i64);
assert!(num > 40);
assert!(num < 50);
assert!(num >= 42);
assert!(num <= 42);
assert!(40 < num);
assert!(50 > num);
assert!(42 <= num);
assert!(42 >= num);
}
#[test]
fn test_ordering_with_references_and_primitives() {
let num = Number::from(42i64);
let num_ref = #
assert!(num_ref > 40i32);
assert!(num_ref < 50i32);
assert!(num_ref >= 42i32);
assert!(num_ref <= 42i32);
assert!(40i32 < num_ref);
assert!(50i32 > num_ref);
assert!(42i32 <= num_ref);
assert!(42i32 >= num_ref);
let float_num = num!(3.16f64);
let float_ref = &float_num;
assert!(float_ref > 3.0f64);
assert!(float_ref < 4.0f64);
assert!(3.0f64 < float_ref);
assert!(4.0f64 > float_ref);
let u32_num = Number::from(100u64);
let u32_ref = &u32_num;
assert!(u32_ref > 99i32);
assert!(u32_ref < 101i32);
assert!(99i32 < u32_ref);
assert!(101i32 > u32_ref);
}
#[test]
fn test_reference_ordering_comprehensive() {
let num_u32 = Number::from(42u64);
let smaller_u32 = 40u32;
let larger_u32 = 50u32;
let num_u32_ref = &num_u32;
let smaller_u32_ref = &smaller_u32;
let larger_u32_ref = &larger_u32;
assert!(
num_u32_ref > smaller_u32,
"Failed: &Number > smaller_primitive for {num_u32:?} and {smaller_u32:?}"
);
assert!(
num_u32_ref < larger_u32,
"Failed: &Number < larger_primitive for {num_u32:?} and {larger_u32:?}"
);
assert!(
num_u32_ref >= smaller_u32,
"Failed: &Number >= smaller_primitive for {num_u32:?} and {smaller_u32:?}"
);
assert!(
num_u32_ref <= larger_u32,
"Failed: &Number <= larger_primitive for {num_u32:?} and {larger_u32:?}"
);
assert!(
smaller_u32 < num_u32_ref,
"Failed: smaller_primitive < &Number for {smaller_u32:?} and {num_u32:?}"
);
assert!(
larger_u32 > num_u32_ref,
"Failed: larger_primitive > &Number for {larger_u32:?} and {num_u32:?}"
);
assert!(
smaller_u32 <= num_u32_ref,
"Failed: smaller_primitive <= &Number for {smaller_u32:?} and {num_u32:?}"
);
assert!(
larger_u32 >= num_u32_ref,
"Failed: larger_primitive >= &Number for {larger_u32:?} and {num_u32:?}"
);
assert!(
num_u32_ref > smaller_u32_ref,
"Failed: &Number > &smaller_primitive for {num_u32:?} and {smaller_u32:?}"
);
assert!(
num_u32_ref < larger_u32_ref,
"Failed: &Number < &larger_primitive for {num_u32:?} and {larger_u32:?}"
);
assert!(
num_u32_ref >= smaller_u32_ref,
"Failed: &Number >= &smaller_primitive for {num_u32:?} and {smaller_u32:?}"
);
assert!(
num_u32_ref <= larger_u32_ref,
"Failed: &Number <= &larger_primitive for {num_u32:?} and {larger_u32:?}"
);
assert!(
smaller_u32_ref < num_u32_ref,
"Failed: &smaller_primitive < &Number for {smaller_u32:?} and {num_u32:?}"
);
assert!(
larger_u32_ref > num_u32_ref,
"Failed: &larger_primitive > &Number for {larger_u32:?} and {num_u32:?}"
);
assert!(
smaller_u32_ref <= num_u32_ref,
"Failed: &smaller_primitive <= &Number for {smaller_u32:?} and {num_u32:?}"
);
assert!(
larger_u32_ref >= num_u32_ref,
"Failed: &larger_primitive >= &Number for {larger_u32:?} and {num_u32:?}"
);
let num_i32 = Number::from(-42i64);
let smaller_i32 = -50i32;
let larger_i32 = -40i32;
let num_i32_ref = &num_i32;
let smaller_i32_ref = &smaller_i32;
let larger_i32_ref = &larger_i32;
assert!(
num_i32_ref > smaller_i32,
"Failed: &Number > smaller_primitive for {num_i32:?} and {smaller_i32:?}"
);
assert!(
num_i32_ref < larger_i32,
"Failed: &Number < larger_primitive for {num_i32:?} and {larger_i32:?}"
);
assert!(
num_i32_ref >= smaller_i32,
"Failed: &Number >= smaller_primitive for {num_i32:?} and {smaller_i32:?}"
);
assert!(
num_i32_ref <= larger_i32,
"Failed: &Number <= larger_primitive for {num_i32:?} and {larger_i32:?}"
);
assert!(
smaller_i32 < num_i32_ref,
"Failed: smaller_primitive < &Number for {smaller_i32:?} and {num_i32:?}"
);
assert!(
larger_i32 > num_i32_ref,
"Failed: larger_primitive > &Number for {larger_i32:?} and {num_i32:?}"
);
assert!(
smaller_i32 <= num_i32_ref,
"Failed: smaller_primitive <= &Number for {smaller_i32:?} and {num_i32:?}"
);
assert!(
larger_i32 >= num_i32_ref,
"Failed: larger_primitive >= &Number for {larger_i32:?} and {num_i32:?}"
);
assert!(
num_i32_ref > smaller_i32_ref,
"Failed: &Number > &smaller_primitive for {num_i32:?} and {smaller_i32:?}"
);
assert!(
num_i32_ref < larger_i32_ref,
"Failed: &Number < &larger_primitive for {num_i32:?} and {larger_i32:?}"
);
assert!(
num_i32_ref >= smaller_i32_ref,
"Failed: &Number >= &smaller_primitive for {num_i32:?} and {smaller_i32:?}"
);
assert!(
num_i32_ref <= larger_i32_ref,
"Failed: &Number <= &larger_primitive for {num_i32:?} and {larger_i32:?}"
);
assert!(
smaller_i32_ref < num_i32_ref,
"Failed: &smaller_primitive < &Number for {smaller_i32:?} and {num_i32:?}"
);
assert!(
larger_i32_ref > num_i32_ref,
"Failed: &larger_primitive > &Number for {larger_i32:?} and {num_i32:?}"
);
assert!(
smaller_i32_ref <= num_i32_ref,
"Failed: &smaller_primitive <= &Number for {smaller_i32:?} and {num_i32:?}"
);
assert!(
larger_i32_ref >= num_i32_ref,
"Failed: &larger_primitive >= &Number for {larger_i32:?} and {num_i32:?}"
);
let num_f64 = num!(3.16);
let smaller_f64 = 3.0f64;
let larger_f64 = 4.0f64;
let num_f64_ref = &num_f64;
let smaller_f64_ref = &smaller_f64;
let larger_f64_ref = &larger_f64;
assert!(
num_f64_ref > smaller_f64,
"Failed: &Number > smaller_primitive for {num_f64:?} and {smaller_f64:?}"
);
assert!(
num_f64_ref < larger_f64,
"Failed: &Number < larger_primitive for {num_f64:?} and {larger_f64:?}"
);
assert!(
num_f64_ref >= smaller_f64,
"Failed: &Number >= smaller_primitive for {num_f64:?} and {smaller_f64:?}"
);
assert!(
num_f64_ref <= larger_f64,
"Failed: &Number <= larger_primitive for {num_f64:?} and {larger_f64:?}"
);
assert!(
smaller_f64 < num_f64_ref,
"Failed: smaller_primitive < &Number for {smaller_f64:?} and {num_f64:?}"
);
assert!(
larger_f64 > num_f64_ref,
"Failed: larger_primitive > &Number for {larger_f64:?} and {num_f64:?}"
);
assert!(
smaller_f64 <= num_f64_ref,
"Failed: smaller_primitive <= &Number for {smaller_f64:?} and {num_f64:?}"
);
assert!(
larger_f64 >= num_f64_ref,
"Failed: larger_primitive >= &Number for {larger_f64:?} and {num_f64:?}"
);
assert!(
num_f64_ref > smaller_f64_ref,
"Failed: &Number > &smaller_primitive for {num_f64:?} and {smaller_f64:?}"
);
assert!(
num_f64_ref < larger_f64_ref,
"Failed: &Number < &larger_primitive for {num_f64:?} and {larger_f64:?}"
);
assert!(
num_f64_ref >= smaller_f64_ref,
"Failed: &Number >= &smaller_primitive for {num_f64:?} and {smaller_f64:?}"
);
assert!(
num_f64_ref <= larger_f64_ref,
"Failed: &Number <= &larger_primitive for {num_f64:?} and {larger_f64:?}"
);
assert!(
smaller_f64_ref < num_f64_ref,
"Failed: &smaller_primitive < &Number for {smaller_f64:?} and {num_f64:?}"
);
assert!(
larger_f64_ref > num_f64_ref,
"Failed: &larger_primitive > &Number for {larger_f64:?} and {num_f64:?}"
);
assert!(
smaller_f64_ref <= num_f64_ref,
"Failed: &smaller_primitive <= &Number for {smaller_f64:?} and {num_f64:?}"
);
assert!(
larger_f64_ref >= num_f64_ref,
"Failed: &larger_primitive >= &Number for {larger_f64:?} and {num_f64:?}"
);
}
#[test]
fn test_reference_ordering_equality() {
let num_u32 = Number::from(42u64);
let prim_u32 = 42u32;
let num_u32_ref = &num_u32;
let prim_u32_ref = &prim_u32;
assert!(
num_u32_ref >= prim_u32,
"Failed: &Number >= primitive for {num_u32:?} and {prim_u32:?}"
);
assert!(
num_u32_ref <= prim_u32,
"Failed: &Number <= primitive for {num_u32:?} and {prim_u32:?}"
);
assert!(
prim_u32 >= num_u32_ref,
"Failed: primitive >= &Number for {prim_u32:?} and {num_u32:?}"
);
assert!(
prim_u32 <= num_u32_ref,
"Failed: primitive <= &Number for {prim_u32:?} and {num_u32:?}"
);
assert!(
num_u32_ref >= prim_u32_ref,
"Failed: &Number >= &primitive for {num_u32:?} and {prim_u32:?}"
);
assert!(
num_u32_ref <= prim_u32_ref,
"Failed: &Number <= &primitive for {num_u32:?} and {prim_u32:?}"
);
assert!(
prim_u32_ref >= num_u32_ref,
"Failed: &primitive >= &Number for {prim_u32:?} and {num_u32:?}"
);
assert!(
prim_u32_ref <= num_u32_ref,
"Failed: &primitive <= &Number for {prim_u32:?} and {num_u32:?}"
);
let num_i32 = Number::from(-42i64);
let prim_i32 = -42i32;
let num_i32_ref = &num_i32;
let prim_i32_ref = &prim_i32;
assert!(
num_i32_ref >= prim_i32,
"Failed: &Number >= primitive for {num_i32:?} and {prim_i32:?}"
);
assert!(
num_i32_ref <= prim_i32,
"Failed: &Number <= primitive for {num_i32:?} and {prim_i32:?}"
);
assert!(
prim_i32 >= num_i32_ref,
"Failed: primitive >= &Number for {prim_i32:?} and {num_i32:?}"
);
assert!(
prim_i32 <= num_i32_ref,
"Failed: primitive <= &Number for {prim_i32:?} and {num_i32:?}"
);
assert!(
num_i32_ref >= prim_i32_ref,
"Failed: &Number >= &primitive for {num_i32:?} and {prim_i32:?}"
);
assert!(
num_i32_ref <= prim_i32_ref,
"Failed: &Number <= &primitive for {num_i32:?} and {prim_i32:?}"
);
assert!(
prim_i32_ref >= num_i32_ref,
"Failed: &primitive >= &Number for {prim_i32:?} and {num_i32:?}"
);
assert!(
prim_i32_ref <= num_i32_ref,
"Failed: &primitive <= &Number for {prim_i32:?} and {num_i32:?}"
);
let num_f64 = num!(3.16);
let prim_f64 = 3.16f64;
let num_f64_ref = &num_f64;
let prim_f64_ref = &prim_f64;
assert!(
num_f64_ref >= prim_f64,
"Failed: &Number >= primitive for {num_f64:?} and {prim_f64:?}"
);
assert!(
num_f64_ref <= prim_f64,
"Failed: &Number <= primitive for {num_f64:?} and {prim_f64:?}"
);
assert!(
prim_f64 >= num_f64_ref,
"Failed: primitive >= &Number for {prim_f64:?} and {num_f64:?}"
);
assert!(
prim_f64 <= num_f64_ref,
"Failed: primitive <= &Number for {prim_f64:?} and {num_f64:?}"
);
assert!(
num_f64_ref >= prim_f64_ref,
"Failed: &Number >= &primitive for {num_f64:?} and {prim_f64:?}"
);
assert!(
num_f64_ref <= prim_f64_ref,
"Failed: &Number <= &primitive for {num_f64:?} and {prim_f64:?}"
);
assert!(
prim_f64_ref >= num_f64_ref,
"Failed: &primitive >= &Number for {prim_f64:?} and {num_f64:?}"
);
assert!(
prim_f64_ref <= num_f64_ref,
"Failed: &primitive <= &Number for {prim_f64:?} and {num_f64:?}"
);
}
#[test]
fn test_reference_cross_type_ordering() {
let num_u32 = Number::from(42u64);
let smaller_i32 = 41i32;
let larger_i32 = 43i32;
let num_u32_ref = &num_u32;
let smaller_i32_ref = &smaller_i32;
let larger_i32_ref = &larger_i32;
assert!(
num_u32_ref > smaller_i32,
"Failed cross-type: &Number > smaller_primitive for {num_u32:?} and {smaller_i32:?}"
);
assert!(
num_u32_ref < larger_i32,
"Failed cross-type: &Number < larger_primitive for {num_u32:?} and {larger_i32:?}"
);
assert!(
smaller_i32 < num_u32_ref,
"Failed cross-type: smaller_primitive < &Number for {smaller_i32:?} and {num_u32:?}"
);
assert!(
larger_i32 > num_u32_ref,
"Failed cross-type: larger_primitive > &Number for {larger_i32:?} and {num_u32:?}"
);
assert!(
num_u32_ref > smaller_i32_ref,
"Failed cross-type: &Number > &smaller_primitive for {num_u32:?} and {smaller_i32:?}"
);
assert!(
num_u32_ref < larger_i32_ref,
"Failed cross-type: &Number < &larger_primitive for {num_u32:?} and {larger_i32:?}"
);
assert!(
smaller_i32_ref < num_u32_ref,
"Failed cross-type: &smaller_primitive < &Number for {smaller_i32:?} and {num_u32:?}"
);
assert!(
larger_i32_ref > num_u32_ref,
"Failed cross-type: &larger_primitive > &Number for {larger_i32:?} and {num_u32:?}"
);
let num_i32 = Number::from(42i64);
let smaller_u32 = 41u32;
let larger_u32 = 43u32;
let num_i32_ref = &num_i32;
let smaller_u32_ref = &smaller_u32;
let larger_u32_ref = &larger_u32;
assert!(
num_i32_ref > smaller_u32,
"Failed cross-type: &Number > smaller_primitive for {num_i32:?} and {smaller_u32:?}"
);
assert!(
num_i32_ref < larger_u32,
"Failed cross-type: &Number < larger_primitive for {num_i32:?} and {larger_u32:?}"
);
assert!(
smaller_u32 < num_i32_ref,
"Failed cross-type: smaller_primitive < &Number for {smaller_u32:?} and {num_i32:?}"
);
assert!(
larger_u32 > num_i32_ref,
"Failed cross-type: larger_primitive > &Number for {larger_u32:?} and {num_i32:?}"
);
assert!(
num_i32_ref > smaller_u32_ref,
"Failed cross-type: &Number > &smaller_primitive for {num_i32:?} and {smaller_u32:?}"
);
assert!(
num_i32_ref < larger_u32_ref,
"Failed cross-type: &Number < &larger_primitive for {num_i32:?} and {larger_u32:?}"
);
assert!(
smaller_u32_ref < num_i32_ref,
"Failed cross-type: &smaller_primitive < &Number for {smaller_u32:?} and {num_i32:?}"
);
assert!(
larger_u32_ref > num_i32_ref,
"Failed cross-type: &larger_primitive > &Number for {larger_u32:?} and {num_i32:?}"
);
let num_f64 = num!(42.0);
let smaller_u32_2 = 41u32;
let larger_u32_2 = 43u32;
let num_f64_ref = &num_f64;
let smaller_u32_2_ref = &smaller_u32_2;
let larger_u32_2_ref = &larger_u32_2;
assert!(
num_f64_ref > smaller_u32_2,
"Failed cross-type: &Number > smaller_primitive for {num_f64:?} and {smaller_u32_2:?}"
);
assert!(
num_f64_ref < larger_u32_2,
"Failed cross-type: &Number < larger_primitive for {num_f64:?} and {larger_u32_2:?}"
);
assert!(
smaller_u32_2 < num_f64_ref,
"Failed cross-type: smaller_primitive < &Number for {smaller_u32_2:?} and {num_f64:?}"
);
assert!(
larger_u32_2 > num_f64_ref,
"Failed cross-type: larger_primitive > &Number for {larger_u32_2:?} and {num_f64:?}"
);
assert!(
num_f64_ref > smaller_u32_2_ref,
"Failed cross-type: &Number > &smaller_primitive for {num_f64:?} and {smaller_u32_2:?}"
);
assert!(
num_f64_ref < larger_u32_2_ref,
"Failed cross-type: &Number < &larger_primitive for {num_f64:?} and {larger_u32_2:?}"
);
assert!(
smaller_u32_2_ref < num_f64_ref,
"Failed cross-type: &smaller_primitive < &Number for {smaller_u32_2:?} and {num_f64:?}"
);
assert!(
larger_u32_2_ref > num_f64_ref,
"Failed cross-type: &larger_primitive > &Number for {larger_u32_2:?} and {num_f64:?}"
);
let num_f64_2 = num!(42.0);
let smaller_i32_2 = 41i32;
let larger_i32_2 = 43i32;
let num_f64_2_ref = &num_f64_2;
let smaller_i32_2_ref = &smaller_i32_2;
let larger_i32_2_ref = &larger_i32_2;
assert!(
num_f64_2_ref > smaller_i32_2,
"Failed cross-type: &Number > smaller_primitive for {num_f64_2:?} and {smaller_i32_2:?}"
);
assert!(
num_f64_2_ref < larger_i32_2,
"Failed cross-type: &Number < larger_primitive for {num_f64_2:?} and {larger_i32_2:?}"
);
assert!(
smaller_i32_2 < num_f64_2_ref,
"Failed cross-type: smaller_primitive < &Number for {smaller_i32_2:?} and {num_f64_2:?}"
);
assert!(
larger_i32_2 > num_f64_2_ref,
"Failed cross-type: larger_primitive > &Number for {larger_i32_2:?} and {num_f64_2:?}"
);
assert!(
num_f64_2_ref > smaller_i32_2_ref,
"Failed cross-type: &Number > &smaller_primitive for {num_f64_2:?} and {smaller_i32_2:?}"
);
assert!(
num_f64_2_ref < larger_i32_2_ref,
"Failed cross-type: &Number < &larger_primitive for {num_f64_2:?} and {larger_i32_2:?}"
);
assert!(
smaller_i32_2_ref < num_f64_2_ref,
"Failed cross-type: &smaller_primitive < &Number for {smaller_i32_2:?} and {num_f64_2:?}"
);
assert!(
larger_i32_2_ref > num_f64_2_ref,
"Failed cross-type: &larger_primitive > &Number for {larger_i32_2:?} and {num_f64_2:?}"
);
}
#[test]
fn test_sorting_behavior() {
let mut numbers = vec![
Number::from(-10i64),
num!(f64::NAN),
Number::from(0u64),
num!(f64::INFINITY),
Number::from(5u64),
num!(f64::NEG_INFINITY),
num!(7.5f64),
Number::from(10u64),
Number::from(15i64),
num!(20.5f64),
];
let original = numbers.clone();
numbers.sort();
for i in 0..numbers.len() - 1 {
assert!(
numbers[i] <= numbers[i + 1],
"Sorting produced inconsistent order: {:?} > {:?} at positions {} and {}",
numbers[i],
numbers[i + 1],
i,
i + 1
);
}
for orig in &original {
assert!(numbers.contains(orig), "Sorting lost element: {orig:?}");
}
}
#[test]
fn test_ordering_stability() {
let numbers = vec![
Number::from(42i64),
num!(42.0f64),
Number::from(42u64),
num!(42.0f64),
Number::from(42i64),
];
let mut first_sort = numbers.clone();
first_sort.sort();
let mut second_sort = numbers.clone();
second_sort.sort();
assert_eq!(
first_sort, second_sort,
"Multiple sorts should produce identical results"
);
}