use std::num::NonZeroU64;
use ratatui::Terminal;
use ratatui::backend::TestBackend;
use ratatui::layout::Rect;
use kimun_notes::components::text_editor::snapshot::EditorSnapshot;
use kimun_notes::components::text_editor::view::{MarkdownEditorView, Overlay, OverlayKind};
use kimun_notes::settings::themes::Theme;
fn z_cell_and_highlight(line: &str) -> (Option<(usize, usize)>, Vec<usize>) {
let col = line.chars().position(|c| c == 'Z').expect("the marker");
let lines = vec![line.to_string(), String::new()];
let revision = NonZeroU64::new(1).expect("one is not zero");
let snapshot = EditorSnapshot::borrowed(&lines, (1, 0), revision);
let rect = Rect {
x: 0,
y: 0,
width: 24,
height: 10,
};
let theme = Theme::default();
let mut view = MarkdownEditorView::new();
view.update(&snapshot, rect);
view.set_overlays(vec![Overlay::new(
0,
col,
col + 1,
OverlayKind::CurrentMatch,
)]);
let mut terminal = Terminal::new(TestBackend::new(rect.width, rect.height)).expect("backend");
terminal
.draw(|frame| view.render(frame, rect, &theme, false, None))
.expect("draw");
let buffer = terminal.backend().buffer();
let base = buffer.cell((0u16, 9u16)).expect("blank row").bg;
let mut z = None;
for y in 0..rect.height {
for x in 0..rect.width {
if buffer.cell((x, y)).expect("inside the pane").symbol() == "Z" {
z = Some((y as usize, x as usize));
}
}
}
let Some((row, _)) = z else {
return (None, Vec::new());
};
let highlighted = (0..rect.width)
.filter(|&x| buffer.cell((x, row as u16)).expect("inside").bg != base)
.map(|x| x as usize)
.collect();
(z, highlighted)
}
fn assert_overlay_lands_on_z(line: &str) {
let (z, highlighted) = z_cell_and_highlight(line);
let (row, cell) = z.unwrap_or_else(|| panic!("{line:?}: the marker was never painted"));
assert_eq!(
highlighted,
vec![cell],
"{line:?}: the marker paints at visual row {row}, cell {cell}, \
so the overlay belongs there"
);
}
fn assert_overlay_lands_on_z_on_a_continuation_row(line: &str) {
let (z, _) = z_cell_and_highlight(line);
let (row, _) = z.unwrap_or_else(|| panic!("{line:?}: the marker was never painted"));
assert!(
row > 0,
"{line:?}: expected to wrap, but the marker is on row 0"
);
assert_overlay_lands_on_z(line);
}
#[test]
fn an_overlay_paints_on_the_cell_its_char_occupies() {
for line in ["a Z", "> a Z", "- a Z", "## h Z"] {
assert_overlay_lands_on_z(line);
}
}
#[test]
fn a_tab_does_not_shift_an_overlay_off_its_char() {
for line in ["a\tZ", "- a\tZ", "## h\tZ"] {
assert_overlay_lands_on_z(line);
}
}
#[test]
fn a_blockquote_bar_and_a_tab_do_not_shift_an_overlay() {
assert_overlay_lands_on_z("> a\tZ");
assert_overlay_lands_on_z("> > a\tZ");
}
#[test]
fn a_tab_on_a_wrapped_blockquote_row_keeps_its_overlay() {
assert_overlay_lands_on_z_on_a_continuation_row("> aaaa bbbb cccc dddd eeee ff\tZ");
}