1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-24 07:46:59 +03:00

Add some tests for hyperlink parsing and handling

This commit is contained in:
Wez Furlong 2018-02-11 13:48:51 -08:00
parent ac339f9258
commit adc11f303a
5 changed files with 95 additions and 20 deletions

View File

@ -30,7 +30,7 @@ pub enum DecPrivateMode {
#[derive(Debug)]
pub enum CSIAction {
SetPen(CellAttributes),
SetPenNoLink(CellAttributes),
SetForegroundColor(color::ColorAttribute),
SetBackgroundColor(color::ColorAttribute),
SetIntensity(Intensity),
@ -54,6 +54,7 @@ pub enum CSIAction {
SaveCursor,
RestoreCursor,
ScrollLines(i64),
SoftReset,
}
/// Constrol Sequence Initiator (CSI) Parser.
@ -183,12 +184,12 @@ impl<'a> CSIParser<'a> {
// With no parameters, reset to default pen.
// Note that this empty case is only possible for the initial
// iteration.
Some(CSIAction::SetPen(CellAttributes::default()))
Some(CSIAction::SetPenNoLink(CellAttributes::default()))
}
&[0, _..] => {
// Explicitly set to default pen
self.advance_by(1, params);
Some(CSIAction::SetPen(CellAttributes::default()))
Some(CSIAction::SetPenNoLink(CellAttributes::default()))
}
&[38, 2, _colorspace, red, green, blue, _..] => {
// ISO-8613-6 true color foreground
@ -495,6 +496,7 @@ impl<'a> Iterator for CSIParser<'a> {
('l', &[b'?'], Some(params)) => self.dec_reset_mode(params),
('m', &[], Some(params)) => self.sgr(params),
('n', &[], Some(params)) => self.dsr(params),
('p', &[b'!'], Some(&[])) => Some(CSIAction::SoftReset),
('r', &[], Some(params)) => self.set_scroll_region(params),
// SCOSC: Save Cursor

View File

@ -26,6 +26,13 @@ impl Hyperlink {
id: (**id).into(),
}
}
pub fn with_id(url: &str, id: &str) -> Self {
Self {
url: url.into(),
id: id.into(),
}
}
}
/// The spec says that the escape sequence is of the form:

View File

@ -103,7 +103,6 @@ impl Line {
clusters
}
#[allow(dead_code)]
pub fn from_text(s: &str, attrs: &CellAttributes) -> Line {
let mut cells = Vec::new();

View File

@ -777,8 +777,14 @@ impl TerminalState {
fn perform_csi(&mut self, act: CSIAction) {
debug!("{:?}", act);
match act {
CSIAction::SetPen(pen) => {
CSIAction::SoftReset => {
self.pen = CellAttributes::default();
// TODO: see https://vt100.net/docs/vt510-rm/DECSTR.html
}
CSIAction::SetPenNoLink(pen) => {
let link = self.pen.hyperlink.take();
self.pen = pen;
self.pen.hyperlink = link;
}
CSIAction::SetForegroundColor(color) => {
self.pen.foreground = color;

View File

@ -98,6 +98,19 @@ impl TestTerm {
};
self.print(format!("{}K", num));
}
fn hyperlink(&mut self, link: &Rc<Hyperlink>) {
self.print(format!("\x1b]8;id={};{}\x1b\\", link.id, link.url));
}
fn hyperlink_off(&mut self) {
self.print("\x1b]8;;\x1b\\");
}
fn soft_reset(&mut self) {
self.print(CSI);
self.print("!p");
}
}
impl Deref for TestTerm {
@ -190,7 +203,7 @@ bitflags! {
struct Compare : u8{
const TEXT = 1;
const ATTRS = 2;
const DIRTY = 3;
const DIRTY = 4;
}
}
@ -203,20 +216,6 @@ fn print_visible_lines(term: &Terminal) {
}
}
/// Asserts that the visible lines of the terminal have the
/// same cell contents. The cells must exactly match.
#[allow(dead_code)]
fn assert_visible_lines(term: &Terminal, expect_lines: &[Line]) {
print_visible_lines(&term);
let screen = term.screen();
assert_lines_equal(
screen.visible_lines(),
expect_lines,
Compare::ATTRS | Compare::TEXT,
);
}
/// Asserts that the visible lines of the terminal have the
/// same character contents as the expected lines.
/// The other cell attributes are not compared; this is
@ -348,3 +347,65 @@ fn test_delete_lines() {
assert_visible_contents(&term, &["111", "aaa", " ", "bbb", " "]);
assert_dirty_lines!(&term, &[1, 2, 3, 4]);
}
#[test]
fn test_hyperlinks() {
let mut term = TestTerm::new(3, 5, 0);
let link = Rc::new(Hyperlink::with_id("http://example.com", ""));
term.hyperlink(&link);
term.print("hello");
term.hyperlink_off();
let mut linked = CellAttributes::default();
linked.hyperlink = Some(Rc::clone(&link));
assert_lines_equal(
term.screen().visible_lines(),
&[
Line::from_text("hello", &linked),
" ".into(),
" ".into(),
],
Compare::TEXT | Compare::ATTRS,
);
term.hyperlink(&link);
term.print("he");
// Resetting pen should not reset the link
term.print("\x1b[m");
term.print("y!!");
assert_lines_equal(
term.screen().visible_lines(),
&[
Line::from_text("hello", &linked),
Line::from_text("hey!!", &linked),
" ".into(),
],
Compare::TEXT | Compare::ATTRS,
);
let otherlink = Rc::new(Hyperlink::with_id("http://example.com/other", "w00t"));
// Switching link and turning it off
term.hyperlink(&otherlink);
term.print("wo");
// soft reset also disables hyperlink attribute
term.soft_reset();
term.print("00t");
let mut partial_line: Line = "wo00t".into();
partial_line.cells[0].attrs.hyperlink = Some(Rc::clone(&otherlink));
partial_line.cells[1].attrs.hyperlink = Some(Rc::clone(&otherlink));
assert_lines_equal(
term.screen().visible_lines(),
&[
Line::from_text("hello", &linked),
Line::from_text("hey!!", &linked),
partial_line,
],
Compare::TEXT | Compare::ATTRS,
);
}