WIP improvise-ciw8: red tests, wire writes to a non-record are accepted
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
@@ -1337,6 +1337,118 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
fn month_cell(month: &str, measure: &str) -> CellKey {
|
||||
CellKey::new(vec![
|
||||
("Month".to_string(), month.to_string()),
|
||||
("_Measure".to_string(), measure.to_string()),
|
||||
])
|
||||
}
|
||||
|
||||
/// Months in two quarters on Row, Revenue/Cost and `Profit = Revenue - Cost` on
|
||||
/// Column, every month funded, Q2 collapsed: rows `[Jan, Feb, Q2]`.
|
||||
fn host_on_a_fold() -> Host {
|
||||
let mut wb = Workbook::new("T");
|
||||
wb.add_category("Month").unwrap();
|
||||
for (month, quarter) in [("Jan", "Q1"), ("Feb", "Q1"), ("Apr", "Q2"), ("May", "Q2")] {
|
||||
wb.add_item_in_group("Month", month, quarter).unwrap();
|
||||
for measure in ["Revenue", "Cost"] {
|
||||
wb.add_item("_Measure", measure).unwrap();
|
||||
let value = CellValue::Number(10.0);
|
||||
wb.model.set_cell(month_cell(month, measure), value);
|
||||
}
|
||||
}
|
||||
let profit = crate::formula::parse_formula("Profit = Revenue - Cost", "_Measure");
|
||||
wb.model.add_formula(profit.unwrap());
|
||||
wb.active_view_mut().set_axis("Month", Axis::Row);
|
||||
wb.active_view_mut().set_axis("_Measure", Axis::Column);
|
||||
wb.active_view_mut().toggle_group_collapse("Month", "Q2");
|
||||
let mut app = App::new(wb, None);
|
||||
app.rebuild_layout();
|
||||
assert!(app.layout.folds_a_group(2, 1), "setup: row 2 is the Q2 fold");
|
||||
Host::new(app)
|
||||
}
|
||||
|
||||
/// One wire write, as a hand-rolled client composes it: a surrogate built from
|
||||
/// a key, and a basis claiming whatever the host says is current.
|
||||
fn wire_write(host: &mut Host, key: &CellKey, clear: bool) -> Vec<Addressed> {
|
||||
use improvise_protocol::ModelCommand;
|
||||
let cell = RecordCell {
|
||||
record: RecordHash::of(key),
|
||||
measure: key.get("_Measure").map(String::from),
|
||||
};
|
||||
let cmd = match clear {
|
||||
true => ModelCommand::ClearCell(cell),
|
||||
false => ModelCommand::SetCell {
|
||||
cell,
|
||||
value: CellValue::Number(7.0),
|
||||
},
|
||||
};
|
||||
let (asker, _) = host.connect(10, 10);
|
||||
let frame = crate::ui::reduce::caught_up(host.app(), cmd);
|
||||
host.handle(asker, ClientFrame::Commands(vec![frame]))
|
||||
}
|
||||
|
||||
fn refused(answer: &[Addressed]) -> bool {
|
||||
answer
|
||||
.iter()
|
||||
.any(|a| matches!(a.msg, ServerFrame::Rejected(Rejection::MutationRefused)))
|
||||
}
|
||||
|
||||
fn document_text(host: &Host) -> String {
|
||||
crate::persistence::format_md(&host.app().model_state.workbook)
|
||||
}
|
||||
|
||||
/// improvise-ciw8 — see context/test-evidence/command.md.
|
||||
#[test]
|
||||
fn a_wire_write_to_a_collapsed_fold_is_rejected_and_stores_nothing() {
|
||||
for clear in [false, true] {
|
||||
let mut host = host_on_a_fold();
|
||||
let before = document_text(&host);
|
||||
let answer = wire_write(&mut host, &month_cell("Q2", "Cost"), clear);
|
||||
assert!(refused(&answer), "clear={clear}: not refused: {answer:?}");
|
||||
assert_eq!(document_text(&host), before, "clear={clear}: the fold was written");
|
||||
}
|
||||
}
|
||||
|
||||
/// improvise-ciw8: a formula's result is `CellId::Derived`, no write's target.
|
||||
#[test]
|
||||
fn a_wire_write_under_a_formula_is_rejected_and_stores_nothing() {
|
||||
let mut host = host_on_a_fold();
|
||||
let before = document_text(&host);
|
||||
let answer = wire_write(&mut host, &month_cell("Feb", "Profit"), false);
|
||||
assert!(refused(&answer), "not refused: {answer:?}");
|
||||
assert_eq!(document_text(&host), before, "a value was stored under the formula");
|
||||
}
|
||||
|
||||
/// improvise-ciw8: a key the None axis aggregates over is `CellId::Aggregate`.
|
||||
#[test]
|
||||
fn a_wire_write_to_a_none_axis_aggregate_is_rejected_and_stores_nothing() {
|
||||
let mut host = host();
|
||||
host.app.model_state.workbook.add_category("Product").unwrap();
|
||||
host.app.model_state.workbook.add_item("Product", "Widget").unwrap();
|
||||
let view = host.app.model_state.workbook.active_view_mut();
|
||||
view.set_axis("Product", Axis::None);
|
||||
host.app.rebuild_layout();
|
||||
let before = document_text(&host);
|
||||
let answer = wire_write(&mut host, &cell("South"), false);
|
||||
assert!(refused(&answer), "not refused: {answer:?}");
|
||||
assert_eq!(document_text(&host), before, "the partial key was written");
|
||||
}
|
||||
|
||||
/// The control for the three above: the stored cell beside the fold is written.
|
||||
#[test]
|
||||
fn a_wire_write_to_a_stored_cell_beside_a_fold_is_accepted() {
|
||||
let mut host = host_on_a_fold();
|
||||
let answer = wire_write(&mut host, &month_cell("Feb", "Cost"), false);
|
||||
assert!(
|
||||
answer.iter().any(|a| matches!(a.msg, ServerFrame::Accepted)),
|
||||
"{answer:?}"
|
||||
);
|
||||
let model = &host.app().model_state.workbook.model;
|
||||
let value = model.get_cell(&month_cell("Feb", "Cost"));
|
||||
assert_eq!(value, Some(&CellValue::Number(7.0)));
|
||||
}
|
||||
|
||||
/// Clause 4 must not fire on a frame that merely names a record it is
|
||||
/// creating. See `context/test-evidence/command.md`.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user