synta 0.2.6

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
//! Tests for primitive types

use synta::types::primitive::{Boolean, Integer, Real};
use synta::types::string::BitString;

#[test]
fn test_boolean() {
    let b = Boolean::new(true);
    assert!(b.value());

    let b: Boolean = false.into();
    assert!(!bool::from(b));
}

#[test]
fn test_integer_from_i64() {
    // Positive values
    let i = Integer::from_i64(0);
    assert_eq!(i.as_bytes(), &[0x00]);

    let i = Integer::from_i64(127);
    assert_eq!(i.as_bytes(), &[0x7F]);

    let i = Integer::from_i64(128);
    assert_eq!(i.as_bytes(), &[0x00, 0x80]);

    let i = Integer::from_i64(256);
    assert_eq!(i.as_bytes(), &[0x01, 0x00]);

    // Negative values
    let i = Integer::from_i64(-1);
    assert_eq!(i.as_bytes(), &[0xFF]);

    let i = Integer::from_i64(-128);
    assert_eq!(i.as_bytes(), &[0x80]);

    let i = Integer::from_i64(-129);
    assert_eq!(i.as_bytes(), &[0xFF, 0x7F]);
}

#[test]
fn test_integer_from_u64() {
    let i = Integer::from_u64(0);
    assert_eq!(i.as_bytes(), &[0x00]);

    let i = Integer::from_u64(127);
    assert_eq!(i.as_bytes(), &[0x7F]);

    let i = Integer::from_u64(128);
    assert_eq!(i.as_bytes(), &[0x00, 0x80]);

    let i = Integer::from_u64(255);
    assert_eq!(i.as_bytes(), &[0x00, 0xFF]);
}

#[test]
fn test_integer_roundtrip() {
    let values = vec![0i64, 1, -1, 127, 128, -128, -129, 256, i64::MAX, i64::MIN];

    for val in values {
        let i = Integer::from_i64(val);
        assert_eq!(i.as_i64().unwrap(), val);
    }
}

#[test]
fn test_integer_u64_roundtrip() {
    let values = vec![0u64, 1, 127, 128, 255, 256, u32::MAX as u64];

    for val in values {
        let i = Integer::from_u64(val);
        assert_eq!(i.as_u64().unwrap(), val);
    }
}

#[test]
fn test_bitstring_creation() {
    // Valid bit string with 0 unused bits
    let bs = BitString::new(vec![0xFF, 0x80], 0).unwrap();
    assert_eq!(bs.as_bytes(), &[0xFF, 0x80]);
    assert_eq!(bs.unused_bits(), 0);
    assert_eq!(bs.bit_len(), 16);

    // Valid bit string with 3 unused bits (last byte: 10000000 = 0x80, unused bits are 0)
    let bs = BitString::new(vec![0xFF, 0x80], 3).unwrap();
    assert_eq!(bs.as_bytes(), &[0xFF, 0x80]);
    assert_eq!(bs.unused_bits(), 3);
    assert_eq!(bs.bit_len(), 13);

    // Empty bit string with 0 unused bits
    let bs = BitString::new(vec![], 0).unwrap();
    assert_eq!(bs.as_bytes(), &[]);
    assert_eq!(bs.unused_bits(), 0);
    assert_eq!(bs.bit_len(), 0);
}

#[test]
fn test_bitstring_invalid_unused_bits() {
    // unused_bits > 7 should fail
    let result = BitString::new(vec![0xFF], 8);
    assert!(result.is_err());

    let result = BitString::new(vec![0xFF], 10);
    assert!(result.is_err());
}

#[test]
fn test_bitstring_der_compliance() {
    // Unused bits in last byte must be zero for DER compliance
    // Last byte is 0x81 (10000001), with 3 unused bits
    // The unused 3 bits (001) are not zero, so this should fail
    let result = BitString::new(vec![0xFF, 0x81], 3);
    assert!(result.is_err());

    // Last byte is 0x80 (10000000), with 3 unused bits
    // The unused 3 bits (000) are zero, so this should succeed
    let result = BitString::new(vec![0xFF, 0x80], 3);
    assert!(result.is_ok());

    // Last byte is 0xF0 (11110000), with 4 unused bits
    // The unused 4 bits (0000) are zero, so this should succeed
    let result = BitString::new(vec![0xFF, 0xF0], 4);
    assert!(result.is_ok());

    // Last byte is 0xF8 (11111000), with 4 unused bits
    // The unused 4 bits (1000) are not zero, so this should fail
    let result = BitString::new(vec![0xFF, 0xF8], 4);
    assert!(result.is_err());
}

#[test]
fn test_real_construction() {
    let r = Real::new(std::f64::consts::PI);
    assert_eq!(r.value(), std::f64::consts::PI);

    // From<f64> and Into<f64> conversions
    let r: Real = std::f64::consts::E.into();
    assert_eq!(f64::from(r), std::f64::consts::E);
}

#[test]
fn test_real_special_values() {
    let inf = Real::new(f64::INFINITY);
    assert!(inf.value().is_infinite() && inf.value() > 0.0);

    let neg_inf = Real::new(f64::NEG_INFINITY);
    assert!(neg_inf.value().is_infinite() && neg_inf.value() < 0.0);

    let nan = Real::new(f64::NAN);
    assert!(nan.value().is_nan());

    let zero = Real::new(0.0);
    assert_eq!(zero.value(), 0.0);
    assert!(zero.value().is_finite());
}