use super::*;
use crate::base::Size;
use crate::theme::default_theme;
use crate::widgets::test_util::{draw_into, row};
const DOC: &str = "# Title\n\nBody with `code` inline.\n\n- first\n- second\n\n> wisdom\n\n```\nfn main() {}\n```\n";
fn cell_of(row: &str, needle: &str) -> i32 {
let byte = row.find(needle).unwrap();
row[..byte].chars().count() as i32
}
#[test]
fn heading_list_quote_and_fence_chrome() {
let t = default_theme().tokens;
let c = draw_into(MarkdownView::new(DOC).element(&t), Size::new(28, 14));
let title_y = 0;
assert!(row(&c, title_y).starts_with("Title"));
assert_eq!(c.cell(Point::new(0, title_y)).unwrap().1, t.accent);
assert!(row(&c, title_y + 1).starts_with('─'));
assert_eq!(c.cell(Point::new(0, title_y + 1)).unwrap().1, t.border);
let body_y = (0..14).find(|y| row(&c, *y).contains("code")).unwrap();
let cx = cell_of(&row(&c, body_y), "code");
assert_eq!(c.cell(Point::new(cx, body_y)).unwrap().2, t.surface_raised);
let li_y = (0..14).find(|y| row(&c, *y).contains("• first")).unwrap();
let mx = cell_of(&row(&c, li_y), "•");
assert_eq!(c.cell(Point::new(mx, li_y)).unwrap().1, t.accent_alt);
let q_y = (0..14).find(|y| row(&c, *y).contains("wisdom")).unwrap();
assert_eq!(c.cell(Point::new(0, q_y)).unwrap().0, 'â–Ž');
let wx = cell_of(&row(&c, q_y), "wisdom");
assert_eq!(c.cell(Point::new(wx, q_y)).unwrap().1, t.text_muted);
let f_y = (0..14).find(|y| row(&c, *y).contains("fn main")).unwrap();
let fx = cell_of(&row(&c, f_y), "fn");
let (_, fg, bg) = c.cell(Point::new(fx, f_y)).unwrap();
assert_eq!(fg, t.syntax_keyword);
assert_eq!(bg, t.surface_raised);
}
#[test]
fn outline_rows_and_scroll_share_the_fold() {
let t = default_theme().tokens;
assert_eq!(
MarkdownView::outline(DOC, &t),
vec![(1, "Title".to_string())]
);
let total = MarkdownView::rows(DOC, &t, 28);
assert!(total >= 10, "typeset rows: {total}");
let c = draw_into(
MarkdownView::new(DOC).scroll_offset(1).element(&t),
Size::new(28, 6),
);
assert!(!row(&c, 0).contains("Title"));
}
#[test]
fn diff_fences_tint_added_removed_and_plain_fences_stay_clike() {
let t = default_theme().tokens;
let doc = "```diff\n-old line\n+new line\n```\n\n```\nfn main() {}\n```\n";
let c = draw_into(MarkdownView::new(doc).element(&t), Size::new(28, 10));
let minus_y = (0..10).find(|y| row(&c, *y).contains("-old")).unwrap();
let mx = cell_of(&row(&c, minus_y), "-old");
let (_, fg, bg) = c.cell(Point::new(mx, minus_y)).unwrap();
assert_eq!(fg, t.error);
assert_eq!(bg, t.surface_raised);
let plus_y = (0..10).find(|y| row(&c, *y).contains("+new")).unwrap();
let px = cell_of(&row(&c, plus_y), "+new");
assert_eq!(c.cell(Point::new(px, plus_y)).unwrap().1, t.ok);
let fn_y = (0..10).find(|y| row(&c, *y).contains("fn main")).unwrap();
let fx = cell_of(&row(&c, fn_y), "fn");
assert_eq!(c.cell(Point::new(fx, fn_y)).unwrap().1, t.syntax_keyword);
}
#[test]
fn json_and_yaml_fences_tint_through_the_data_mapping() {
let t = default_theme().tokens;
let doc = "```json\n{\"name\": \"Ada\", \"ok\": true}\n```\n\n```yaml\nregion: eu-west-1 # main\n```\n";
let c = draw_into(MarkdownView::new(doc).element(&t), Size::new(40, 8));
let j_y = (0..8).find(|y| row(&c, *y).contains("name")).unwrap();
let jrow = row(&c, j_y);
let kx = cell_of(&jrow, "\"name\"");
let (_, fg, bg) = c.cell(Point::new(kx, j_y)).unwrap();
assert_eq!(fg, t.syntax_func, "json key ink");
assert_eq!(bg, t.surface_raised, "fence ground survives");
let vx = cell_of(&jrow, "\"Ada\"");
assert_eq!(c.cell(Point::new(vx, j_y)).unwrap().1, t.syntax_string);
let lx = cell_of(&jrow, "true");
assert_eq!(c.cell(Point::new(lx, j_y)).unwrap().1, t.syntax_keyword);
let y_y = (0..8).find(|y| row(&c, *y).contains("region")).unwrap();
let yrow = row(&c, y_y);
let yx = cell_of(&yrow, "region");
assert_eq!(
c.cell(Point::new(yx, y_y)).unwrap().1,
t.syntax_func,
"yaml key ink"
);
let cx = cell_of(&yrow, "# main");
assert_eq!(c.cell(Point::new(cx, y_y)).unwrap().1, t.syntax_comment);
let sx = cell_of(&yrow, "eu-west-1");
assert_eq!(c.cell(Point::new(sx, y_y)).unwrap().1, t.text);
}
#[test]
fn h3_and_deeper_carry_a_faint_level_prefix() {
let t = default_theme().tokens;
let doc = "## Two\n\n### Three\n\n#### Four";
let c = draw_into(MarkdownView::new(doc).element(&t), Size::new(24, 8));
let two_y = (0..8).find(|y| row(&c, *y).contains("Two")).unwrap();
assert!(row(&c, two_y).starts_with("Two"), "H2 has no prefix");
let three_y = (0..8).find(|y| row(&c, *y).contains("Three")).unwrap();
assert!(
row(&c, three_y).starts_with("### Three"),
"{:?}",
row(&c, three_y)
);
assert_eq!(
c.cell(Point::new(0, three_y)).unwrap().1,
t.text_faint,
"prefix rides the faint ink"
);
let tx = cell_of(&row(&c, three_y), "Three");
assert_eq!(
c.cell(Point::new(tx, three_y)).unwrap().1,
t.text,
"heading text keeps body ink + bold"
);
let four_y = (0..8).find(|y| row(&c, *y).contains("Four")).unwrap();
assert!(row(&c, four_y).starts_with("#### Four"));
}
#[test]
fn wrapping_and_tiny_rects_never_panic() {
let t = default_theme().tokens;
let long = "paragraph with quite a few words that must wrap around";
let c = draw_into(MarkdownView::new(long).element(&t), Size::new(12, 8));
assert!(row(&c, 0).trim_end().len() <= 12);
for size in [Size::new(0, 0), Size::new(2, 1), Size::new(5, 2)] {
let _ = draw_into(MarkdownView::new(DOC).element(&t), size);
}
}