use revue::event::Key;
use revue::layout::Rect;
use revue::render::{Buffer, Modifier};
use revue::style::Color;
use revue::widget::traits::RenderContext;
use revue::widget::{log_entry, richlog, LogEntry, LogLevel, RichLog, StyledView, View};
#[test]
fn test_richlog_new() {
let log = RichLog::new();
assert!(log.is_empty());
assert_eq!(log.len(), 0);
}
#[test]
fn test_richlog_default() {
let log = RichLog::default();
assert!(log.is_empty());
assert_eq!(log.len(), 0);
}
#[test]
fn test_richlog_helper_function() {
let log = richlog();
assert!(log.is_empty());
}
#[test]
fn test_richlog_min_level_builder() {
let log = RichLog::new().min_level(LogLevel::Warning);
let _ = log;
}
#[test]
fn test_richlog_timestamps_builder() {
let log = RichLog::new().timestamps(false);
let _ = log;
}
#[test]
fn test_richlog_sources_builder() {
let log = RichLog::new().sources(false);
let _ = log;
}
#[test]
fn test_richlog_icons_builder() {
let log = RichLog::new().icons(false);
let _ = log;
}
#[test]
fn test_richlog_auto_scroll_builder() {
let log = RichLog::new().auto_scroll(false);
let _ = log;
}
#[test]
fn test_richlog_max_entries_builder() {
let log = RichLog::new().max_entries(100);
let _ = log;
}
#[test]
fn test_richlog_wrap_builder() {
let log = RichLog::new().wrap(true);
let _ = log;
}
#[test]
fn test_richlog_bg_builder() {
let log = RichLog::new().bg(Color::BLACK);
let _ = log;
}
#[test]
fn test_richlog_chained_builders() {
let log = RichLog::new()
.min_level(LogLevel::Error)
.timestamps(true)
.sources(true)
.icons(true)
.auto_scroll(true)
.max_entries(500)
.wrap(false)
.bg(Color::BLACK);
let _ = log;
}
#[test]
fn test_log_entry_new() {
let entry = LogEntry::new("Test message");
assert_eq!(entry.message, "Test message");
assert_eq!(entry.level, LogLevel::Info);
assert!(entry.timestamp.is_none());
assert!(entry.source.is_none());
assert!(!entry.expanded);
assert!(entry.details.is_empty());
}
#[test]
fn test_log_entry_helper_function() {
let entry = log_entry("Helper message");
assert_eq!(entry.message, "Helper message");
}
#[test]
fn test_log_entry_level_builder() {
let entry = LogEntry::new("Warning message").level(LogLevel::Warning);
assert_eq!(entry.level, LogLevel::Warning);
}
#[test]
fn test_log_entry_trace() {
let entry = LogEntry::new("Trace").trace();
assert_eq!(entry.level, LogLevel::Trace);
}
#[test]
fn test_log_entry_debug() {
let entry = LogEntry::new("Debug").debug();
assert_eq!(entry.level, LogLevel::Debug);
}
#[test]
fn test_log_entry_info() {
let entry = LogEntry::new("Info").info();
assert_eq!(entry.level, LogLevel::Info);
}
#[test]
fn test_log_entry_warning() {
let entry = LogEntry::new("Warning").warning();
assert_eq!(entry.level, LogLevel::Warning);
}
#[test]
fn test_log_entry_error() {
let entry = LogEntry::new("Error").error();
assert_eq!(entry.level, LogLevel::Error);
}
#[test]
fn test_log_entry_fatal() {
let entry = LogEntry::new("Fatal").fatal();
assert_eq!(entry.level, LogLevel::Fatal);
}
#[test]
fn test_log_entry_timestamp() {
let entry = LogEntry::new("Message").timestamp("10:30:45");
assert_eq!(entry.timestamp, Some("10:30:45".to_string()));
}
#[test]
fn test_log_entry_source() {
let entry = LogEntry::new("Message").source("main.rs");
assert_eq!(entry.source, Some("main.rs".to_string()));
}
#[test]
fn test_log_entry_detail() {
let entry = LogEntry::new("Message").detail("Line 1").detail("Line 2");
assert_eq!(entry.details.len(), 2);
assert_eq!(entry.details[0], "Line 1");
assert_eq!(entry.details[1], "Line 2");
}
#[test]
fn test_log_entry_details() {
let entry = LogEntry::new("Message").details(vec!["A".to_string(), "B".to_string()]);
assert_eq!(entry.details.len(), 2);
}
#[test]
fn test_log_entry_toggle() {
let mut entry = LogEntry::new("Message");
assert!(!entry.expanded);
entry.toggle();
assert!(entry.expanded);
entry.toggle();
assert!(!entry.expanded);
}
#[test]
fn test_log_entry_chained_builders() {
let entry = LogEntry::new("Complex message")
.level(LogLevel::Error)
.timestamp("12:00:00")
.source("module.rs")
.detail("Stack trace line 1")
.detail("Stack trace line 2");
assert_eq!(entry.level, LogLevel::Error);
assert_eq!(entry.timestamp, Some("12:00:00".to_string()));
assert_eq!(entry.source, Some("module.rs".to_string()));
assert_eq!(entry.details.len(), 2);
}
#[test]
fn test_log_level_partial_ord() {
assert!(LogLevel::Error > LogLevel::Warning);
assert!(LogLevel::Warning > LogLevel::Info);
assert!(LogLevel::Info > LogLevel::Debug);
assert!(LogLevel::Debug > LogLevel::Trace);
}
#[test]
fn test_log_level_colors() {
let trace_color = LogLevel::Trace.color();
let debug_color = LogLevel::Debug.color();
let info_color = LogLevel::Info.color();
let warning_color = LogLevel::Warning.color();
let error_color = LogLevel::Error.color();
let fatal_color = LogLevel::Fatal.color();
assert_ne!(trace_color, debug_color);
assert_ne!(debug_color, info_color);
assert_ne!(info_color, warning_color);
assert_ne!(warning_color, error_color);
assert_ne!(error_color, fatal_color);
}
#[test]
fn test_log_level_icons() {
assert_eq!(LogLevel::Trace.icon(), '·');
assert_eq!(LogLevel::Debug.icon(), '○');
assert_eq!(LogLevel::Info.icon(), '●');
assert_eq!(LogLevel::Warning.icon(), '⚠');
assert_eq!(LogLevel::Error.icon(), '✗');
assert_eq!(LogLevel::Fatal.icon(), '☠');
}
#[test]
fn test_log_level_labels() {
assert_eq!(LogLevel::Trace.label(), "TRACE");
assert_eq!(LogLevel::Debug.label(), "DEBUG");
assert_eq!(LogLevel::Info.label(), "INFO");
assert_eq!(LogLevel::Warning.label(), "WARN");
assert_eq!(LogLevel::Error.label(), "ERROR");
assert_eq!(LogLevel::Fatal.label(), "FATAL");
}
#[test]
fn test_log_level_default() {
let default_level = LogLevel::default();
assert_eq!(default_level, LogLevel::Info);
}
#[test]
fn test_richlog_log() {
let mut log = RichLog::new();
let entry = LogEntry::new("Test entry").level(LogLevel::Info);
log.log(entry);
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_write() {
let mut log = RichLog::new();
log.write(LogLevel::Info, "Info message");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_info() {
let mut log = RichLog::new();
log.info("Info message");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_debug() {
let mut log = RichLog::new();
log.debug("Debug message");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_warn() {
let mut log = RichLog::new();
log.warn("Warning message");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_error() {
let mut log = RichLog::new();
log.error("Error message");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_multiple_entries() {
let mut log = RichLog::new();
log.info("Info 1");
log.debug("Debug 1");
log.warn("Warning 1");
log.error("Error 1");
assert_eq!(log.len(), 4);
}
#[test]
fn test_richlog_clear() {
let mut log = RichLog::new();
log.info("Message");
log.info("Another message");
assert_eq!(log.len(), 2);
log.clear();
assert!(log.is_empty());
assert_eq!(log.len(), 0);
}
#[test]
fn test_richlog_min_level_filtering() {
let mut log = RichLog::new().min_level(LogLevel::Warning);
log.debug("Debug message"); log.info("Info message"); log.warn("Warning message"); log.error("Error message");
assert_eq!(log.len(), 2);
}
#[test]
fn test_richlog_max_entries_limit() {
let mut log = RichLog::new().max_entries(3);
for i in 0..10 {
log.info(format!("Message {}", i));
}
assert_eq!(log.len(), 3);
}
#[test]
fn test_richlog_max_entries_zero() {
let mut log = RichLog::new().max_entries(0);
log.info("Message 1");
log.info("Message 2");
assert_eq!(log.len(), 2);
}
#[test]
fn test_richlog_scroll_up() {
let mut log = RichLog::new().auto_scroll(false);
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_up(2);
let _ = log;
}
#[test]
fn test_richlog_scroll_down() {
let mut log = RichLog::new();
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_down(3);
let _ = log;
}
#[test]
fn test_richlog_scroll_to_top() {
let mut log = RichLog::new();
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_to_top();
let _ = log;
}
#[test]
fn test_richlog_scroll_to_bottom() {
let mut log = RichLog::new();
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_to_bottom();
let _ = log;
}
#[test]
fn test_richlog_scroll_up_from_top() {
let mut log = RichLog::new();
log.info("Message");
log.scroll_up(10); let _ = log;
}
#[test]
fn test_richlog_scroll_down_past_end() {
let mut log = RichLog::new();
log.info("Message");
log.scroll_down(100); let _ = log;
}
#[test]
fn test_richlog_auto_scroll_behavior() {
let mut log = RichLog::new().auto_scroll(true);
log.info("First message");
log.info("Second message");
let _ = log;
}
#[test]
fn test_richlog_scroll_up_disables_auto_scroll() {
let mut log = RichLog::new().auto_scroll(true);
log.info("Message");
log.scroll_up(1);
let _ = log;
}
#[test]
fn test_richlog_scroll_to_top_disables_auto_scroll() {
let mut log = RichLog::new().auto_scroll(true);
log.info("Message");
log.scroll_to_top();
let _ = log;
}
#[test]
fn test_richlog_handle_key_up() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Up);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_k() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Char('k'));
assert!(handled);
}
#[test]
fn test_richlog_handle_key_down() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Down);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_j() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Char('j'));
assert!(handled);
}
#[test]
fn test_richlog_handle_key_page_up() {
let mut log = RichLog::new();
for i in 0..20 {
log.info(format!("Message {}", i));
}
let handled = log.handle_key(&Key::PageUp);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_page_down() {
let mut log = RichLog::new();
for i in 0..20 {
log.info(format!("Message {}", i));
}
let handled = log.handle_key(&Key::PageDown);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_home() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Home);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_g() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Char('g'));
assert!(handled);
}
#[test]
fn test_richlog_handle_key_end() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::End);
assert!(handled);
}
#[test]
fn test_richlog_handle_key_shift_g() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Char('G'));
assert!(handled);
}
#[test]
fn test_richlog_handle_key_c_clear() {
let mut log = RichLog::new();
log.info("Message");
assert_eq!(log.len(), 1);
let handled = log.handle_key(&Key::Char('c'));
assert!(handled);
assert!(log.is_empty());
}
#[test]
fn test_richlog_handle_key_unhandled() {
let mut log = RichLog::new();
log.info("Message");
let handled = log.handle_key(&Key::Char('x'));
assert!(!handled);
let handled = log.handle_key(&Key::Enter);
assert!(!handled);
let handled = log.handle_key(&Key::Tab);
assert!(!handled);
}
#[test]
fn test_richlog_select_next() {
let mut log = RichLog::new();
log.info("Message 1");
log.info("Message 2");
log.select_next();
let _ = log;
}
#[test]
fn test_richlog_select_next_from_none() {
let mut log = RichLog::new();
log.info("Message");
log.select_next();
let _ = log;
}
#[test]
fn test_richlog_select_prev() {
let mut log = RichLog::new();
log.info("Message 1");
log.info("Message 2");
log.select_next();
log.select_prev();
let _ = log;
}
#[test]
fn test_richlog_toggle_selected() {
let mut log = RichLog::new();
log.info("Message");
log.select_next();
log.toggle_selected();
let _ = log;
}
#[test]
fn test_richlog_toggle_selected_no_selection() {
let mut log = RichLog::new();
log.info("Message");
log.toggle_selected();
let _ = log;
}
#[test]
fn test_richlog_render_empty() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let log = RichLog::new();
log.render(&mut ctx);
}
#[test]
fn test_richlog_render_single_entry() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.info("Test message");
log.render(&mut ctx);
let cell = buffer.get(12, 0).unwrap();
assert_eq!(cell.symbol, '●'); }
#[test]
fn test_richlog_render_multiple_entries() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
for i in 0..5 {
log.info(format!("Message {}", i));
}
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '●');
}
#[test]
fn test_richlog_render_with_timestamp() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().timestamps(true);
log.log(LogEntry::new("Message").timestamp("10:30:00"));
log.render(&mut ctx);
let _ = buffer;
}
#[test]
fn test_richlog_render_with_source() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().sources(true);
log.log(LogEntry::new("Message").source("main.rs"));
log.render(&mut ctx);
let _ = buffer;
}
#[test]
fn test_richlog_render_without_icons() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().icons(false);
log.info("Message");
log.render(&mut ctx);
let _ = buffer;
}
#[test]
fn test_richlog_render_with_background() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().bg(Color::BLACK);
log.info("Message");
log.render(&mut ctx);
let cell = buffer.get(0, 0).unwrap();
assert_eq!(cell.bg, Some(Color::BLACK));
}
#[test]
fn test_richlog_render_scrolled() {
let mut buffer = Buffer::new(80, 5);
let area = Rect::new(0, 0, 80, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().auto_scroll(false);
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_to_bottom();
log.render(&mut ctx);
let _ = buffer;
}
#[test]
fn test_richlog_render_scrolled_to_top() {
let mut buffer = Buffer::new(80, 5);
let area = Rect::new(0, 0, 80, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_to_top();
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '●');
}
#[test]
fn test_richlog_render_with_scroll_indicator() {
let mut buffer = Buffer::new(80, 5);
let area = Rect::new(0, 0, 80, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().auto_scroll(false);
for i in 0..20 {
log.info(format!("Message {}", i));
}
log.scroll_to_top();
log.render(&mut ctx);
let indicator = buffer.get(79, 0).unwrap().symbol;
let _ = indicator;
}
#[test]
fn test_richlog_render_zero_area() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 10, 1); let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.info("Message");
log.render(&mut ctx);
}
#[test]
fn test_richlog_render_small_area() {
let mut buffer = Buffer::new(80, 24);
let area = Rect::new(0, 0, 10, 2); let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.info("Short message");
log.render(&mut ctx);
}
#[test]
fn test_richlog_trace_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Trace message").level(LogLevel::Trace));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '·');
}
#[test]
fn test_richlog_debug_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Debug message").level(LogLevel::Debug));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '○');
}
#[test]
fn test_richlog_info_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Info message").level(LogLevel::Info));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '●');
}
#[test]
fn test_richlog_warning_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Warning message").level(LogLevel::Warning));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '⚠');
}
#[test]
fn test_richlog_error_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Error message").level(LogLevel::Error));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '✗');
}
#[test]
fn test_richlog_fatal_level_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.log(LogEntry::new("Fatal message").level(LogLevel::Fatal));
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '☠');
}
#[test]
fn test_richlog_level_colors_in_render() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.info("Info");
log.warn("Warning");
log.error("Error");
log.scroll_to_top();
log.render(&mut ctx);
let info_cell = buffer.get(12, 0).unwrap();
assert_eq!(info_cell.fg, Some(Color::CYAN));
}
#[test]
fn test_richlog_error_bold_modifier() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.error("Error message");
log.render(&mut ctx);
let msg_cell = buffer.get(29, 0).unwrap();
assert!(msg_cell.modifier.contains(Modifier::BOLD));
}
#[test]
fn test_richlog_message_text_rendering() {
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().auto_scroll(false); log.info("Hello World");
log.render(&mut ctx);
assert_eq!(buffer.get(29, 0).unwrap().symbol, 'H');
assert_eq!(buffer.get(35, 0).unwrap().symbol, 'W');
}
#[test]
fn test_richlog_long_message_truncation() {
let mut buffer = Buffer::new(20, 1);
let area = Rect::new(0, 0, 20, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new();
log.info("This is a very long message that should be truncated");
log.render(&mut ctx);
let _ = buffer;
}
#[test]
fn test_richlog_empty_entry() {
let mut log = RichLog::new();
log.info("");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_unicode_message() {
let mut log = RichLog::new();
log.info("안녕하세요 🎉"); assert_eq!(log.len(), 1);
let mut buffer = Buffer::new(80, 1);
let area = Rect::new(0, 0, 80, 1);
let mut ctx = RenderContext::new(&mut buffer, area);
log.render(&mut ctx);
}
#[test]
fn test_richlog_special_characters() {
let mut log = RichLog::new();
log.info("Special: \t\n\r");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_very_long_single_line() {
let mut log = RichLog::new();
let long_msg = "A".repeat(10000);
log.info(&long_msg);
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_many_entries() {
let mut log = RichLog::new();
for i in 0..10000 {
log.info(format!("Message {}", i));
}
assert_eq!(log.len(), 1000);
}
#[test]
fn test_richlog_scroll_empty_log() {
let mut log = RichLog::new();
log.scroll_up(10);
log.scroll_down(10);
log.scroll_to_top();
log.scroll_to_bottom();
}
#[test]
fn test_richlog_handle_keys_empty_log() {
let mut log = RichLog::new();
assert!(log.handle_key(&Key::Up));
assert!(log.handle_key(&Key::Down));
assert!(log.handle_key(&Key::Char('k')));
assert!(log.handle_key(&Key::Char('j')));
assert!(!log.handle_key(&Key::Enter));
assert!(!log.handle_key(&Key::Tab));
}
#[test]
fn test_richlog_clear_multiple_times() {
let mut log = RichLog::new();
log.info("Message");
log.clear();
log.clear();
log.clear();
assert!(log.is_empty());
}
#[test]
fn test_richlog_max_entries_with_scroll() {
let mut log = RichLog::new().max_entries(5);
for i in 0..10 {
log.info(format!("Message {}", i));
}
log.scroll_down(10);
log.scroll_up(5);
}
#[test]
fn test_richlog_css_id() {
let log = RichLog::new().element_id("test-log");
assert_eq!(View::id(&log), Some("test-log"));
}
#[test]
fn test_richlog_css_classes() {
let log = RichLog::new().class("console").class("monospace");
assert!(log.has_class("console"));
assert!(log.has_class("monospace"));
assert!(!log.has_class("other"));
}
#[test]
fn test_richlog_styled_view_methods() {
let mut log = RichLog::new();
log.set_id("my-log");
assert_eq!(View::id(&log), Some("my-log"));
log.add_class("highlight");
assert!(log.has_class("highlight"));
log.remove_class("highlight");
assert!(!log.has_class("highlight"));
log.toggle_class("active");
assert!(log.has_class("active"));
log.toggle_class("active");
assert!(!log.has_class("active"));
}
#[test]
fn test_richlog_builder_with_css() {
let log = RichLog::new()
.element_id("app-log")
.class("dark")
.class("scrollable");
assert_eq!(View::id(&log), Some("app-log"));
assert!(log.has_class("dark"));
assert!(log.has_class("scrollable"));
}
#[test]
fn test_log_entry_clone() {
let entry1 = LogEntry::new("Test")
.level(LogLevel::Error)
.timestamp("10:00:00")
.source("test.rs");
let entry2 = entry1.clone();
assert_eq!(entry1.message, entry2.message);
assert_eq!(entry1.level, entry2.level);
assert_eq!(entry1.timestamp, entry2.timestamp);
assert_eq!(entry1.source, entry2.source);
}
#[test]
fn test_log_level_debug() {
let debug = format!("{:?}", LogLevel::Error);
assert!(!debug.is_empty());
}
#[test]
fn test_log_entry_debug_formatting() {
let entry = LogEntry::new("Debug test");
let debug = format!("{:?}", entry);
assert!(!debug.is_empty());
assert!(debug.contains("Debug test"));
}
#[test]
fn test_richlog_full_workflow() {
let mut buffer = Buffer::new(80, 10);
let area = Rect::new(0, 0, 80, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new()
.min_level(LogLevel::Debug)
.timestamps(true)
.sources(true)
.icons(true)
.max_entries(100)
.bg(Color::BLACK);
log.debug("Application starting");
log.info("Connected to database");
log.warn("High memory usage detected");
log.error("Failed to load config");
log.scroll_up(1);
log.scroll_down(1);
log.render(&mut ctx);
log.handle_key(&Key::Char('c')); assert!(log.is_empty());
log.info("New message after clear");
assert_eq!(log.len(), 1);
}
#[test]
fn test_richlog_visible_entries_filtering() {
let mut log = RichLog::new().min_level(LogLevel::Warning);
log.debug("Debug"); log.info("Info"); log.warn("Warning"); log.error("Error");
assert_eq!(log.len(), 2);
}
#[test]
fn test_richlog_all_log_levels() {
let mut buffer = Buffer::new(80, 10);
let area = Rect::new(0, 0, 80, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
let mut log = RichLog::new().auto_scroll(false);
log.log(LogEntry::new("Trace").trace());
log.log(LogEntry::new("Debug").debug());
log.log(LogEntry::new("Info").info());
log.log(LogEntry::new("Warning").warning());
log.log(LogEntry::new("Error").error());
log.log(LogEntry::new("Fatal").fatal());
log.render(&mut ctx);
assert_eq!(buffer.get(12, 0).unwrap().symbol, '·');
assert_eq!(buffer.get(12, 1).unwrap().symbol, '○');
assert_eq!(buffer.get(12, 2).unwrap().symbol, '●');
assert_eq!(buffer.get(12, 3).unwrap().symbol, '⚠');
assert_eq!(buffer.get(12, 4).unwrap().symbol, '✗');
assert_eq!(buffer.get(12, 5).unwrap().symbol, '☠');
}