use super::*;
use crate::widget::form::rich_text_editor::{FormattedSpan, TextFormat};
fn bold() -> TextFormat {
TextFormat {
bold: true,
..Default::default()
}
}
fn italic() -> TextFormat {
TextFormat {
italic: true,
..Default::default()
}
}
fn underline() -> TextFormat {
TextFormat {
underline: true,
..Default::default()
}
}
fn strikethrough() -> TextFormat {
TextFormat {
strikethrough: true,
..Default::default()
}
}
fn code() -> TextFormat {
TextFormat {
code: true,
..Default::default()
}
}
#[test]
fn test_render_basic() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content("Hello");
editor.render(&mut ctx);
}
#[test]
fn test_render_with_toolbar() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().toolbar(true);
editor.render(&mut ctx);
}
#[test]
fn test_render_without_toolbar() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().toolbar(false);
editor.render(&mut ctx);
}
#[test]
fn test_render_split_view() {
let mut buffer = Buffer::new(80, 20);
let area = Rect::new(0, 0, 80, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Split)
.content("# Title");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.content("Preview text");
editor.render(&mut ctx);
}
#[test]
fn test_render_small_area() {
let mut buffer = Buffer::new(1, 1);
let area = Rect::new(0, 0, 1, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new();
editor.render(&mut ctx); }
#[test]
fn test_render_with_dialog() {
let mut buffer = Buffer::new(60, 20);
let area = Rect::new(0, 0, 60, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.open_link_dialog();
editor.render(&mut ctx);
}
#[test]
fn test_render_all_block_types() {
let mut buffer = Buffer::new(50, 20);
let area = Rect::new(0, 0, 50, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let md = "# H1\n## H2\n### H3\n> Quote\n- Bullet\n1. Number\n```\ncode\n```\n---";
let editor = RichTextEditor::new().from_markdown(md);
editor.render(&mut ctx);
}
#[test]
fn test_render_editor_mode() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Editor)
.content("Editor content");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode_with_headings() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.from_markdown("# Heading 1\n## Heading 2\n### Heading 3");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode_with_lists() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.from_markdown("- Item 1\n- Item 2\n1. Number 1\n2. Number 2");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode_with_quote() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.from_markdown("> This is a quote");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode_with_code_block() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.from_markdown("```rust\nlet x = 1;\n```");
editor.render(&mut ctx);
}
#[test]
fn test_render_preview_mode_with_horizontal_rule() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Preview)
.from_markdown("---");
editor.render(&mut ctx);
}
#[test]
fn test_render_split_view_with_content() {
let mut buffer = Buffer::new(80, 20);
let area = Rect::new(0, 0, 80, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Split)
.from_markdown("# Title\n\nContent paragraph\n- List item");
editor.render(&mut ctx);
}
#[test]
fn test_render_split_view_narrow() {
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.view_mode(EditorViewMode::Split)
.content("Content");
editor.render(&mut ctx);
}
#[test]
fn test_render_zero_width() {
let mut buffer = Buffer::new(0, 10);
let area = Rect::new(0, 0, 0, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new();
editor.render(&mut ctx);
}
#[test]
fn test_render_zero_height() {
let mut buffer = Buffer::new(40, 0);
let area = Rect::new(0, 0, 40, 0);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new();
editor.render(&mut ctx);
}
#[test]
fn test_render_single_cell() {
let mut buffer = Buffer::new(1, 1);
let area = Rect::new(0, 0, 1, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content("X");
editor.render(&mut ctx);
}
#[test]
fn test_render_very_narrow() {
let mut buffer = Buffer::new(2, 10);
let area = Rect::new(0, 0, 2, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content("Long text");
editor.render(&mut ctx);
}
#[test]
fn test_render_very_short() {
let mut buffer = Buffer::new(40, 1);
let area = Rect::new(0, 0, 40, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content("Line 1\nLine 2");
editor.render(&mut ctx);
}
#[test]
fn test_render_large_area() {
let mut buffer = Buffer::new(200, 100);
let area = Rect::new(0, 0, 200, 100);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content("Content");
editor.render(&mut ctx);
}
#[test]
fn test_render_long_line() {
let mut buffer = Buffer::new(20, 5);
let area = Rect::new(0, 0, 20, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
let long_text = "This is a very long line that exceeds the buffer width";
let editor = RichTextEditor::new().content(long_text);
editor.render(&mut ctx);
}
#[test]
fn test_render_many_lines() {
let mut buffer = Buffer::new(40, 5);
let area = Rect::new(0, 0, 40, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
let many_lines = (0..20)
.map(|i| format!("Line {}", i))
.collect::<Vec<_>>()
.join("\n");
let editor = RichTextEditor::new().content(&many_lines);
editor.render(&mut ctx);
}
#[test]
fn test_render_empty_content() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new();
editor.render(&mut ctx);
}
#[test]
fn test_render_whitespace_content() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().content(" \n\n ");
editor.render(&mut ctx);
}
#[test]
fn test_render_with_focus() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().focused(true);
editor.render(&mut ctx);
}
#[test]
fn test_render_without_focus() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().focused(false);
editor.render(&mut ctx);
}
#[test]
fn test_render_with_cursor_position() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new().content("Line 1\nLine 2");
editor.set_cursor(1, 3);
editor.render(&mut ctx);
}
#[test]
fn test_render_with_custom_colors() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.bg(Color::rgb(20, 20, 30))
.fg(Color::rgb(200, 200, 200));
editor.render(&mut ctx);
}
#[test]
fn test_render_with_named_colors() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().bg(Color::BLACK).fg(Color::WHITE);
editor.render(&mut ctx);
}
#[test]
fn test_render_link_dialog() {
let mut buffer = Buffer::new(60, 20);
let area = Rect::new(0, 0, 60, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.open_link_dialog();
editor.render(&mut ctx);
}
#[test]
fn test_render_image_dialog() {
let mut buffer = Buffer::new(60, 20);
let area = Rect::new(0, 0, 60, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.open_image_dialog();
editor.render(&mut ctx);
}
#[test]
fn test_render_dialog_with_content() {
let mut buffer = Buffer::new(60, 20);
let area = Rect::new(0, 0, 60, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new().content("Some content");
editor.open_link_dialog();
editor.render(&mut ctx);
}
#[test]
fn test_render_dialog_after_close() {
let mut buffer = Buffer::new(60, 20);
let area = Rect::new(0, 0, 60, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.open_link_dialog();
editor.close_dialog();
editor.render(&mut ctx);
}
#[test]
fn test_render_toolbar_with_editor_mode() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.toolbar(true)
.view_mode(EditorViewMode::Editor);
editor.render(&mut ctx);
}
#[test]
fn test_render_toolbar_with_preview_mode() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.toolbar(true)
.view_mode(EditorViewMode::Preview);
editor.render(&mut ctx);
}
#[test]
fn test_render_toolbar_with_split_mode() {
let mut buffer = Buffer::new(80, 10);
let area = Rect::new(0, 0, 80, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new()
.toolbar(true)
.view_mode(EditorViewMode::Split);
editor.render(&mut ctx);
}
#[test]
fn test_render_toolbar_with_minimum_height() {
let mut buffer = Buffer::new(40, 1);
let area = Rect::new(0, 0, 40, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let editor = RichTextEditor::new().toolbar(true);
editor.render(&mut ctx);
}
#[test]
fn test_render_mixed_block_types() {
let mut buffer = Buffer::new(50, 20);
let area = Rect::new(0, 0, 50, 20);
let mut ctx = RenderContext::new(&mut buffer, area);
let markdown = "# Heading\n\nParagraph with **bold** text.\n\n- List item 1\n- List item 2\n\n> Quote\n\n```\ncode\n```";
let editor = RichTextEditor::new().from_markdown(markdown);
editor.render(&mut ctx);
}
#[test]
fn test_render_all_heading_levels() {
let mut buffer = Buffer::new(40, 15);
let area = Rect::new(0, 0, 40, 15);
let mut ctx = RenderContext::new(&mut buffer, area);
let markdown = "# H1\n## H2\n### H3\n#### H4\n##### H5\n###### H6";
let editor = RichTextEditor::new().from_markdown(markdown);
editor.render(&mut ctx);
}
#[test]
fn test_render_nested_list_structure() {
let mut buffer = Buffer::new(40, 15);
let area = Rect::new(0, 0, 40, 15);
let mut ctx = RenderContext::new(&mut buffer, area);
let markdown = "- Item 1\n- Item 2\n - Nested 1\n - Nested 2\n- Item 3";
let editor = RichTextEditor::new().from_markdown(markdown);
editor.render(&mut ctx);
}
#[test]
fn test_render_with_special_characters() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let content = "Special chars: < > & \" ' \\ / @ # $ % ^ *";
let editor = RichTextEditor::new().content(content);
editor.render(&mut ctx);
}
#[test]
fn test_render_with_unicode() {
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let content = "Unicode: 你好 🌍 🎉";
let editor = RichTextEditor::new().content(content);
editor.render(&mut ctx);
}
#[test]
fn test_render_bold_text() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("Bold").with_format(bold())];
editor.render(&mut ctx);
let cell = buffer.get(0, 1); assert!(cell.is_some());
assert!(cell.unwrap().modifier.contains(Modifier::BOLD));
}
#[test]
fn test_render_italic_text() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("Italic").with_format(italic())];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
assert!(cell.unwrap().modifier.contains(Modifier::ITALIC));
}
#[test]
fn test_render_underline_text() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("Underline").with_format(underline())];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
assert!(cell.unwrap().modifier.contains(Modifier::UNDERLINE));
}
#[test]
fn test_render_strikethrough_text() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("Strike").with_format(strikethrough())];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
assert!(cell.unwrap().modifier.contains(Modifier::CROSSED_OUT));
}
#[test]
fn test_render_code_text() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("code").with_format(code())];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
assert!(cell.unwrap().modifier.contains(Modifier::DIM));
}
#[test]
fn test_render_combined_modifiers() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("BiU").with_format(TextFormat {
bold: true,
italic: true,
underline: true,
..Default::default()
})];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
let modifier = cell.unwrap().modifier;
assert!(modifier.contains(Modifier::BOLD));
assert!(modifier.contains(Modifier::ITALIC));
assert!(modifier.contains(Modifier::UNDERLINE));
}
#[test]
fn test_render_multiple_formatted_spans() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![
FormattedSpan::new("Red").with_format(bold()),
FormattedSpan::new(" "),
FormattedSpan::new("Blue").with_format(italic()),
];
editor.render(&mut ctx);
assert!(buffer.get(0, 1).unwrap().modifier.contains(Modifier::BOLD));
assert!(buffer
.get(4, 1)
.unwrap()
.modifier
.contains(Modifier::ITALIC));
}
#[test]
fn test_render_all_modifiers() {
use crate::render::Modifier;
let mut buffer = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut editor = RichTextEditor::new();
editor.blocks[0].spans = vec![FormattedSpan::new("All").with_format(TextFormat {
bold: true,
italic: true,
underline: true,
strikethrough: true,
code: true,
..Default::default()
})];
editor.render(&mut ctx);
let cell = buffer.get(0, 1);
assert!(cell.is_some());
let modifier = cell.unwrap().modifier;
assert!(modifier.contains(Modifier::BOLD));
assert!(modifier.contains(Modifier::ITALIC));
assert!(modifier.contains(Modifier::UNDERLINE));
assert!(modifier.contains(Modifier::CROSSED_OUT));
assert!(modifier.contains(Modifier::DIM));
}