use super::*;
#[test]
fn xtsave_xtrestore_roundtrips_multiple_modes() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b[?2004h\x1b[?1004h\x1b[?2004;1004s\x1b[?2004l\x1b[?1004l\x1b[?2004;1004r",
);
assert!(parser.screen().mode(TerminalMode::BracketedPaste));
assert!(parser.screen().mode(TerminalMode::FocusInOut));
}
#[test]
fn xtsave_with_no_params_saves_all_modes() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b[?2004h\x1b[?1004h\x1b[?s\x1b[?2004l\x1b[?1004l\x1b[?r",
);
assert!(parser.screen().mode(TerminalMode::BracketedPaste));
assert!(parser.screen().mode(TerminalMode::FocusInOut));
}
#[test]
fn xtrestore_without_prior_save_is_noop() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[?2004h\x1b[?2004r");
assert!(
parser.screen().mode(TerminalMode::BracketedPaste),
"XTRESTORE for a never-saved mode must not change its current state",
);
process(&mut parser, b"\x1b[?2004l\x1b[?2004r");
assert!(
!parser.screen().mode(TerminalMode::BracketedPaste),
"XTRESTORE for a never-saved mode must still leave it cleared",
);
}
#[test]
fn xtsave_overwrites_previous_snapshot() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b[?2004s\x1b[?2004h\x1b[?2004s\x1b[?2004l\x1b[?2004r",
);
assert!(
parser.screen().mode(TerminalMode::BracketedPaste),
"second XTSAVE must overwrite the first; restore must reapply the on bit",
);
}
#[test]
fn xtrestore_emits_mode_changed_on_transition() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[?2004h\x1b[?2004s\x1b[?2004l");
parser.screen_mut().drain_events();
process(&mut parser, b"\x1b[?2004r");
let events = parser.screen_mut().drain_events();
assert!(
events.contains(&ScreenEvent::ModeChanged {
mode: TerminalMode::BracketedPaste,
enabled: true,
}),
"XTRESTORE re-enabling BracketedPaste must emit ModeChanged; got {events:?}",
);
}
#[test]
fn xtsave_unrecognized_mode_is_ignored() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[?9999s\x1b[?2004h\x1b[?9999r");
assert!(
parser.screen().mode(TerminalMode::BracketedPaste),
"XTRESTORE for an unrecognized mode must not touch unrelated state",
);
}
#[test]
fn xtsave_mode_9_round_trip() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[?9h\x1b[?9s\x1b[?9l\x1b[?9r");
assert!(
parser.screen().mode(TerminalMode::MouseReportX10),
"XTRESTORE ?9 must reapply the X10 mouse bit saved by XTSAVE ?9",
);
}
#[test]
fn xtsave_mode_67_round_trip() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b[?67h\x1b[?67s\x1b[?67l\x1b[?67r");
assert!(
parser.screen().mode(TerminalMode::BackspaceBs),
"XTRESTORE ?67 must reapply the DECBKM bit saved by XTSAVE ?67",
);
}