//! Unit tests for core type system
//! 
//! Tests the fundamental types that underpin the entire trading system,
//! with focus on precision, validation, and safety.

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_price_basic() {
        let price = Price::new(150.25);
        assert!((price.to_f64() - 150.25).abs() < 0.01);
        
        let zero = Price::ZERO;
        assert_eq!(zero.to_f64(), 0.0);
        
        let cent = Price::CENT;
        assert!((cent.to_f64() - 0.01).abs() < 0.001);
    }

    #[test]
    fn test_price_arithmetic() {
        let p1 = Price::new(100.0);
        let p2 = Price::new(50.0);
        
        let sum = p1 + p2;
        assert!((sum.to_f64() - 150.0).abs() < 0.01);
        
        assert!(p1 > p2);
        assert_eq!(p1, Price::new(100.0));
    }

    #[test]
    fn test_quantity_basic() {
        let qty = Quantity::new(1000.5);
        assert!((qty.to_f64() - 1000.5).abs() < 0.01);
        
        let zero = Quantity::ZERO;
        assert_eq!(zero.to_f64(), 0.0);
    }

    #[test]
    fn test_order_id() {
        let id1 = OrderId::new();
        let id2 = OrderId::new();
        
        assert_ne!(id1, id2);
        assert!(!id1.to_string().is_empty());
    }

    #[test]
    fn test_side_enum() {
        assert_ne!(Side::Buy, Side::Sell);
        assert_eq!(Side::Buy, Side::Buy);
        assert_eq!(Side::Sell, Side::Sell);
    }

    #[test]
    fn test_symbol_basic() {
        let symbol1 = Symbol::new("AAPL".to_string());
        let symbol2 = Symbol::new("AAPL".to_string());
        let symbol3 = Symbol::new("GOOGL".to_string());
        
        assert_eq!(symbol1, symbol2);
        assert_ne!(symbol1, symbol3);
    }

    #[test]
    fn test_order_status() {
        let status = OrderStatus::Pending;
        assert_eq!(status, OrderStatus::Pending);
        assert_ne!(status, OrderStatus::Filled);
    }

    #[test]
    fn test_order_type() {
        let order_type = OrderType::Market;
        assert_eq!(order_type, OrderType::Market);
        assert_ne!(order_type, OrderType::Limit);
    }

    #[test]
    fn test_price_precision() {
        // Test high precision prices
        let precise_price = Price::new(123.456789);
        assert!((precise_price.to_f64() - 123.456789).abs() < 0.000001);
    }

    #[test]
    fn test_quantity_precision() {
        // Test fractional quantities
        let fractional_qty = Quantity::new(100.125);
        assert!((fractional_qty.to_f64() - 100.125).abs() < 0.001);
    }

    #[test]
    fn test_price_ordering() {
        let prices = vec![
            Price::new(100.0),
            Price::new(50.0),
            Price::new(200.0),
            Price::new(75.0),
        ];
        
        let mut sorted_prices = prices.clone();
        sorted_prices.sort();
        
        assert_eq!(sorted_prices[0], Price::new(50.0));
        assert_eq!(sorted_prices[1], Price::new(75.0));
        assert_eq!(sorted_prices[2], Price::new(100.0));
        assert_eq!(sorted_prices[3], Price::new(200.0));
    }
}