diff --git a/crates/improvise-wasm-client/tests/lockstep.rs b/crates/improvise-wasm-client/tests/lockstep.rs index d7106c90..08badb7f 100644 --- a/crates/improvise-wasm-client/tests/lockstep.rs +++ b/crates/improvise-wasm-client/tests/lockstep.rs @@ -2712,12 +2712,14 @@ fn sent( /// held. See `context/test-evidence/clients.md`. #[test] fn keys_sent_before_a_scroll_is_answered_agree_with_the_tui() { - let cases: [Pipelined; 5] = [ + let cases: [Pipelined; 7] = [ ("wrap", (2, 6), ((2, 0), 1, 0), &["i", "Enter", "8", "Enter"]), ("horizontal wrap", (2, 1), ((2, 0), 1, 0), &["i", "Enter", "8", "Enter"]), ("G", (2, 6), ((0, 0), 0, 0), &["G", "i", "7", "Enter"]), ("$", (2, 1), ((0, 0), 0, 0), &["$", "i", "7", "Enter"]), ("gg", (2, 6), ((2, 0), 1, 0), &["g", "g", "i", "7", "Enter"]), + ("$ x", (2, 1), ((0, 0), 0, 0), &["$", "x"]), + ("gg p", (2, 6), ((2, 0), 1, 0), &["y", "y", "g", "g", "p"]), ]; for (name, window, (at, row_offset, col_offset), keys) in cases { let mut tui = wrapping_host(); @@ -2764,13 +2766,15 @@ fn keys_sent_before_a_scroll_is_answered_agree_with_the_tui() { "{what}: a write was composed before its target was projected" ); assert!( - client.view.mode.is_editing() && !client.view.status_msg.is_empty(), - "{what}: Enter must wait out loud with the editor open: {:?}, {:?}", + client.view.mode.is_editing() == keys.contains(&"i") + && !client.view.status_msg.is_empty(), + "{what}: the last key must wait out loud, any editor open: {:?}, {:?}", client.view.mode, client.view.status_msg ); deliver(replies, session, &mut client); - let reply = sent(&mut host, session, &mut client, "Enter"); + let retry = keys.last().expect("a key"); + let reply = sent(&mut host, session, &mut client, retry); deliver(reply, session, &mut client); } assert_eq!( @@ -2800,3 +2804,50 @@ fn keys_sent_before_a_scroll_is_answered_agree_with_the_tui() { } } } + +/// improvise-7mro: a cell inside the held window whose offsets the client has +/// moved is read at its own position. See `context/test-evidence/clients.md`. +#[test] +fn a_held_cell_is_read_at_its_position_and_not_its_cache_index() { + let keys = ["k", "k", "j", "i"]; + let mut tui = wrapping_host(); + tui.cursor_mut().selected = (2, 0); + for k in keys { + reduce_key(&mut tui, BrowserKey::new(k).to_key_event().unwrap()); + } + assert_eq!(tui.view_state.cursor().selected, (1, 0), "setup: on Profit/Jan"); + + let mut host = improvise_command::ui::host::Host::new(wrapping_host()); + let (session, welcome) = host.connect(2, 6); + let mut client = ClientState { + window: (2, 6), + ..ClientState::default() + }; + deliver(vec![welcome], session, &mut client); + let placed = vec![ + improvise_protocol::Command::SetSelected { row: 2, col: 0 }, + improvise_protocol::Command::SetRowOffset(1), + ]; + client.fold_outgoing(&placed); + deliver( + host.handle(session, ClientFrame::Commands(placed)), + session, + &mut client, + ); + for k in keys { + let _held = sent(&mut host, session, &mut client, k); + } + let cursor = client.view.cursor(); + assert_eq!( + (cursor.selected, cursor.row_offset, client.grid.row_frame.first), + ((1, 0), 0, 1), + "setup: inside the held window, offsets ahead of it" + ); + assert_eq!( + format!("{:?}", client.view.mode), + format!("{:?}", tui.view_state.mode), + "the client read another row's cell: {:?}", + client.view.buffers.get("edit") + ); + assert_eq!(client.view.status_msg, tui.view_state.status_msg); +}