use super::*;
#[test]
fn osc_133_a_marks_prompt_start_on_cursor_row() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;A\x07");
let events = parser.screen_mut().drain_events();
assert!(events.contains(&ScreenEvent::ShellIntegration {
mark: SemanticPrompt::PromptStart,
}));
assert_eq!(
parser
.screen()
.grid()
.drawing_row(0)
.unwrap()
.semantic_prompt(),
Some(SemanticPrompt::PromptStart),
);
}
#[test]
fn osc_133_d_marks_output_end_with_exit_code() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;D;42\x07");
let events = parser.screen_mut().drain_events();
assert!(events.contains(&ScreenEvent::ShellIntegration {
mark: SemanticPrompt::OutputEnd {
exit_code: Some(42)
},
}));
assert_eq!(
parser
.screen()
.grid()
.drawing_row(0)
.unwrap()
.semantic_prompt(),
Some(SemanticPrompt::OutputEnd {
exit_code: Some(42)
}),
);
}
#[test]
fn osc_133_d_without_exit_code_yields_none() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;D\x1b\\");
let events = parser.screen_mut().drain_events();
assert!(events.contains(&ScreenEvent::ShellIntegration {
mark: SemanticPrompt::OutputEnd { exit_code: None },
}));
}
#[test]
fn osc_133_d_negative_exit_code_round_trips() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;D;-1\x07");
let events = parser.screen_mut().drain_events();
assert!(events.contains(&ScreenEvent::ShellIntegration {
mark: SemanticPrompt::OutputEnd {
exit_code: Some(-1)
},
}));
}
#[test]
fn osc_133_malformed_drops_silently() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133\x07");
process(&mut parser, b"\x1b]133;Z\x07");
process(&mut parser, b"\x1b]133;D;abc\x07");
let events = parser.screen_mut().drain_events();
assert!(
events
.iter()
.all(|e| !matches!(e, ScreenEvent::ShellIntegration { .. })),
"no ShellIntegration event expected, got {events:?}",
);
assert_eq!(
parser
.screen()
.grid()
.drawing_row(0)
.unwrap()
.semantic_prompt(),
None,
);
}
#[test]
fn osc_133_most_recent_wins_on_same_row() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;A\x07");
process(&mut parser, b"\x1b]133;B\x07");
process(&mut parser, b"\x1b]133;C\x07");
assert_eq!(
parser
.screen()
.grid()
.drawing_row(0)
.unwrap()
.semantic_prompt(),
Some(SemanticPrompt::OutputStart),
);
let events = parser.screen_mut().drain_events();
let marks: Vec<_> = events
.iter()
.filter_map(|e| match e {
ScreenEvent::ShellIntegration { mark } => Some(*mark),
_ => None,
})
.collect();
assert_eq!(
marks,
vec![
SemanticPrompt::PromptStart,
SemanticPrompt::PromptEnd,
SemanticPrompt::OutputStart,
],
);
}
#[test]
fn osc_133_marks_separate_rows_after_lf() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]133;A\x07");
process(&mut parser, b"\r\n");
process(&mut parser, b"\x1b]133;C\x07");
let screen = parser.screen();
assert_eq!(
screen.grid().drawing_row(0).unwrap().semantic_prompt(),
Some(SemanticPrompt::PromptStart),
);
assert_eq!(
screen.grid().drawing_row(1).unwrap().semantic_prompt(),
Some(SemanticPrompt::OutputStart),
);
}