use revue::layout::Rect;
use revue::render::Buffer;
use revue::widget::{RenderContext, Text, View};
#[test]
fn test_large_buffer_creation() {
let buf = Buffer::new(500, 200);
assert_eq!(buf.width(), 500);
assert_eq!(buf.height(), 200);
}
#[test]
fn test_buffer_fill_large_area() {
let mut buf = Buffer::new(200, 100);
buf.fill(0, 0, 200, 100, revue::render::Cell::new('X'));
assert_eq!(buf.get(199, 99).unwrap().symbol, 'X');
assert_eq!(buf.get(0, 0).unwrap().symbol, 'X');
}
#[test]
fn test_css_many_rules() {
let mut css = String::new();
for i in 0..500 {
css.push_str(&format!(
".class-{} {{ color: rgb({}, {}, {}); padding: {}; }}\n",
i,
i % 256,
(i * 3) % 256,
(i * 7) % 256,
i % 20
));
}
let sheet = revue::style::parse_css(&css).unwrap();
assert_eq!(sheet.rules.len(), 500);
}
#[test]
fn test_css_long_selector_chain() {
let css = ".a .b .c .d .e .f .g .h { color: red; }";
let sheet = revue::style::parse_css(css).unwrap();
assert_eq!(sheet.rules.len(), 1);
}
#[test]
fn test_css_many_declarations() {
let mut css = String::from(".heavy {\n");
for i in 0..100 {
css.push_str(&format!(" padding: {};\n", i));
}
css.push_str("}\n");
let sheet = revue::style::parse_css(&css).unwrap();
assert_eq!(sheet.rules[0].declarations.len(), 100);
}
#[test]
fn test_css_many_variables() {
let mut css = String::from(":root {\n");
for i in 0..100 {
css.push_str(&format!(
" --color-{}: rgb({}, {}, {});\n",
i,
i,
i * 2,
i * 3
));
}
css.push_str("}\n");
let sheet = revue::style::parse_css(&css).unwrap();
assert_eq!(sheet.variables.len(), 100);
}
#[test]
fn test_render_many_text_widgets() {
let mut buf = Buffer::new(80, 24);
for i in 0..100 {
let text = Text::new(format!("Line {}", i));
let row_area = Rect::new(0, (i % 24) as u16, 80, 1);
let mut ctx = RenderContext::new(&mut buf, row_area);
text.render(&mut ctx);
}
}
#[test]
fn test_deep_nested_stack() {
use revue::widget::vstack;
let mut widget: Box<dyn View> = Box::new(Text::new("Leaf"));
for _ in 0..10 {
widget = Box::new(vstack().child(widget));
}
let mut buf = Buffer::new(80, 24);
let area = Rect::new(0, 0, 80, 24);
let mut ctx = RenderContext::new(&mut buf, area);
widget.render(&mut ctx);
}
#[test]
fn test_csv_viewer_large_dataset() {
use revue::widget::CsvViewer;
let mut csv = String::from("Name,Age,City,Score\n");
for i in 0..1000 {
csv.push_str(&format!(
"User{},{},City{},{}\n",
i,
20 + i % 50,
i % 100,
i * 7 % 100
));
}
let viewer = CsvViewer::from_content(&csv);
assert_eq!(viewer.row_count(), 1000);
assert_eq!(viewer.column_count(), 4);
assert_eq!(viewer.get_cell(999, 0), Some("User999"));
}
#[test]
fn test_csv_viewer_many_columns() {
use revue::widget::CsvViewer;
let header: Vec<String> = (0..50).map(|i| format!("Col{}", i)).collect();
let row: Vec<String> = (0..50).map(|i| format!("Val{}", i)).collect();
let csv = format!("{}\n{}", header.join(","), row.join(","));
let viewer = CsvViewer::from_content(&csv);
assert_eq!(viewer.column_count(), 50);
}
#[test]
fn test_csv_viewer_search_large() {
use revue::widget::CsvViewer;
let mut csv = String::from("Name,Value\n");
for i in 0..500 {
csv.push_str(&format!(
"item{},{}\n",
i,
if i == 42 { "target" } else { "other" }
));
}
let mut viewer = CsvViewer::from_content(&csv);
viewer.search("target");
assert_eq!(viewer.match_count(), 1);
}
#[test]
fn test_scroll_view_large_content() {
let mut scroll = revue::widget::scroll_view().content_height(10000);
scroll.scroll_to_bottom(24);
assert_eq!(scroll.offset(), 10000 - 24);
scroll.scroll_to_top();
assert_eq!(scroll.offset(), 0);
for _ in 0..1000 {
scroll.scroll_down(10, 24);
}
assert!(scroll.offset() <= 10000 - 24);
}
#[test]
fn test_command_palette_many_commands() {
use revue::widget::{Command, CommandPalette};
let mut palette = CommandPalette::new();
for i in 0..500 {
palette.add_command(Command::new(
format!("cmd_{}", i),
format!("Command Number {}", i),
));
}
palette.show();
assert_eq!(palette.filtered.len(), 500);
palette.set_query("42");
assert!(palette.filtered.len() < 500);
assert!(palette.filtered.len() >= 1); }
#[test]
fn test_sortable_list_many_items() {
use revue::widget::SortableList;
let items: Vec<String> = (0..1000).map(|i| format!("Item {}", i)).collect();
let mut list = SortableList::new(items);
assert_eq!(list.items().len(), 1000);
for _ in 0..1000 {
list.select_next();
}
assert_eq!(list.selected(), Some(999));
for _ in 0..10 {
list.move_up();
}
assert_eq!(list.selected(), Some(989));
}
#[test]
fn test_empty_css() {
let sheet = revue::style::parse_css("").unwrap();
assert!(sheet.rules.is_empty());
}
#[test]
fn test_whitespace_only_css() {
let sheet = revue::style::parse_css(" \n\n\t ").unwrap();
assert!(sheet.rules.is_empty());
}
#[test]
fn test_render_zero_area_no_panic() {
let mut buf = Buffer::new(1, 1);
let area = Rect::new(0, 0, 0, 0);
let mut ctx = RenderContext::new(&mut buf, area);
let text = Text::new("Should not render");
text.render(&mut ctx);
}
use revue::dom::WidgetMeta;
struct RenderCounter {
render_count: std::cell::Cell<u32>,
should_render: bool,
}
impl RenderCounter {
fn new(should_render: bool) -> Self {
Self {
render_count: std::cell::Cell::new(0),
should_render,
}
}
fn count(&self) -> u32 {
self.render_count.get()
}
}
impl View for RenderCounter {
fn render(&self, _ctx: &mut RenderContext) {
self.render_count.set(self.render_count.get() + 1);
}
fn needs_render(&self) -> bool {
self.should_render
}
fn meta(&self) -> WidgetMeta {
WidgetMeta::new("RenderCounter")
}
}
#[test]
fn test_needs_render_default_is_true() {
let text = Text::new("Hello");
assert!(text.needs_render());
}
#[test]
fn test_needs_render_skips_in_stack() {
use revue::widget::vstack;
let mut buf = Buffer::new(40, 10);
let area = Rect::new(0, 0, 40, 10);
let always = RenderCounter::new(true);
let never = RenderCounter::new(false);
let stack = vstack().child_sized(always, 3).child_sized(never, 3);
{
let mut ctx = RenderContext::new(&mut buf, area);
stack.render(&mut ctx);
}
}
#[test]
fn test_needs_render_false_widget() {
let widget = RenderCounter::new(false);
assert!(!widget.needs_render());
assert_eq!(widget.count(), 0);
let mut buf = Buffer::new(10, 5);
let area = Rect::new(0, 0, 10, 5);
let mut ctx = RenderContext::new(&mut buf, area);
widget.render(&mut ctx);
assert_eq!(widget.count(), 1);
}
#[test]
fn test_needs_render_true_widget() {
let widget = RenderCounter::new(true);
assert!(widget.needs_render());
}