aboutsummaryrefslogtreecommitdiff
path: root/src/client/shell/tests/graphics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/shell/tests/graphics.rs')
-rw-r--r--src/client/shell/tests/graphics.rs148
1 files changed, 124 insertions, 24 deletions
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"));
}