use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use typ_buffer::{Position, Selection};
use typ_core::{Panel, RenderContext, ThemeColors};
use typ_panel_editor::EditorPanel;
fn pos(line: usize, col: usize) -> Position {
Position { line, col }
}
fn render(panel: &mut EditorPanel, area: Rect) -> Buffer {
let theme = ThemeColors::default();
let ctx = RenderContext {
theme: &theme,
is_focused: true,
panel_index: 0,
terminal_width: area.width,
terminal_height: area.height,
};
let mut buf = Buffer::empty(area);
panel.render(area, &mut buf, &ctx);
buf
}
const AREA: Rect = Rect {
x: 0,
y: 0,
width: 24,
height: 6,
};
fn tx(col: u16) -> u16 {
3 + col
}
fn ty(line: u16) -> u16 {
1 + line
}
#[test]
fn the_cursors_line_is_tinted_across_the_whole_text_width() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("ab\ncd\n");
let buf = render(&mut panel, AREA);
for col in 0..20 {
assert_eq!(
buf[(tx(col), ty(0))].bg,
theme.cursor_line_bg,
"column {col} of the cursor's line should be tinted"
);
}
}
#[test]
fn other_lines_are_left_alone() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("ab\ncd\n");
let buf = render(&mut panel, AREA);
assert_eq!(buf[(tx(0), ty(1))].bg, theme.bg);
}
#[test]
fn the_highlight_stops_at_the_gutter() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("ab\ncd\n");
let buf = render(&mut panel, AREA);
assert_eq!(buf[(1, ty(0))].bg, theme.gutter_bg);
}
#[test]
fn every_cursors_line_is_highlighted_not_just_the_primarys() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("ab\ncd\nef\n");
panel.set_selections_for_test(vec![
Selection::caret(pos(0, 0)),
Selection::caret(pos(2, 0)),
]);
let buf = render(&mut panel, AREA);
assert_eq!(buf[(tx(0), ty(0))].bg, theme.cursor_line_bg);
assert_eq!(buf[(tx(0), ty(2))].bg, theme.cursor_line_bg);
assert_eq!(buf[(tx(0), ty(1))].bg, theme.bg, "the gap is not a cursor");
}
#[test]
fn a_line_with_a_real_selection_on_it_loses_the_stripe() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("abcdef\nghi\n");
panel.set_selections_for_test(vec![Selection {
anchor: pos(0, 0),
head: pos(0, 3),
}]);
let buf = render(&mut panel, AREA);
assert_eq!(
buf[(tx(5), ty(0))].bg,
theme.bg,
"past the selection, on a line with a non-empty selection, is plain"
);
}
#[test]
fn the_primary_selection_is_drawn_in_its_own_colour() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("abc\ndef\n");
panel.set_selections_for_test(vec![
Selection {
anchor: pos(0, 0),
head: pos(0, 2),
},
Selection {
anchor: pos(1, 0),
head: pos(1, 2),
},
]);
let buf = render(&mut panel, AREA);
assert_eq!(
buf[(tx(0), ty(1))].bg,
theme.selection_primary_bg,
"the primary is the one every motion is relative to"
);
assert_eq!(buf[(tx(0), ty(0))].bg, theme.selection_bg);
}
#[test]
fn a_lone_selection_is_the_primary_one() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("abc\n");
panel.set_selections_for_test(vec![Selection {
anchor: pos(0, 0),
head: pos(0, 2),
}]);
let buf = render(&mut panel, AREA);
assert_eq!(buf[(tx(0), ty(0))].bg, theme.selection_primary_bg);
}
#[test]
fn both_halves_of_a_matched_pair_are_highlighted() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("fn f() {\n}\n");
panel.set_selections_for_test(vec![Selection::caret(pos(0, 7))]);
let buf = render(&mut panel, AREA);
assert_eq!(buf[(tx(7), ty(0))].bg, theme.bracket_match_bg, "the open");
assert_eq!(buf[(tx(7), ty(0))].fg, theme.bracket_match_fg);
assert_eq!(buf[(tx(0), ty(1))].bg, theme.bracket_match_bg, "the close");
}
#[test]
fn an_unmatched_bracket_is_drawn_plainly_and_silently() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("fn f( {\n");
panel.set_selections_for_test(vec![Selection::caret(pos(0, 4))]);
let buf = render(&mut panel, AREA);
assert_ne!(buf[(tx(4), ty(0))].bg, theme.bracket_match_bg);
}
#[test]
fn a_selection_wins_over_a_bracket_highlight() {
let theme = ThemeColors::default();
let mut panel = EditorPanel::from_str("(abc)\n");
panel.set_selections_for_test(vec![Selection {
anchor: pos(0, 0),
head: pos(0, 5),
}]);
let buf = render(&mut panel, AREA);
assert_eq!(buf[(tx(0), ty(0))].bg, theme.selection_primary_bg);
}