use sql_cli::data::arithmetic_evaluator::ArithmeticEvaluator;
use sql_cli::data::datatable::{DataTable, DataValue};
use sql_cli::recursive_parser::SqlExpression;
#[test]
fn test_registry_constant_functions() {
let table = DataTable::new("test");
let mut evaluator = ArithmeticEvaluator::new(&table);
let pi_expr = SqlExpression::FunctionCall {
name: "PI".to_string(),
args: vec![],
distinct: false,
};
let pi_result = evaluator.evaluate(&pi_expr, 0).unwrap();
match pi_result {
DataValue::Float(val) => assert!((val - std::f64::consts::PI).abs() < 1e-10),
_ => panic!("Expected Float for PI()"),
}
let me_expr = SqlExpression::FunctionCall {
name: "ME".to_string(),
args: vec![],
distinct: false,
};
let me_result = evaluator.evaluate(&me_expr, 0).unwrap();
match me_result {
DataValue::Float(val) => assert!((val - 9.1093837015e-31).abs() < 1e-40),
_ => panic!("Expected Float for ME()"),
}
let e_expr = SqlExpression::FunctionCall {
name: "E".to_string(),
args: vec![],
distinct: false,
};
let e_result = evaluator.evaluate(&e_expr, 0).unwrap();
match e_result {
DataValue::Float(val) => assert!((val - std::f64::consts::E).abs() < 1e-10),
_ => panic!("Expected Float for E()"),
}
}
#[test]
fn test_registry_astronomical_functions() {
let table = DataTable::new("test");
let mut evaluator = ArithmeticEvaluator::new(&table);
let earth_expr = SqlExpression::FunctionCall {
name: "MASS_EARTH".to_string(),
args: vec![],
distinct: false,
};
let earth_result = evaluator.evaluate(&earth_expr, 0).unwrap();
match earth_result {
DataValue::Float(val) => assert_eq!(val, 5.97237e24),
_ => panic!("Expected Float for MASS_EARTH()"),
}
let sun_expr = SqlExpression::FunctionCall {
name: "MASS_SUN".to_string(),
args: vec![],
distinct: false,
};
let sun_result = evaluator.evaluate(&sun_expr, 0).unwrap();
match sun_result {
DataValue::Float(val) => assert_eq!(val, 1.989e30),
_ => panic!("Expected Float for MASS_SUN()"),
}
let au_expr = SqlExpression::FunctionCall {
name: "AU".to_string(),
args: vec![],
distinct: false,
};
let au_result = evaluator.evaluate(&au_expr, 0).unwrap();
match au_result {
DataValue::Float(val) => assert_eq!(val, 1.495978707e11),
_ => panic!("Expected Float for AU()"),
}
let ly_expr = SqlExpression::FunctionCall {
name: "LIGHT_YEAR".to_string(),
args: vec![],
distinct: false,
};
let ly_result = evaluator.evaluate(&ly_expr, 0).unwrap();
match ly_result {
DataValue::Float(val) => assert_eq!(val, 9.4607e15),
_ => panic!("Expected Float for LIGHT_YEAR()"),
}
}
#[test]
fn test_registry_chemistry_functions() {
let table = DataTable::new("test");
let mut evaluator = ArithmeticEvaluator::new(&table);
let avogadro_expr = SqlExpression::FunctionCall {
name: "AVOGADRO".to_string(),
args: vec![],
distinct: false,
};
let avogadro_result = evaluator.evaluate(&avogadro_expr, 0).unwrap();
match avogadro_result {
DataValue::Float(val) => assert!((val - 6.02214076e23).abs() < 1e20),
_ => panic!("Expected Float for AVOGADRO()"),
}
let carbon_mass_expr = SqlExpression::FunctionCall {
name: "ATOMIC_MASS".to_string(),
args: vec![SqlExpression::StringLiteral("Carbon".to_string())],
distinct: false,
};
let carbon_result = evaluator.evaluate(&carbon_mass_expr, 0).unwrap();
match carbon_result {
DataValue::Float(val) => assert!((val - 12.01).abs() < 0.01),
_ => panic!("Expected Float for ATOMIC_MASS('Carbon')"),
}
let gold_number_expr = SqlExpression::FunctionCall {
name: "ATOMIC_NUMBER".to_string(),
args: vec![SqlExpression::StringLiteral("Au".to_string())],
distinct: false,
};
let gold_result = evaluator.evaluate(&gold_number_expr, 0).unwrap();
match gold_result {
DataValue::Integer(val) => assert_eq!(val, 79),
_ => panic!("Expected Integer for ATOMIC_NUMBER('Au')"),
}
}
#[test]
fn test_registry_function_errors() {
let table = DataTable::new("test");
let mut evaluator = ArithmeticEvaluator::new(&table);
let pi_with_args = SqlExpression::FunctionCall {
name: "PI".to_string(),
args: vec![SqlExpression::NumberLiteral("1.0".to_string())],
distinct: false,
};
assert!(evaluator.evaluate(&pi_with_args, 0).is_err());
let unknown_element = SqlExpression::FunctionCall {
name: "ATOMIC_MASS".to_string(),
args: vec![SqlExpression::StringLiteral("Xyz".to_string())],
distinct: false,
};
assert!(evaluator.evaluate(&unknown_element, 0).is_err());
let wrong_type = SqlExpression::FunctionCall {
name: "ATOMIC_MASS".to_string(),
args: vec![SqlExpression::NumberLiteral("42".to_string())],
distinct: false,
};
assert!(evaluator.evaluate(&wrong_type, 0).is_err());
}