improvise-umi4: WIP failing tests — an untouched edit must store the identical value
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:
@@ -473,6 +473,123 @@ mod tests {
|
||||
"bulk entry lands at the start of the new row"
|
||||
);
|
||||
}
|
||||
|
||||
/// Values whose `Display` (four decimals) and value disagree, plus text.
|
||||
fn values_display_rounds() -> Vec<crate::model::cell::CellValue> {
|
||||
use crate::model::cell::CellValue::{Number, Text};
|
||||
vec![
|
||||
Number(1.23456789),
|
||||
Number(0.1 + 0.2),
|
||||
Number(98765.4321987),
|
||||
Number(123456789012345.67),
|
||||
Number(-0.00001234),
|
||||
Text("0.1 + 0.2".into()),
|
||||
]
|
||||
}
|
||||
|
||||
/// Two regions, two measures, with `value` at (West, Revenue): never index 0.
|
||||
fn grid_holding(value: crate::model::cell::CellValue, records: bool) -> crate::ui::app::App {
|
||||
use crate::model::cell::{CellKey, CellValue};
|
||||
use crate::ui::app::App;
|
||||
use crate::view::Axis;
|
||||
|
||||
let mut wb = Workbook::new("Seed");
|
||||
wb.add_category("Region").unwrap();
|
||||
for region in ["North", "West"] {
|
||||
wb.add_item("Region", region).unwrap();
|
||||
}
|
||||
for measure in ["Cost", "Revenue"] {
|
||||
wb.add_item("_Measure", measure).unwrap();
|
||||
}
|
||||
let key = |r: &str, m: &str| {
|
||||
CellKey::new(vec![
|
||||
("Region".into(), r.into()),
|
||||
("_Measure".into(), m.into()),
|
||||
])
|
||||
};
|
||||
wb.model.set_cell(key("North", "Cost"), CellValue::Number(1.0));
|
||||
wb.model.set_cell(key("North", "Revenue"), CellValue::Number(2.0));
|
||||
wb.model.set_cell(key("West", "Cost"), CellValue::Number(3.0));
|
||||
wb.model.set_cell(key("West", "Revenue"), value);
|
||||
{
|
||||
let v = wb.active_view_mut();
|
||||
match records {
|
||||
true => {
|
||||
v.set_axis("_Index", Axis::Row);
|
||||
v.set_axis("_Dim", Axis::Column);
|
||||
v.set_axis("Region", Axis::None);
|
||||
v.set_axis("_Measure", Axis::None);
|
||||
}
|
||||
false => {
|
||||
v.set_axis("Region", Axis::Row);
|
||||
v.set_axis("_Measure", Axis::Column);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut app = App::new(wb, None);
|
||||
app.rebuild_layout();
|
||||
assert_eq!(app.layout.is_records_mode(), records, "wrong fixture mode");
|
||||
app
|
||||
}
|
||||
|
||||
/// Open the editor on (West, Revenue) and commit it untouched; the stored value.
|
||||
fn no_op_commit(records: bool, value: crate::model::cell::CellValue) {
|
||||
use crate::model::cell::CellKey;
|
||||
use improvise_protocol::key::KeyCode;
|
||||
|
||||
let mut app = grid_holding(value.clone(), records);
|
||||
let target = CellKey::new(vec![
|
||||
("Region".into(), "West".into()),
|
||||
("_Measure".into(), "Revenue".into()),
|
||||
]);
|
||||
let at = match records {
|
||||
true => (1, 3),
|
||||
false => (1, 1),
|
||||
};
|
||||
app.cursor_mut().selected = at;
|
||||
if records {
|
||||
app.view_state.mode = AppMode::RecordsNormal;
|
||||
assert_eq!(
|
||||
app.layout.record_col(at.1),
|
||||
Some(&RecordCol::Measure("Revenue".into())),
|
||||
"the cursor is not on the Revenue column"
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
app.model_state.workbook.model.get_cell(&target),
|
||||
Some(&value),
|
||||
"the fixture does not hold the value under test"
|
||||
);
|
||||
press(&mut app, KeyCode::Char('i'));
|
||||
assert!(app.view_state.mode.is_editing(), "`i` did not open an editor");
|
||||
press(&mut app, KeyCode::Enter);
|
||||
let stored = app.model_state.workbook.model.get_cell(&target).cloned();
|
||||
let same = match (&stored, &value) {
|
||||
(Some(CellValue::Number(a)), CellValue::Number(b)) => a.to_bits() == b.to_bits(),
|
||||
(stored, value) => stored.as_ref() == Some(value),
|
||||
};
|
||||
assert!(
|
||||
same,
|
||||
"{} mode: i then Enter on {value:?} stored {stored:?}",
|
||||
if records { "records" } else { "pivot" }
|
||||
);
|
||||
}
|
||||
|
||||
/// BUG (improvise-umi4) — see `context/test-evidence/command.md`.
|
||||
#[test]
|
||||
fn an_untouched_pivot_edit_stores_the_identical_value() {
|
||||
for value in values_display_rounds() {
|
||||
no_op_commit(false, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// BUG (improvise-umi4) — see `context/test-evidence/command.md`.
|
||||
#[test]
|
||||
fn an_untouched_records_edit_stores_the_identical_value() {
|
||||
for value in values_display_rounds() {
|
||||
no_op_commit(true, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Commit commands (mode-specific buffer consumers) ────────────────────────
|
||||
|
||||
@@ -1755,3 +1755,72 @@ fn yy_over_an_aggregate_copies_the_sum_the_host_copies() {
|
||||
"client and host yanked different values over an aggregate"
|
||||
);
|
||||
}
|
||||
|
||||
/// Two regions by two measures, `value` at (South, Revenue): row 1, column 1,
|
||||
/// so "the cell under the cursor" is not "the first cell".
|
||||
fn precise_host(value: improvise_protocol::CellValue) -> App {
|
||||
let mut wb = Workbook::new("Test");
|
||||
wb.add_category("Region").unwrap();
|
||||
wb.add_item("Region", "North").unwrap();
|
||||
wb.add_item("Region", "South").unwrap();
|
||||
wb.add_item("_Measure", "Cost").unwrap();
|
||||
wb.add_item("_Measure", "Revenue").unwrap();
|
||||
wb.active_view_mut().set_axis("Region", Axis::Row);
|
||||
wb.active_view_mut().set_axis("_Measure", Axis::Column);
|
||||
for (region, measure, v) in [
|
||||
("North", "Cost", improvise_protocol::CellValue::Number(1.0)),
|
||||
("North", "Revenue", improvise_protocol::CellValue::Number(2.0)),
|
||||
("South", "Cost", improvise_protocol::CellValue::Number(3.0)),
|
||||
("South", "Revenue", value),
|
||||
] {
|
||||
wb.model.set_cell(region_measure(region, measure), v);
|
||||
}
|
||||
let mut app = App::new(wb, None);
|
||||
app.term_height = 2 + 8;
|
||||
app.rebuild_layout();
|
||||
app.cursor_mut().selected = (1, 1);
|
||||
app
|
||||
}
|
||||
|
||||
/// BUG (improvise-umi4) — see `context/test-evidence/clients.md`.
|
||||
#[test]
|
||||
fn an_untouched_browser_edit_stores_the_identical_value() {
|
||||
use improvise_protocol::CellValue::{Number, Text};
|
||||
let window = (2, 2);
|
||||
for value in [
|
||||
Number(1.23456789),
|
||||
Number(0.1 + 0.2),
|
||||
Number(98765.4321987),
|
||||
Number(123456789012345.67),
|
||||
Number(-0.00001234),
|
||||
Text("0.1 + 0.2".into()),
|
||||
] {
|
||||
let mut host = precise_host(value.clone());
|
||||
let mut client = client_ready_to_edit(&host, window);
|
||||
for key in ["i", "Enter"] {
|
||||
let event = BrowserKey::new(key).to_key_event().unwrap();
|
||||
let KeyOutcome::Local(cmds) = resolve(&client, event) else {
|
||||
panic!("{key}: the client must answer this key locally");
|
||||
};
|
||||
for cmd in &cmds {
|
||||
client.fold(cmd);
|
||||
}
|
||||
apply_on(&mut host, &cmds);
|
||||
}
|
||||
assert!(
|
||||
!client.view.mode.is_editing(),
|
||||
"Enter did not commit, so nothing was written and this proves nothing"
|
||||
);
|
||||
let stored = host
|
||||
.model_state
|
||||
.workbook
|
||||
.model
|
||||
.get_cell(®ion_measure("South", "Revenue"))
|
||||
.cloned();
|
||||
let same = match (&stored, &value) {
|
||||
(Some(Number(a)), Number(b)) => a.to_bits() == b.to_bits(),
|
||||
(stored, value) => stored.as_ref() == Some(value),
|
||||
};
|
||||
assert!(same, "i then Enter on {value:?} stored {stored:?}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user