use super::{rendered_non_empty_lines, test_assets, test_md_theme};
use crate::markdown::parse_markdown;
use crate::*;
#[test]
fn inline_latex_renders_with_latex_style() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"The formula $x^2 + y^2$ is here.\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let latex_line = lines
.iter()
.find(|line| line_plain_text(line).contains("x² + y²"))
.expect("expected a line containing inline latex content");
let latex_span = latex_line
.spans
.iter()
.find(|span| span.content.contains("x² + y²"))
.expect("expected a span with latex content");
assert!(
latex_span.style.bg.is_some(),
"inline latex should have a background color"
);
}
#[test]
fn display_latex_renders_in_framed_block() {
let (ss, theme) = test_assets();
let (lines, _, _, _) =
parse_markdown("$$E = mc^2$$\n", &ss, &theme, &test_md_theme(), false, true).into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("┌─ latex")),
"expected latex block header"
);
assert!(
rendered.iter().any(|line| line.contains("E = mc²")),
"expected latex content"
);
assert!(
rendered.iter().any(|line| line.contains("└")),
"expected latex block footer"
);
}
#[test]
fn inline_latex_is_searchable() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"Check $\\alpha + \\beta$ here.\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let searchable: Vec<String> = lines.iter().map(line_plain_text).collect();
assert!(
searchable.iter().any(|line| line.contains("α + β")),
"latex content should be searchable"
);
}
#[test]
fn display_latex_in_blockquote_has_quote_prefix() {
let (ss, theme) = test_assets();
let (lines, _, _, _) =
parse_markdown("> $$F = ma$$\n", &ss, &theme, &test_md_theme(), false, true).into();
let rendered = rendered_non_empty_lines(&lines);
let header = rendered
.iter()
.find(|line| line.contains("┌─ latex"))
.expect("expected latex block header in blockquote");
assert!(
header.starts_with('▏'),
"latex block in blockquote should have quote prefix"
);
}
#[test]
fn mermaid_block_renders_in_framed_block() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"```mermaid\ngraph TD\n A --> B\n```\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("┌─ mermaid")),
"expected mermaid block header"
);
assert!(
rendered.iter().any(|line| line.contains('A')),
"expected node A in rendered content"
);
assert!(
rendered.iter().any(|line| line.contains('B')),
"expected node B in rendered content"
);
assert!(
rendered.iter().any(|line| line.contains("└")),
"expected mermaid block footer"
);
}
#[test]
fn mermaid_block_in_blockquote_has_quote_prefix() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"> ```mermaid\n> graph LR\n> X --> Y\n> ```\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let rendered = rendered_non_empty_lines(&lines);
let header = rendered
.iter()
.find(|line| line.contains("┌─ mermaid"))
.expect("expected mermaid block header in blockquote");
assert!(
header.starts_with('▏'),
"mermaid block in blockquote should have quote prefix"
);
}
#[test]
fn mermaid_content_is_searchable() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"```mermaid\nsequenceDiagram\n A->>B: Hello\n```\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let searchable = markdown::width::build_searchable_lines(&lines);
assert!(
searchable.iter().any(|line| line.contains('A')),
"mermaid content should be searchable (node A)"
);
assert!(
searchable.iter().any(|line| line.contains("Hello")),
"mermaid content should be searchable (message Hello)"
);
}
#[test]
fn mermaid_rendered_block_has_no_gutter() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"```mermaid\ngraph TD\n A --> B\n B --> C\n```\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let rendered = rendered_non_empty_lines(&lines);
let content_lines: Vec<_> = rendered
.iter()
.filter(|l| !l.contains('┌') && !l.contains('└'))
.collect();
assert!(
content_lines.iter().all(|line| !line.contains("│1│")),
"rendered mermaid should not have numbered gutter"
);
}
#[test]
fn mermaid_fallback_has_numbered_gutter() {
let (ss, theme) = test_assets();
let src = "```mermaid\ngantt\n title Schedule\n section Dev\n```\n";
let (lines, _, _, _) = parse_markdown(src, &ss, &theme, &test_md_theme(), false, true).into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("│1│")),
"fallback mermaid should have numbered gutter"
);
}
#[test]
fn mermaid_pie_renders_bar_chart() {
let (ss, theme) = test_assets();
let src = "```mermaid\npie title Languages\n \"Rust\" : 65\n \"Go\" : 35\n```\n";
let (lines, _, _, _) = parse_markdown(src, &ss, &theme, &test_md_theme(), false, true).into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("┌─ mermaid")),
"expected mermaid block header for pie"
);
assert!(
rendered.iter().any(|line| line.contains("Languages")),
"expected pie chart title"
);
assert!(
rendered.iter().any(|line| line.contains("Rust")),
"expected Rust label in pie chart"
);
assert!(
rendered.iter().any(|line| line.contains('█')),
"expected bar characters in pie chart"
);
assert!(
rendered.iter().any(|line| line.contains('%')),
"expected percentage in pie chart"
);
}
#[test]
fn mermaid_unsupported_type_falls_back_to_colored_source() {
let (ss, theme) = test_assets();
let src = "```mermaid\ngantt\n title Schedule\n section Phase 1\n```\n";
let (lines, _, _, _) = parse_markdown(src, &ss, &theme, &test_md_theme(), false, true).into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("┌─ mermaid")),
"expected mermaid block header"
);
assert!(
rendered.iter().any(|line| line.contains("gantt")),
"unsupported type should show source (gantt keyword)"
);
}
#[test]
fn mermaid_empty_block_renders_without_crash() {
let (ss, theme) = test_assets();
let (lines, _, _, _) = parse_markdown(
"```mermaid\n```\n",
&ss,
&theme,
&test_md_theme(),
false,
true,
)
.into();
let rendered = rendered_non_empty_lines(&lines);
assert!(
rendered.iter().any(|line| line.contains("┌─ mermaid")),
"expected mermaid block header for empty block"
);
assert!(
rendered.iter().any(|line| line.contains("└")),
"expected mermaid block footer for empty block"
);
}