use super::*;
#[test]
fn xtwinops_22_23_t_push_pop_both_round_trips() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;outer\x07");
process(&mut parser, b"\x1b]1;outer-icon\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[22;0t");
assert_eq!(parser.screen().title(), "outer");
assert_eq!(parser.screen().icon_name(), "outer-icon");
assert!(parser.screen_mut().drain_events().is_empty());
process(&mut parser, b"\x1b]0;inner\x07");
let _ = parser.screen_mut().drain_events();
assert_eq!(parser.screen().title(), "inner");
assert_eq!(parser.screen().icon_name(), "inner");
process(&mut parser, b"\x1b[23;0t");
assert_eq!(parser.screen().title(), "outer");
assert_eq!(parser.screen().icon_name(), "outer-icon");
let events = parser.screen_mut().drain_events();
assert!(events.contains(&ScreenEvent::TitleChanged));
}
#[test]
fn xtwinops_22_23_t_default_zero_param() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;outer\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[22t");
process(&mut parser, b"\x1b]2;inner\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23t");
assert_eq!(parser.screen().title(), "outer");
}
#[test]
fn xtwinops_22_23_t_selective_icon_only() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;window\x07");
process(&mut parser, b"\x1b]1;icon-outer\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[22;1t");
process(&mut parser, b"\x1b]1;icon-inner\x07");
process(&mut parser, b"\x1b]2;window-replaced\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23;1t");
assert_eq!(parser.screen().icon_name(), "icon-outer");
assert_eq!(parser.screen().title(), "window-replaced");
}
#[test]
fn xtwinops_22_23_t_selective_title_only() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;window-outer\x07");
process(&mut parser, b"\x1b]1;icon\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[22;2t");
process(&mut parser, b"\x1b]2;window-inner\x07");
process(&mut parser, b"\x1b]1;icon-replaced\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23;2t");
assert_eq!(parser.screen().title(), "window-outer");
assert_eq!(parser.screen().icon_name(), "icon-replaced");
}
#[test]
fn xtwinops_22_t_caps_at_ten_with_fifo_drop() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
for i in 0..11 {
let osc = format!("\x1b]2;t{i}\x07");
process(&mut parser, osc.as_bytes());
process(&mut parser, b"\x1b[22;2t");
}
let _ = parser.screen_mut().drain_events();
for _ in 0..10 {
process(&mut parser, b"\x1b[23;2t");
}
assert_eq!(parser.screen().title(), "t1");
let title_before = parser.screen().title().to_string();
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23;2t");
assert_eq!(parser.screen().title(), title_before);
let events = parser.screen_mut().drain_events();
assert!(!events.contains(&ScreenEvent::TitleChanged));
}
#[test]
fn xtwinops_23_t_pop_on_empty_stack_is_noop() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;only\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23;0t");
assert_eq!(parser.screen().title(), "only");
let events = parser.screen_mut().drain_events();
assert!(!events.contains(&ScreenEvent::TitleChanged));
}
#[test]
fn xtwinops_22_23_t_persists_across_alt_screen_toggle() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;outer\x07");
let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[22;0t");
process(&mut parser, b"\x1b[?1049h");
process(&mut parser, b"\x1b]2;alt\x07");
process(&mut parser, b"\x1b[?1049l");
process(&mut parser, b"\x1b[23;0t");
assert_eq!(parser.screen().title(), "outer");
}
#[test]
fn xtwinops_22_23_t_ris_clears_stack() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]2;outer\x07");
process(&mut parser, b"\x1b[22;0t");
process(&mut parser, b"\x1bc"); let _ = parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[23;0t");
assert_eq!(parser.screen().title(), "");
let events = parser.screen_mut().drain_events();
assert!(!events.contains(&ScreenEvent::TitleChanged));
}
#[test]
fn xtwinops_text_area_cells() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[18t");
assert_eq!(drain_replies(&mut parser), b"\x1b[8;24;80t");
}
#[test]
fn xtwinops_text_area_cells_custom_size() {
let mut parser = crate::Parser::new(
TerminalSize {
rows: 40,
cols: 132,
},
0,
);
process(&mut parser, b"\x1b[18t");
assert_eq!(drain_replies(&mut parser), b"\x1b[8;40;132t");
}
#[test]
fn xtwinops_cell_size_pixels() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
parser.screen_mut().set_pixel_cell_size(CellPixelSize {
width: 8,
height: 16,
});
process(&mut parser, b"\x1b[16t");
assert_eq!(drain_replies(&mut parser), b"\x1b[6;16;8t");
}
#[test]
fn xtwinops_cell_size_pixels_unknown() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[16t");
assert!(drain_replies(&mut parser).is_empty());
}
#[test]
fn xtwinops_text_area_pixels() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
parser.screen_mut().set_pixel_cell_size(CellPixelSize {
width: 8,
height: 16,
});
process(&mut parser, b"\x1b[14t");
assert_eq!(drain_replies(&mut parser), b"\x1b[4;384;640t");
}
#[test]
fn xtwinops_text_area_pixels_unknown() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[14t");
assert!(drain_replies(&mut parser).is_empty());
}
#[test]
fn xtwinops_text_area_pixels_no_reply_when_height_is_zero() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
parser.screen_mut().set_pixel_cell_size(CellPixelSize {
width: 12,
height: 0,
});
process(&mut parser, b"\x1b[14t");
assert!(drain_replies(&mut parser).is_empty());
}
#[test]
fn xtwinops_cell_size_pixels_no_reply_when_height_is_zero() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
parser.screen_mut().set_pixel_cell_size(CellPixelSize {
width: 12,
height: 0,
});
process(&mut parser, b"\x1b[16t");
assert!(drain_replies(&mut parser).is_empty());
}