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:
Ed L
2026-03-21 23:28:48 -07:00
parent 6a9d28ecd6
commit 56d11aee74
4 changed files with 418 additions and 0 deletions

View File

@ -125,3 +125,117 @@ impl View {
self.col_offset = 0;
}
}
#[cfg(test)]
mod tests {
use super::View;
use crate::view::Axis;
fn view_with_cats(cats: &[&str]) -> View {
let mut v = View::new("Test");
for &c in cats { v.on_category_added(c); }
v
}
#[test]
fn first_category_assigned_to_row() {
let v = view_with_cats(&["Region"]);
assert_eq!(v.axis_of("Region"), Axis::Row);
}
#[test]
fn second_category_assigned_to_column() {
let v = view_with_cats(&["Region", "Product"]);
assert_eq!(v.axis_of("Product"), Axis::Column);
}
#[test]
fn third_and_later_categories_assigned_to_page() {
let v = view_with_cats(&["Region", "Product", "Time", "Scenario"]);
assert_eq!(v.axis_of("Time"), Axis::Page);
assert_eq!(v.axis_of("Scenario"), Axis::Page);
}
#[test]
fn set_axis_changes_assignment() {
let mut v = view_with_cats(&["Region", "Product"]);
v.set_axis("Region", Axis::Column);
assert_eq!(v.axis_of("Region"), Axis::Column);
}
#[test]
fn categories_on_returns_correct_list() {
let v = view_with_cats(&["Region", "Product", "Time"]);
assert_eq!(v.categories_on(Axis::Row), vec!["Region"]);
assert_eq!(v.categories_on(Axis::Column), vec!["Product"]);
assert_eq!(v.categories_on(Axis::Page), vec!["Time"]);
}
#[test]
fn axis_of_unknown_category_returns_unassigned() {
let v = View::new("Test");
assert_eq!(v.axis_of("Ghost"), Axis::Unassigned);
}
#[test]
fn page_selection_set_and_get() {
let mut v = view_with_cats(&["Region", "Product", "Time"]);
v.set_page_selection("Time", "Q1");
assert_eq!(v.page_selection("Time"), Some("Q1"));
assert_eq!(v.page_selection("Region"), None);
}
#[test]
fn toggle_group_collapse_toggles_twice() {
let mut v = View::new("Test");
assert!(!v.is_group_collapsed("Time", "Q1"));
v.toggle_group_collapse("Time", "Q1");
assert!(v.is_group_collapsed("Time", "Q1"));
v.toggle_group_collapse("Time", "Q1");
assert!(!v.is_group_collapsed("Time", "Q1"));
}
#[test]
fn hide_and_show_item() {
let mut v = View::new("Test");
assert!(!v.is_hidden("Region", "East"));
v.hide_item("Region", "East");
assert!(v.is_hidden("Region", "East"));
v.show_item("Region", "East");
assert!(!v.is_hidden("Region", "East"));
}
#[test]
fn cycle_axis_row_to_column() {
let mut v = view_with_cats(&["Region", "Product"]);
v.cycle_axis("Region");
assert_eq!(v.axis_of("Region"), Axis::Column);
}
#[test]
fn cycle_axis_column_to_page() {
let mut v = view_with_cats(&["Region", "Product"]);
v.set_axis("Product", Axis::Column);
v.cycle_axis("Product");
assert_eq!(v.axis_of("Product"), Axis::Page);
}
#[test]
fn cycle_axis_page_to_row() {
let mut v = view_with_cats(&["Region", "Product", "Time"]);
v.cycle_axis("Time");
assert_eq!(v.axis_of("Time"), Axis::Row);
}
#[test]
fn cycle_axis_resets_scroll_and_selection() {
let mut v = view_with_cats(&["Region"]);
v.row_offset = 5;
v.col_offset = 3;
v.selected = (2, 2);
v.cycle_axis("Region");
assert_eq!(v.row_offset, 0);
assert_eq!(v.col_offset, 0);
assert_eq!(v.selected, (0, 0));
}
}