feat(grid): allow drilling into formula cells

When drilling into a cell that is the target of a formula, the resulting
record set was empty because the formula target coordinate itself does not
exist in the raw data.

This change strips the '_Measure' coordinate from the drill key if the
value is a known formula target, allowing the underlying data records that
feed the formula to be discovered.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
This commit is contained in:
Edward Langley
2026-04-14 00:49:31 -07:00
parent a94abd6e6c
commit f019577810

View File

@ -111,6 +111,57 @@ mod tests {
"Expected TogglePruneEmpty, got: {dbg}"
);
}
/// Drilling into a formula cell (e.g. Profit = Revenue - Cost) should
/// return the underlying data records, not an empty result set. The
/// formula target coordinate is stripped from the drill key so that
/// matching_cells finds the raw data backing the formula.
#[test]
fn drill_into_formula_cell_returns_data_records() {
use crate::formula::parse_formula;
use crate::model::Model;
use crate::model::cell::{CellKey, CellValue};
let mut m = Model::new("Test");
m.add_category("Region").unwrap();
m.category_mut("Region").unwrap().add_item("East");
m.category_mut("_Measure").unwrap().add_item("Revenue");
m.category_mut("_Measure").unwrap().add_item("Cost");
m.set_cell(
CellKey::new(vec![
("_Measure".into(), "Revenue".into()),
("Region".into(), "East".into()),
]),
CellValue::Number(1000.0),
);
m.set_cell(
CellKey::new(vec![
("_Measure".into(), "Cost".into()),
("Region".into(), "East".into()),
]),
CellValue::Number(600.0),
);
m.add_formula(parse_formula("Profit = Revenue - Cost", "_Measure").unwrap());
let layout = make_layout(&m);
let reg = make_registry();
let ctx = make_ctx(&m, &layout, &reg);
// Drill into the Profit/East cell — a formula-derived cell
let key = CellKey::new(vec![
("_Measure".into(), "Profit".into()),
("Region".into(), "East".into()),
]);
let cmd = DrillIntoCell { key };
let effects = cmd.execute(&ctx);
let dbg = effects_debug(&effects);
// Should find underlying data records, not "0 rows"
assert!(
!dbg.contains("0 rows"),
"Drill into formula cell should find data records, got: {dbg}"
);
}
}
// ── Grid operations ─────────────────────────────────────────────────────
@ -233,9 +284,27 @@ impl Cmd for DrillIntoCell {
let drill_name = "_Drill".to_string();
let mut effects: Vec<Box<dyn Effect>> = Vec::new();
// If drilling into a formula cell, strip the formula target from the
// key so matching_cells finds the underlying raw data records instead
// of returning nothing.
let drill_key = if let Some(measure_val) = self.key.get("_Measure") {
let is_formula_target = ctx
.model
.formulas()
.iter()
.any(|f| f.target_category == "_Measure" && f.target == measure_val);
if is_formula_target {
self.key.without("_Measure")
} else {
self.key.clone()
}
} else {
self.key.clone()
};
// Capture the records snapshot NOW (before we switch views).
let records: Vec<(crate::model::cell::CellKey, crate::model::cell::CellValue)> =
if self.key.0.is_empty() {
if drill_key.0.is_empty() {
ctx.model
.data
.iter_cells()
@ -244,7 +313,7 @@ impl Cmd for DrillIntoCell {
} else {
ctx.model
.data
.matching_cells(&self.key.0)
.matching_cells(&drill_key.0)
.into_iter()
.map(|(k, v)| (k, v.clone()))
.collect()