use rlox::common::base_value::{BaseValue, Number}; #[test] fn test_number_addition_with_type_promotion() { // Test float + int -> both become F64 let float_num = Number::F64(3.5); let int_num = Number::I32(2); let result = float_num.add(int_num); match result { Number::F64(val) => assert_eq!(val, 5.5), _ => panic!("Expected F64 result from float + int"), } // Test int + unsigned -> both become I64 let int_num = Number::I32(-5); let unsigned_num = Number::U32(10); let result = int_num.add(unsigned_num); match result { Number::I64(val) => assert_eq!(val, 5), _ => panic!("Expected I64 result from int + unsigned"), } // Test float + unsigned -> both become F64 let float_num = Number::F32(2.5); let unsigned_num = Number::U64(3); let result = float_num.add(unsigned_num); match result { Number::F64(val) => assert_eq!(val, 5.5), _ => panic!("Expected F64 result from float + unsigned"), } // Test unsigned + unsigned -> both stay U128 let unsigned1 = Number::U32(100); let unsigned2 = Number::U64(200); let result = unsigned1.add(unsigned2); match result { Number::U128(val) => assert_eq!(val, 300), _ => panic!("Expected U128 result from unsigned + unsigned"), } } #[test] fn test_number_subtraction() { let a = Number::F64(10.5); let b = Number::I32(5); let result = a.sub(b); match result { Number::F64(val) => assert_eq!(val, 5.5), _ => panic!("Expected F64 result"), } let a = Number::I32(10); let b = Number::U32(3); let result = a.sub(b); match result { Number::I64(val) => assert_eq!(val, 7), _ => panic!("Expected I64 result"), } } #[test] fn test_number_multiplication() { let a = Number::F64(2.5); let b = Number::I32(4); let result = a.mul(b); match result { Number::F64(val) => assert_eq!(val, 10.0), _ => panic!("Expected F64 result"), } let a = Number::U32(5); let b = Number::U32(6); let result = a.mul(b); match result { Number::U128(val) => assert_eq!(val, 30), _ => panic!("Expected U128 result"), } } #[test] fn test_number_division() { let a = Number::F64(10.0); let b = Number::I32(4); let result = a.div(b).unwrap(); match result { Number::F64(val) => assert_eq!(val, 2.5), _ => panic!("Expected F64 result"), } // Test division by zero let a = Number::I32(10); let b = Number::I32(0); assert!(a.div(b).is_none()); let a = Number::F64(10.0); let b = Number::F64(0.0); assert!(a.div(b).is_none()); } #[test] fn test_number_remainder() { let a = Number::I32(10); let b = Number::I32(3); let result = a.rem(b).unwrap(); match result { Number::I64(val) => assert_eq!(val, 1), _ => panic!("Expected I64 result"), } let a = Number::F64(10.5); let b = Number::F64(3.0); let result = a.rem(b).unwrap(); match result { Number::F64(val) => assert_eq!(val, 1.5), _ => panic!("Expected F64 result"), } } #[test] fn test_number_negation() { let num = Number::I32(5); let result = num.neg(); match result { Number::I32(val) => assert_eq!(val, -5), _ => panic!("Expected I32 result"), } let num = Number::U32(5); let result = num.neg(); match result { Number::I64(val) => assert_eq!(val, -5), _ => panic!("Expected I64 result for negated unsigned"), } let num = Number::F64(3.5); let result = num.neg(); match result { Number::F64(val) => assert_eq!(val, -3.5), _ => panic!("Expected F64 result"), } } #[test] fn test_number_comparison() { let a = Number::I32(5); let b = Number::F64(5.0); assert_eq!(a.partial_cmp(&b), Some(std::cmp::Ordering::Equal)); let a = Number::I32(5); let b = Number::F64(6.0); assert_eq!(a.partial_cmp(&b), Some(std::cmp::Ordering::Less)); let a = Number::U32(10); let b = Number::I32(5); assert_eq!(a.partial_cmp(&b), Some(std::cmp::Ordering::Greater)); } #[test] fn test_baevalue_operations() { // Test BaseValue addition let a = BaseValue::Number(Number::I32(5)); let b = BaseValue::Number(Number::F64(3.5)); let result = (a + b).unwrap(); match result { BaseValue::Number(Number::F64(val)) => assert_eq!(val, 8.5), _ => panic!("Expected Number(F64) result"), } // Test string concatenation let a = BaseValue::String("Hello ".to_string()); let b = BaseValue::String("World".to_string()); let result = (a + b).unwrap(); match result { BaseValue::String(s) => assert_eq!(s, "Hello World"), _ => panic!("Expected String result"), } } #[test] fn test_is_zero() { assert!(Number::I32(0).is_zero()); assert!(Number::F64(0.0).is_zero()); assert!(Number::U32(0).is_zero()); assert!(!Number::I32(1).is_zero()); assert!(!Number::F64(0.1).is_zero()); assert!(!Number::U32(1).is_zero()); }