icydb-model 0.299.0

IcyDB application-model authoring, validation, and code generation
Documentation
use super::*;
use std::str::FromStr;

fn dec(v: &str) -> Decimal {
    Decimal::from_str(v).unwrap()
}

#[test]
fn clamps_integers() {
    let clamp = Clamp::new(10, 20);

    let mut v = 5;
    clamp.normalize(&mut v).unwrap();
    assert_eq!(v, 10);

    let mut v = 25;
    clamp.normalize(&mut v).unwrap();
    assert_eq!(v, 20);

    let mut v = 15;
    clamp.normalize(&mut v).unwrap();
    assert_eq!(v, 15);
}

#[test]
fn clamp_invalid_config() {
    let clamp = Clamp::new(20, 10);

    let mut v = 15;
    assert!(clamp.normalize(&mut v).is_err());
}

#[test]
fn invalid_numeric_clamp_configuration_preserves_values() {
    let clamps = [
        Clamp::new(0_u128, u128::MAX),
        Clamp::new(u128::MAX, 0),
        Clamp::new(u128::MAX, u128::MAX),
        Clamp::new(0.0_f64, f64::NAN),
        Clamp::new(f64::INFINITY, 1.0),
        Clamp::new(0.0, f64::NEG_INFINITY),
        Clamp::new(0.0, 1e40),
        Clamp::new(-1e40, 0.0),
        Clamp::new(0.0_f32, f32::MAX),
    ];
    for clamp in clamps {
        for original in [0_u128, 7, u128::MAX] {
            let mut value = original;
            for _ in 0..2 {
                assert!(clamp.normalize(&mut value).is_err());
                assert_eq!(value, original);
            }
        }
    }
}

#[test]
fn invalid_numeric_rounding_configuration_preserves_values() {
    for round in [
        RoundDecimalPlaces::new(-1),
        RoundDecimalPlaces::new(u64::MAX),
    ] {
        for original in [dec("1.235"), dec("-1.235"), Decimal::ZERO] {
            let mut value = original;
            for _ in 0..2 {
                assert!(round.normalize(&mut value).is_err());
                assert_eq!(value, original);
            }
        }
    }
}

#[test]
fn numeric_normalizer_boundaries_and_defaults_remain_valid() {
    let mut value = i128::MIN;
    Clamp::new(i128::MIN, i128::MAX)
        .normalize(&mut value)
        .unwrap();
    assert_eq!(value, i128::MIN);
    let mut value = i128::MAX as u128;
    Clamp::new(0_u128, i128::MAX as u128)
        .normalize(&mut value)
        .unwrap();
    assert_eq!(value, i128::MAX as u128);
    let mut value = dec("1.235");
    Clamp::new(dec("1.2"), dec("1.3"))
        .normalize(&mut value)
        .unwrap();
    assert_eq!(value, dec("1.235"));
    let mut value = 7;
    Clamp::default().normalize(&mut value).unwrap();
    assert_eq!(value, 0);
    for (round, expected) in [
        (RoundDecimalPlaces::default(), dec("1")),
        (RoundDecimalPlaces::new(2), dec("1.24")),
        (RoundDecimalPlaces::new(u32::MAX), dec("1.235")),
    ] {
        let mut value = dec("1.235");
        round.normalize(&mut value).unwrap();
        assert_eq!(value, expected);
    }
}

#[test]
fn rounds_decimal_places_midpoint_away_from_zero() {
    let round = RoundDecimalPlaces::new(2);

    let mut v = dec("1.234");
    round.normalize(&mut v).unwrap();
    assert_eq!(v, dec("1.23"));

    let mut v = dec("1.235");
    round.normalize(&mut v).unwrap();
    assert_eq!(v, dec("1.24"));

    let mut v = dec("-1.235");
    round.normalize(&mut v).unwrap();
    assert_eq!(v, dec("-1.24"));
}