use office_rs::error::Result;
use office_rs::xlsx::{
CellProvider,
CellReference,
CellValue,
FormulaCalculator,
FormulaValue,
parse_formula,
};
use std::collections::HashMap;
struct TestCellProvider {
cells: HashMap<String, CellValue>,
}
impl TestCellProvider {
fn new() -> Self {
let mut cells = HashMap::new();
cells.insert("A1".to_string(), CellValue::Number(10.0));
cells.insert("A2".to_string(), CellValue::Number(5.0));
cells.insert("A3".to_string(), CellValue::Number(2.0));
cells.insert("B1".to_string(), CellValue::Number(3.0));
cells.insert("B2".to_string(), CellValue::Number(0.0));
cells.insert("C1".to_string(), CellValue::Text("Hello".to_string()));
cells.insert("C2".to_string(), CellValue::Boolean(true));
cells.insert("C3".to_string(), CellValue::Boolean(false));
Self { cells }
}
}
impl CellProvider for TestCellProvider {
fn get_cell_value(&self, reference: &CellReference) -> Result<CellValue> {
let key = reference.to_a1();
Ok(self.cells.get(&key).cloned().unwrap_or(CellValue::Empty))
}
fn get_range_values(
&self,
_start: &CellReference,
_end: &CellReference
) -> Result<Vec<Vec<CellValue>>> {
Ok(vec![])
}
}
#[test]
fn test_addition() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=1+2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(3.0));
let expr = parse_formula("=A1+A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
let expr = parse_formula("=A1+5")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
let expr = parse_formula("=A1+A2+A3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(17.0));
let expr = parse_formula("=A1+(-A2)")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0));
println!("加法运算测试通过");
Ok(())
}
#[test]
fn test_subtraction() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=5-2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(3.0));
let expr = parse_formula("=A1-A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0));
let expr = parse_formula("=A1-3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(7.0));
let expr = parse_formula("=A1-(-A2)")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
println!("减法运算测试通过");
Ok(())
}
#[test]
fn test_multiplication() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=3*4")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(12.0));
let expr = parse_formula("=A1*A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(50.0));
let expr = parse_formula("=A1*2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(20.0));
let expr = parse_formula("=A1*A2*A3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(100.0));
println!("乘法运算测试通过");
Ok(())
}
#[test]
fn test_division() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=8/2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(4.0));
let expr = parse_formula("=A1/A3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0));
let expr = parse_formula("=A1/2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0));
let expr = parse_formula("=A1/B2")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Error(office_rs::xlsx::FormulaError::DivisionByZero));
println!("除法运算测试通过");
Ok(())
}
#[test]
fn test_power() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=2^3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(8.0));
let expr = parse_formula("=A3^B1")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(8.0));
let expr = parse_formula("=A3^2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(4.0));
println!("幂运算测试通过");
Ok(())
}
#[test]
fn test_unary_operators() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=+5")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0));
let expr = parse_formula("=-5")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-5.0));
let expr = parse_formula("=-A1")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-10.0));
let expr = parse_formula("=50%")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(0.5));
let expr = parse_formula("=A1%")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(0.1));
println!("一元操作符测试通过");
Ok(())
}
#[test]
fn test_operator_precedence() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=2+3*4")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(14.0));
let expr = parse_formula("=(2+3)*4")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(20.0));
let expr = parse_formula("=2^3^2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(512.0));
let expr = parse_formula("=A1+A2*A3-B1")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(17.0));
let expr = parse_formula("=2+3*4^2%")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(5.0843414799682));
let expr = parse_formula("=2+((3*4)^2)%")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(3.44));
println!("运算符优先级测试通过");
Ok(())
}
#[test]
fn test_type_conversions() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=C2+C3")?; let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(1.0));
let expr = parse_formula("=A1+\"5\"")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
let expr = parse_formula("=A1+\"abc\"")?;
let result = calculator.evaluate(&expr);
assert!(result.is_err());
println!("类型转换测试通过");
Ok(())
}
#[test]
fn test_error_handling() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=1/0")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Error(office_rs::xlsx::FormulaError::DivisionByZero));
let expr = parse_formula("=\"abc\"+5")?;
let result = calculator.evaluate(&expr);
assert!(result.is_err());
println!("错误处理测试通过");
Ok(())
}
#[test]
fn test_multi_operators() -> Result<()> {
let provider = Box::new(TestCellProvider::new());
let mut calculator = FormulaCalculator::new(provider);
let expr = parse_formula("=3*-4")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-12.0));
let expr = parse_formula("=A1*-A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-50.0));
let expr = parse_formula("=-A1*2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-20.0));
let expr = parse_formula("=A1*-A2*A3")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(-100.0));
let expr = parse_formula("=A1++A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
let expr = parse_formula("=A1--A2")?;
let result = calculator.evaluate(&expr)?;
assert_eq!(result, FormulaValue::Number(15.0));
println!("乘法运算测试通过");
Ok(())
}
fn main() -> Result<()> {
test_addition()?;
test_subtraction()?;
test_multiplication()?;
test_division()?;
test_power()?;
test_unary_operators()?;
test_operator_precedence()?;
test_type_conversions()?;
test_error_handling()?;
println!("所有基础算术运算测试通过!");
Ok(())
}