diff options
Diffstat (limited to 'src/client/shell/tests')
| -rw-r--r-- | src/client/shell/tests/copy.rs | 2 | ||||
| -rw-r--r-- | src/client/shell/tests/graphics.rs | 148 | ||||
| -rw-r--r-- | src/client/shell/tests/input.rs | 14 | ||||
| -rw-r--r-- | src/client/shell/tests/text_editing.rs | 2 |
4 files changed, 136 insertions, 30 deletions
diff --git a/src/client/shell/tests/copy.rs b/src/client/shell/tests/copy.rs index 112417fc..67e36f23 100644 --- a/src/client/shell/tests/copy.rs +++ b/src/client/shell/tests/copy.rs @@ -1563,7 +1563,7 @@ fn navigator_narrow_layout_and_long_search_stay_inside_the_popup() { navigator.query = "界".repeat(100).as_str().into(); let frame = state.compose(width, height).expect("navigator frame"); let popup = state.hits.navigator_popup; - let cursor = frame.cursor.expect("search cursor"); + let cursor = frame.cursor.as_ref().expect("search cursor"); assert!(super::super::contains(popup, (cursor.x, cursor.y))); assert!(state.hits.navigator_rows.is_empty()); assert!(popup.right() <= width && popup.bottom() <= height); diff --git a/src/client/shell/tests/graphics.rs b/src/client/shell/tests/graphics.rs index 240e031c..e54301a4 100644 --- a/src/client/shell/tests/graphics.rs +++ b/src/client/shell/tests/graphics.rs @@ -63,6 +63,48 @@ fn add_main_image( surface.graphics.placements.push(placement); } +#[cfg(unix)] +#[test] +fn failed_direct_ack_composition_restores_graphics_for_inline_retry() { + use crate::kitty_graphics::surface::host_image_id; + + let mut state = ClientShellState::new(ClientShellConfig::from_config(&Config::default())); + state.set_snapshot(Box::new(snapshot())); + let mut pane = surface(); + let (mut asset, mut placement) = image( + SurfaceGraphicsTarget::Pane { + pane_id: "pane_1".into(), + }, + 0, + 0, + 71, + ); + asset.key.source = SurfaceGraphicsSource::PaneLayer { + pane_id: "pane_1".into(), + layer_id: "direct-rollback".into(), + }; + placement.asset = asset.key.clone(); + let key = asset.key.clone(); + pane.graphics.assets.push(asset); + pane.graphics.placements.push(placement); + state.set_pane_surface(pane); + + // Model an ACK arriving while projection pairing makes composition unavailable. + state.pending_pane_surface = Some(surface()); + let image_id = host_image_id(state.graphics_scope(), &key); + let graphics_before = format!("{:?}", state.graphics); + let checkpoint = state.direct_graphics_checkpoint(); + assert!(state.trust_direct_graphics_asset(&key, image_id)); + assert!(state.compose(106, 20).is_none()); + state.restore_direct_graphics_checkpoint(checkpoint); + assert_eq!(format!("{:?}", state.graphics), graphics_before); + + // Once pairing is available, fallback still owns the asset and uploads it normally. + state.pending_pane_surface = None; + let retry = state.compose(106, 20).expect("fallback frame"); + assert!(String::from_utf8_lossy(&retry.graphics.into_inline_bytes()).contains("a=t")); +} + fn is_placed(bytes: &[u8], point: (u16, u16)) -> bool { String::from_utf8_lossy(bytes).contains(&format!("\x1b[{};{}H", point.1 + 1, point.0 + 1)) } @@ -85,11 +127,11 @@ fn assert_graphics_cover(state: &mut ClientShellState, covered: Rect, cols: u16, state.set_pane_surface(surface); let frame = state.compose(cols, rows).unwrap(); assert!( - is_placed(&frame.graphics, outside), + is_placed(&frame.graphics.clone().into_inline_bytes(), outside), "outside={outside:?} cover={covered:?}" ); assert!( - !is_placed(&frame.graphics, inside), + !is_placed(&frame.graphics.clone().into_inline_bytes(), inside), "inside={inside:?} cover={covered:?}" ); } @@ -327,18 +369,38 @@ fn every_dialog_and_menu_occludes_its_panel_not_the_whole_screen() { state.compose(106, 40).unwrap(); state.overlay = Some(overlay); let frame = state.compose(106, 40).unwrap(); - assert!(is_placed(&frame.graphics, outside), "{:?}", state.overlay); + assert!( + is_placed(&frame.graphics.clone().into_inline_bytes(), outside), + "{:?}", + state.overlay + ); if let Some(border) = border { - assert!(!is_placed(&frame.graphics, border), "{:?}", state.overlay); - assert!(String::from_utf8_lossy(&frame.graphics).contains("a=d,d=i")); + assert!( + !is_placed(&frame.graphics.clone().into_inline_bytes(), border), + "{:?}", + state.overlay + ); + assert!( + String::from_utf8_lossy(&frame.graphics.clone().into_inline_bytes()) + .contains("a=d,d=i") + ); } state.overlay = None; let restored = state.compose(106, 40).unwrap(); - assert!(is_placed(&restored.graphics, outside)); + assert!(is_placed( + &restored.graphics.clone().into_inline_bytes(), + outside + )); if let Some(border) = border { - assert!(is_placed(&restored.graphics, border)); + assert!(is_placed( + &restored.graphics.clone().into_inline_bytes(), + border + )); } - assert!(!String::from_utf8_lossy(&restored.graphics).contains("a=t")); + assert!( + !String::from_utf8_lossy(&restored.graphics.clone().into_inline_bytes()) + .contains("a=t") + ); } } @@ -377,17 +439,26 @@ fn selection_copy_cursor_and_search_hide_only_the_highlighted_images() { }); let frame = state.compose(106, 20).unwrap(); for point in &points[..3] { - assert!(!is_placed(&frame.graphics, *point), "{point:?}"); + assert!( + !is_placed(&frame.graphics.clone().into_inline_bytes(), *point), + "{point:?}" + ); } - assert!(is_placed(&frame.graphics, points[3])); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + points[3] + )); state.mode = ClientShellMode::Terminal; state.copy_mode = None; state.selection = None; let frame = state.compose(106, 20).unwrap(); for point in points { - assert!(is_placed(&frame.graphics, point)); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + point + )); } - assert!(!String::from_utf8_lossy(&frame.graphics).contains("a=t")); + assert!(!String::from_utf8_lossy(&frame.graphics.clone().into_inline_bytes()).contains("a=t")); } #[test] @@ -400,15 +471,26 @@ fn mobile_switcher_still_hides_the_entire_underlying_surface() { add_main_image(&mut surface, layout, point, 1); state.set_pane_surface(surface); let frame = state.compose(40, 24).unwrap(); - assert!(is_placed(&frame.graphics, point)); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + point + )); state.mode = ClientShellMode::Navigate; let frame = state.compose(40, 24).unwrap(); - assert!(!is_placed(&frame.graphics, point)); - assert!(String::from_utf8_lossy(&frame.graphics).contains("a=d,d=i")); + assert!(!is_placed( + &frame.graphics.clone().into_inline_bytes(), + point + )); + assert!( + String::from_utf8_lossy(&frame.graphics.clone().into_inline_bytes()).contains("a=d,d=i") + ); state.mode = ClientShellMode::Terminal; let frame = state.compose(40, 24).unwrap(); - assert!(is_placed(&frame.graphics, point)); - assert!(!String::from_utf8_lossy(&frame.graphics).contains("a=t")); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + point + )); + assert!(!String::from_utf8_lossy(&frame.graphics.clone().into_inline_bytes()).contains("a=t")); } #[test] @@ -437,15 +519,33 @@ fn popup_terminal_keeps_own_graphics_and_hides_only_background_overlap() { surface.graphics.placements.push(placement); state.set_pane_surface(surface); let frame = state.compose(106, 20).unwrap(); - assert!(is_placed(&frame.graphics, outside)); - assert!(!is_placed(&frame.graphics, border)); - assert!(is_placed(&frame.graphics, inside)); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + outside + )); + assert!(!is_placed( + &frame.graphics.clone().into_inline_bytes(), + border + )); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + inside + )); state.overlay = Some(ClientShellOverlay::Onboarding); let frame = state.compose(106, 20).unwrap(); - assert!(is_placed(&frame.graphics, outside)); - assert!(!is_placed(&frame.graphics, inside)); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + outside + )); + assert!(!is_placed( + &frame.graphics.clone().into_inline_bytes(), + inside + )); state.overlay = None; let frame = state.compose(106, 20).unwrap(); - assert!(is_placed(&frame.graphics, inside)); - assert!(!String::from_utf8_lossy(&frame.graphics).contains("a=t")); + assert!(is_placed( + &frame.graphics.clone().into_inline_bytes(), + inside + )); + assert!(!String::from_utf8_lossy(&frame.graphics.clone().into_inline_bytes()).contains("a=t")); } diff --git a/src/client/shell/tests/input.rs b/src/client/shell/tests/input.rs index b55cf9a2..b54548f2 100644 --- a/src/client/shell/tests/input.rs +++ b/src/client/shell/tests/input.rs @@ -216,18 +216,24 @@ fn client_shell_graphics_follow_final_shell_origin_and_local_overlay_visibility( state.set_pane_surface(pane_surface); let visible = state.compose(106, 20).expect("visible graphics frame"); - let visible = String::from_utf8_lossy(&visible.graphics); + let visible = visible.graphics.clone().into_inline_bytes(); + let visible = String::from_utf8_lossy(&visible); assert!(visible.contains("a=t,t=d")); assert!(visible.contains("\u{1b}[2;27H")); state.overlay = Some(ClientShellOverlay::Onboarding); let uncovered = state.compose(106, 20).expect("overlay frame"); - assert!(!String::from_utf8_lossy(&uncovered.graphics).contains("a=d")); - assert!(String::from_utf8_lossy(&uncovered.graphics).contains("a=p")); + assert!( + !String::from_utf8_lossy(&uncovered.graphics.clone().into_inline_bytes()).contains("a=d") + ); + assert!( + String::from_utf8_lossy(&uncovered.graphics.clone().into_inline_bytes()).contains("a=p") + ); state.overlay = None; let restored = state.compose(106, 20).expect("restored graphics frame"); - let restored = String::from_utf8_lossy(&restored.graphics); + let restored = restored.graphics.clone().into_inline_bytes(); + let restored = String::from_utf8_lossy(&restored); assert!(restored.contains("a=p")); assert!(!restored.contains("a=t,t=d")); } diff --git a/src/client/shell/tests/text_editing.rs b/src/client/shell/tests/text_editing.rs index b63ce9f6..118a606e 100644 --- a/src/client/shell/tests/text_editing.rs +++ b/src/client/shell/tests/text_editing.rs @@ -384,7 +384,7 @@ fn every_field_renders_long_unicode_across_resize_without_mutation() { for (width, height) in [(120, 40), (60, 20), (12, 6), (1, 1), (120, 40)] { let before = editor(&mut state).clone(); if let Some(frame) = state.compose(width, height) { - if let Some(cursor) = frame.cursor.filter(|cursor| cursor.visible) { + if let Some(cursor) = frame.cursor.as_ref().filter(|cursor| cursor.visible) { assert!(cursor.x < width && cursor.y < height, "field {field}"); } } |
