use super::*;
#[test]
fn osc_8_hyperlink() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b]8;;https://example.com\x07link\x1b]8;;\x07plain",
);
let screen = parser.screen();
assert_eq!(
screen
.cell(0, 0)
.unwrap()
.hyperlink()
.map(|h| h.uri.as_ref()),
Some("https://example.com")
);
assert_eq!(
screen
.cell(0, 3)
.unwrap()
.hyperlink()
.map(|h| h.uri.as_ref()),
Some("https://example.com")
);
assert_eq!(
screen
.cell(0, 0)
.unwrap()
.hyperlink()
.and_then(|h| h.id.as_deref()),
None
);
assert!(screen.cell(0, 4).unwrap().hyperlink().is_none());
}
#[test]
fn osc_8_hyperlink_with_params() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b]8;id=foo;https://example.com\x07X\x1b]8;;\x07",
);
let screen = parser.screen();
assert_eq!(
screen
.cell(0, 0)
.unwrap()
.hyperlink()
.map(|h| h.uri.as_ref()),
Some("https://example.com")
);
}
#[test]
fn osc_8_hyperlink_st_terminator() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b]8;;https://example.com\x1b\\X\x1b]8;;\x1b\\",
);
let screen = parser.screen();
assert_eq!(
screen
.cell(0, 0)
.unwrap()
.hyperlink()
.map(|h| h.uri.as_ref()),
Some("https://example.com")
);
}
#[test]
fn osc_8_reset_by_ris() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]8;;https://example.com\x07\x1bcX");
let screen = parser.screen();
assert!(screen.cell(0, 0).unwrap().hyperlink().is_none());
}
#[test]
fn osc_8_hyperlink_preserves_id() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]8;id=foo;https://x\x07A\x1b]8;;\x07");
let screen = parser.screen();
let link = screen
.cell(0, 0)
.unwrap()
.hyperlink()
.expect("link present");
assert_eq!(link.id.as_deref(), Some("foo"));
assert_eq!(link.uri.as_ref(), "https://x");
}
#[test]
fn osc_8_adjacent_spans_with_different_ids_do_not_merge() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b]8;id=A;https://x\x07A\x1b]8;id=B;https://x\x07B\x1b]8;;\x07",
);
let screen = parser.screen();
let link_a = screen.cell(0, 0).unwrap().hyperlink().expect("A link");
let link_b = screen.cell(0, 1).unwrap().hyperlink().expect("B link");
assert_eq!(link_a.uri, link_b.uri);
assert_ne!(
link_a, link_b,
"adjacent OSC 8 spans with different ids must remain distinct hyperlinks",
);
assert_eq!(link_a.id.as_deref(), Some("A"));
assert_eq!(link_b.id.as_deref(), Some("B"));
}
#[test]
fn osc_8_unknown_key_is_ignored() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, b"\x1b]8;foo=bar;https://x\x07A\x1b]8;;\x07");
let screen = parser.screen();
let link = screen
.cell(0, 0)
.unwrap()
.hyperlink()
.expect("link present");
assert_eq!(link.id, None);
assert_eq!(link.uri.as_ref(), "https://x");
}
#[test]
fn osc_8_id_with_colon_separator() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(
&mut parser,
b"\x1b]8;id=foo:bar=baz;https://x\x07A\x1b]8;;\x07",
);
let screen = parser.screen();
let link = screen
.cell(0, 0)
.unwrap()
.hyperlink()
.expect("link present");
assert_eq!(link.id.as_deref(), Some("foo"));
assert_eq!(link.uri.as_ref(), "https://x");
}