Test: add unit tests co-located with the code they cover
- model/cell.rs: CellKey (sorting, get, with, without, matches_partial, display) and DataStore (set/get, overwrite, empty-removes-key, sum_matching, matching_cells, text exclusion) - model/category.rs: item ids, deduplication, group assignment, top_level_groups, item_index insertion order - formula/parser.rs: subtraction, WHERE clause, SUM/AVG, IF, numeric literal, chained arithmetic, error on missing = - view/view.rs: auto-axis assignment, set_axis, categories_on, page_selection, group collapse toggle, hide/show, cycle_axis (all transitions + scroll/selection reset) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -304,3 +304,60 @@ fn parse_comparison(tokens: &[Token], pos: &mut usize) -> Result<Expr> {
|
||||
let right = parse_add_sub(tokens, pos)?;
|
||||
Ok(Expr::BinOp(op.to_string(), Box::new(left), Box::new(right)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_formula;
|
||||
use crate::formula::{Expr, AggFunc};
|
||||
|
||||
#[test]
|
||||
fn parse_simple_subtraction() {
|
||||
let f = parse_formula("Profit = Revenue - Cost", "Measure").unwrap();
|
||||
assert_eq!(f.target, "Profit");
|
||||
assert_eq!(f.target_category, "Measure");
|
||||
assert!(matches!(f.expr, Expr::BinOp(ref op, _, _) if op == "-"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_where_clause() {
|
||||
let f = parse_formula("EastRev = Revenue WHERE Region = \"East\"", "Measure").unwrap();
|
||||
assert_eq!(f.target, "EastRev");
|
||||
let filter = f.filter.as_ref().unwrap();
|
||||
assert_eq!(filter.category, "Region");
|
||||
assert_eq!(filter.item, "East");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_sum_aggregation() {
|
||||
let f = parse_formula("Total = SUM(Revenue)", "Measure").unwrap();
|
||||
assert!(matches!(f.expr, Expr::Agg(AggFunc::Sum, _, _)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_avg_aggregation() {
|
||||
let f = parse_formula("Avg = AVG(Revenue)", "Measure").unwrap();
|
||||
assert!(matches!(f.expr, Expr::Agg(AggFunc::Avg, _, _)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_if_expression() {
|
||||
let f = parse_formula("Capped = IF(Revenue > 1000, 1000, Revenue)", "Measure").unwrap();
|
||||
assert!(matches!(f.expr, Expr::If(_, _, _)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_numeric_literal() {
|
||||
let f = parse_formula("Fixed = 42", "Measure").unwrap();
|
||||
assert!(matches!(f.expr, Expr::Number(n) if (n - 42.0).abs() < 1e-10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_chained_arithmetic() {
|
||||
parse_formula("X = (A + B) * (C - D)", "Cat").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_missing_equals_returns_error() {
|
||||
assert!(parse_formula("BadFormula Revenue Cost", "Cat").is_err());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user