use revue::event::Key;
use revue::layout::Rect;
use revue::render::Buffer;
use revue::style::Color;
use revue::widget::traits::RenderContext;
use revue::widget::{Resizable, ResizeHandle, ResizeStyle, StyledView, View};
#[test]
fn test_resizable_default_creation() {
let r = Resizable::new(20, 10);
assert_eq!(r.size(), (20, 10));
assert!(!r.is_resizing());
}
#[test]
fn test_resizable_minimum_size() {
let r = Resizable::new(0, 0);
assert_eq!(r.size(), (1, 1));
}
#[test]
fn test_resizable_large_size() {
let r = Resizable::new(200, 100);
assert_eq!(r.size(), (200, 100));
}
#[test]
fn test_resizable_min_size_builder() {
let r = Resizable::new(20, 10).min_size(10, 5);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_min_size_with_zero() {
let r = Resizable::new(20, 10).min_size(0, 0);
let _ = r;
}
#[test]
fn test_resizable_max_size_builder() {
let r = Resizable::new(20, 10).max_size(50, 30);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_max_size_zero_means_unlimited() {
let r = Resizable::new(20, 10).max_size(0, 0);
let _ = r;
}
#[test]
fn test_resizable_handles_builder_all() {
let r = Resizable::new(20, 10).handles(ResizeHandle::ALL);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(0, 0, area), Some(ResizeHandle::TopLeft));
assert_eq!(r.handle_at(10, 0, area), Some(ResizeHandle::Top));
assert_eq!(r.handle_at(0, 5, area), Some(ResizeHandle::Left));
}
#[test]
fn test_resizable_handles_builder_edges() {
let r = Resizable::new(20, 10).handles(ResizeHandle::EDGES);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(10, 0, area), Some(ResizeHandle::Top));
assert_eq!(r.handle_at(10, 9, area), Some(ResizeHandle::Bottom));
assert_eq!(r.handle_at(0, 5, area), Some(ResizeHandle::Left));
assert_eq!(r.handle_at(19, 5, area), Some(ResizeHandle::Right));
assert_eq!(r.handle_at(0, 0, area), None);
}
#[test]
fn test_resizable_handles_builder_corners() {
let r = Resizable::new(20, 10).handles(ResizeHandle::CORNERS);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(0, 0, area), Some(ResizeHandle::TopLeft));
assert_eq!(r.handle_at(19, 0, area), Some(ResizeHandle::TopRight));
assert_eq!(r.handle_at(10, 0, area), None);
}
#[test]
fn test_resizable_handles_builder_single() {
let r = Resizable::new(20, 10).handles(&[ResizeHandle::Right][..]);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(19, 5, area), Some(ResizeHandle::Right));
assert_eq!(r.handle_at(0, 5, area), None);
}
#[test]
fn test_resizable_handles_builder_empty() {
let r = Resizable::new(20, 10).handles(&[]);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(0, 0, area), None);
assert_eq!(r.handle_at(19, 5, area), None);
}
#[test]
fn test_resizable_style_builder_border() {
let r = Resizable::new(20, 10).style(ResizeStyle::Border);
let area = Rect::new(0, 0, 20, 10);
let content = r.content_area(area);
assert_eq!(content.x, 1);
assert_eq!(content.y, 1);
}
#[test]
fn test_resizable_style_builder_subtle() {
let r = Resizable::new(20, 10).style(ResizeStyle::Subtle);
let area = Rect::new(0, 0, 20, 10);
let content = r.content_area(area);
assert_eq!(content.x, 0);
assert_eq!(content.y, 0);
}
#[test]
fn test_resizable_style_builder_hidden() {
let r = Resizable::new(20, 10).style(ResizeStyle::Hidden);
let area = Rect::new(0, 0, 20, 10);
let content = r.content_area(area);
assert_eq!(content.x, 0);
assert_eq!(content.y, 0);
}
#[test]
fn test_resizable_style_builder_dots() {
let r = Resizable::new(20, 10).style(ResizeStyle::Dots);
let area = Rect::new(0, 0, 20, 10);
let content = r.content_area(area);
assert_eq!(content.x, 0);
assert_eq!(content.y, 0);
}
#[test]
fn test_resizable_handle_color_builder() {
let r = Resizable::new(20, 10).handle_color(Color::RED);
let _ = r;
}
#[test]
fn test_resizable_active_color_builder() {
let r = Resizable::new(20, 10).active_color(Color::GREEN);
let _ = r;
}
#[test]
fn test_resizable_preserve_aspect_ratio_builder() {
let r = Resizable::new(20, 10).preserve_aspect_ratio();
let mut r = r;
r.set_size(40, 10);
assert_eq!(r.size(), (40, 20));
}
#[test]
fn test_resizable_custom_aspect_ratio_builder() {
let r = Resizable::new(20, 10).aspect_ratio(1.5);
let mut r = r;
r.set_size(30, 10);
assert_eq!(r.size(), (30, 20));
}
#[test]
fn test_resizable_snap_to_grid_builder() {
let mut r = Resizable::new(20, 10).snap_to_grid(5, 5);
r.set_size(23, 12);
assert_eq!(r.size(), (25, 10));
}
#[test]
fn test_resizable_snap_to_grid_clamped() {
let mut r = Resizable::new(20, 10).snap_to_grid(0, 0);
r.set_size(23, 12);
assert_eq!(r.size(), (23, 12));
}
#[test]
fn test_resizable_on_resize_builder() {
use std::cell::Cell;
use std::rc::Rc;
let called = Rc::new(Cell::new(false));
let called_clone = called.clone();
let mut r = Resizable::new(20, 10).on_resize(move |_w, _h| {
called_clone.set(true);
});
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(5, 3);
assert!(called.get());
}
#[test]
fn test_resizable_set_size_basic() {
let mut r = Resizable::new(20, 10);
r.set_size(30, 15);
assert_eq!(r.size(), (30, 15));
}
#[test]
fn test_resizable_set_size_respects_min() {
let mut r = Resizable::new(20, 10).min_size(10, 5);
r.set_size(5, 2);
assert_eq!(r.size(), (10, 5));
}
#[test]
fn test_resizable_set_size_respects_max() {
let mut r = Resizable::new(20, 10).max_size(30, 15);
r.set_size(50, 20);
assert_eq!(r.size(), (30, 15));
}
#[test]
fn test_resizable_set_size_max_zero_no_limit() {
let mut r = Resizable::new(20, 10).max_size(0, 0);
r.set_size(1000, 1000);
assert_eq!(r.size(), (1000, 1000));
}
#[test]
fn test_resizable_set_size_max_width_only() {
let mut r = Resizable::new(20, 10).max_size(30, 0);
r.set_size(50, 100);
assert_eq!(r.size(), (30, 100));
}
#[test]
fn test_resizable_set_size_max_height_only() {
let mut r = Resizable::new(20, 10).max_size(0, 15);
r.set_size(100, 20);
assert_eq!(r.size(), (100, 15));
}
#[test]
fn test_resizable_start_resize_valid_handle() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::BottomRight);
assert!(r.is_resizing());
}
#[test]
fn test_resizable_start_resize_invalid_handle() {
let mut r = Resizable::new(20, 10).handles(ResizeHandle::CORNERS);
r.start_resize(ResizeHandle::Top);
assert!(!r.is_resizing());
}
#[test]
fn test_resizable_end_resize() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::BottomRight);
assert!(r.is_resizing());
r.end_resize();
assert!(!r.is_resizing());
}
#[test]
fn test_resizable_apply_delta_not_resizing() {
let mut r = Resizable::new(20, 10);
r.apply_delta(10, 10);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_apply_delta_horizontal_right() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::Right);
r.apply_delta(10, 0);
assert_eq!(r.size(), (30, 10));
}
#[test]
fn test_resizable_apply_delta_horizontal_left() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::Left);
r.apply_delta(-10, 0);
assert_eq!(r.size(), (30, 10));
}
#[test]
fn test_resizable_apply_delta_vertical_bottom() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::Bottom);
r.apply_delta(0, 5);
assert_eq!(r.size(), (20, 15));
}
#[test]
fn test_resizable_apply_delta_vertical_top() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::Top);
r.apply_delta(0, -5);
assert_eq!(r.size(), (20, 15));
}
#[test]
fn test_resizable_apply_delta_both() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(5, 3);
assert_eq!(r.size(), (25, 13));
}
#[test]
fn test_resizable_apply_delta_respects_min() {
let mut r = Resizable::new(20, 10).min_size(15, 8);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(-10, -5);
assert_eq!(r.size(), (15, 8));
}
#[test]
fn test_resizable_apply_delta_respects_max() {
let mut r = Resizable::new(20, 10).max_size(30, 20);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(100, 100);
assert_eq!(r.size(), (30, 20));
}
#[test]
fn test_resizable_apply_delta_never_below_one() {
let mut r = Resizable::new(5, 5).min_size(1, 1);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(-100, -100);
assert_eq!(r.size(), (1, 1));
}
#[test]
fn test_resizable_aspect_ratio_preserved() {
let mut r = Resizable::new(20, 10).preserve_aspect_ratio();
r.set_size(40, 5);
assert_eq!(r.size(), (40, 20));
}
#[test]
fn test_resizable_aspect_ratio_with_min() {
let mut r = Resizable::new(20, 10)
.preserve_aspect_ratio()
.min_size(10, 5);
r.set_size(15, 10);
assert_eq!(r.size(), (15, 7));
}
#[test]
fn test_resizable_aspect_ratio_with_max() {
let mut r = Resizable::new(20, 10)
.preserve_aspect_ratio()
.max_size(50, 20);
r.set_size(100, 10);
let (w, h) = r.size();
assert_eq!(w, 50);
assert_eq!(h, 20);
}
#[test]
fn test_resizable_custom_aspect_ratio() {
let mut r = Resizable::new(20, 10).aspect_ratio(4.0);
r.set_size(40, 5);
assert_eq!(r.size(), (40, 10));
}
#[test]
fn test_resizable_grid_snap_basic() {
let mut r = Resizable::new(20, 10).snap_to_grid(5, 5);
r.set_size(23, 12);
assert_eq!(r.size(), (25, 10));
}
#[test]
fn test_resizable_grid_snap_round_up() {
let mut r = Resizable::new(20, 10).snap_to_grid(10, 10);
r.set_size(26, 16);
assert_eq!(r.size(), (30, 20));
}
#[test]
fn test_resizable_grid_snap_round_down() {
let mut r = Resizable::new(20, 10).snap_to_grid(10, 10);
r.set_size(24, 14);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_grid_snap_exactly_on_grid() {
let mut r = Resizable::new(20, 10).snap_to_grid(5, 5);
r.set_size(25, 15);
assert_eq!(r.size(), (25, 15));
}
#[test]
fn test_resizable_grid_snap_different_grids() {
let mut r = Resizable::new(20, 10).snap_to_grid(10, 5);
r.set_size(27, 13);
assert_eq!(r.size(), (30, 15));
}
#[test]
fn test_resizable_handle_at_corner() {
let r = Resizable::new(20, 10);
let area = Rect::new(5, 5, 20, 10);
assert_eq!(r.handle_at(5, 5, area), Some(ResizeHandle::TopLeft));
assert_eq!(r.handle_at(24, 5, area), Some(ResizeHandle::TopRight));
assert_eq!(r.handle_at(5, 14, area), Some(ResizeHandle::BottomLeft));
assert_eq!(r.handle_at(24, 14, area), Some(ResizeHandle::BottomRight));
}
#[test]
fn test_resizable_handle_at_edge() {
let r = Resizable::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(10, 0, area), Some(ResizeHandle::Top));
assert_eq!(r.handle_at(10, 9, area), Some(ResizeHandle::Bottom));
assert_eq!(r.handle_at(0, 5, area), Some(ResizeHandle::Left));
assert_eq!(r.handle_at(19, 5, area), Some(ResizeHandle::Right));
}
#[test]
fn test_resizable_handle_at_center() {
let r = Resizable::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(10, 5, area), None);
}
#[test]
fn test_resizable_handle_at_inside_area() {
let r = Resizable::new(20, 10);
let area = Rect::new(5, 5, 20, 10);
assert_eq!(r.handle_at(15, 10, area), None);
}
#[test]
fn test_resizable_handle_at_with_limited_handles() {
let r = Resizable::new(20, 10).handles(ResizeHandle::CORNERS);
let area = Rect::new(0, 0, 20, 10);
assert_eq!(r.handle_at(10, 0, area), None);
assert_eq!(r.handle_at(10, 9, area), None);
assert_eq!(r.handle_at(0, 0, area), Some(ResizeHandle::TopLeft));
assert_eq!(r.handle_at(19, 9, area), Some(ResizeHandle::BottomRight));
}
#[test]
fn test_resizable_set_hovered_handle() {
let mut r = Resizable::new(20, 10);
r.set_hovered(Some(ResizeHandle::TopLeft));
r.set_hovered(None);
}
#[test]
fn test_resizable_set_hovered_different_corners() {
let mut r = Resizable::new(20, 10);
for handle in ResizeHandle::ALL.iter() {
r.set_hovered(Some(*handle));
}
}
#[test]
fn test_resizable_content_area_border_style() {
let r = Resizable::new(20, 10).style(ResizeStyle::Border);
let area = Rect::new(5, 5, 100, 100);
let content = r.content_area(area);
assert_eq!(content.x, 6);
assert_eq!(content.y, 6);
assert_eq!(content.width, 18);
assert_eq!(content.height, 8);
}
#[test]
fn test_resizable_content_area_dots_style() {
let r = Resizable::new(20, 10).style(ResizeStyle::Dots);
let area = Rect::new(5, 5, 100, 100);
let content = r.content_area(area);
assert_eq!(content.x, 5);
assert_eq!(content.y, 5);
assert_eq!(content.width, 20);
assert_eq!(content.height, 10);
}
#[test]
fn test_resizable_content_area_subtle_style() {
let r = Resizable::new(20, 10).style(ResizeStyle::Subtle);
let area = Rect::new(5, 5, 100, 100);
let content = r.content_area(area);
assert_eq!(content.x, 5);
assert_eq!(content.y, 5);
assert_eq!(content.width, 20);
assert_eq!(content.height, 10);
}
#[test]
fn test_resizable_content_area_hidden_style() {
let r = Resizable::new(20, 10).style(ResizeStyle::Hidden);
let area = Rect::new(5, 5, 100, 100);
let content = r.content_area(area);
assert_eq!(content.x, 5);
assert_eq!(content.y, 5);
assert_eq!(content.width, 20);
assert_eq!(content.height, 10);
}
#[test]
fn test_resizable_content_area_small_size() {
let r = Resizable::new(3, 3).style(ResizeStyle::Border);
let area = Rect::new(0, 0, 10, 10);
let content = r.content_area(area);
assert_eq!(content.x, 1);
assert_eq!(content.y, 1);
assert_eq!(content.width, 1);
assert_eq!(content.height, 1);
}
#[test]
fn test_resizable_key_right_increases_width() {
let mut r = Resizable::new(20, 10).focused(true);
r.handle_key(&Key::Right);
assert_eq!(r.size(), (21, 10));
}
#[test]
fn test_resizable_key_left_decreases_width() {
let mut r = Resizable::new(20, 10).focused(true);
r.handle_key(&Key::Left);
assert_eq!(r.size(), (19, 10));
}
#[test]
fn test_resizable_key_down_increases_height() {
let mut r = Resizable::new(20, 10).focused(true);
r.handle_key(&Key::Down);
assert_eq!(r.size(), (20, 11));
}
#[test]
fn test_resizable_key_up_decreases_height() {
let mut r = Resizable::new(20, 10).focused(true);
r.handle_key(&Key::Up);
assert_eq!(r.size(), (20, 9));
}
#[test]
fn test_resizable_key_not_focused_ignored() {
let mut r = Resizable::new(20, 10);
let handled = r.handle_key(&Key::Right);
assert!(!handled);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_key_unhandled_key() {
let mut r = Resizable::new(20, 10).focused(true);
let handled = r.handle_key(&Key::Char('a'));
assert!(!handled);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_key_without_required_handle() {
let r = Resizable::new(20, 10).handles(ResizeHandle::CORNERS);
let mut r = r.focused(true);
let handled = r.handle_key(&Key::Right);
assert!(!handled);
assert_eq!(r.size(), (20, 10));
}
#[test]
fn test_resizable_key_respects_min_width() {
let r = Resizable::new(5, 5).min_size(5, 5);
let mut r = r.focused(true);
r.handle_key(&Key::Left);
assert_eq!(r.size(), (5, 5));
}
#[test]
fn test_resizable_key_respects_max_width() {
let r = Resizable::new(20, 10).max_size(25, 15);
let mut r = r.focused(true);
r.handle_key(&Key::Right);
r.handle_key(&Key::Right);
r.handle_key(&Key::Right);
r.handle_key(&Key::Right);
r.handle_key(&Key::Right);
assert_eq!(r.size(), (25, 10));
}
#[test]
fn test_resizable_render_border_style() {
let r = Resizable::new(10, 5).style(ResizeStyle::Border);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().symbol, '┌');
assert_eq!(buffer.get(9, 0).unwrap().symbol, '┐');
assert_eq!(buffer.get(0, 4).unwrap().symbol, '└');
assert_eq!(buffer.get(9, 4).unwrap().symbol, '┘');
}
#[test]
fn test_resizable_render_border_top_and_bottom() {
let r = Resizable::new(10, 5).style(ResizeStyle::Border);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(1, 0).unwrap().symbol, '─');
assert_eq!(buffer.get(5, 0).unwrap().symbol, '─');
assert_eq!(buffer.get(8, 0).unwrap().symbol, '─');
assert_eq!(buffer.get(1, 4).unwrap().symbol, '─');
assert_eq!(buffer.get(5, 4).unwrap().symbol, '─');
assert_eq!(buffer.get(8, 4).unwrap().symbol, '─');
}
#[test]
fn test_resizable_render_border_sides() {
let r = Resizable::new(10, 5).style(ResizeStyle::Border);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 1).unwrap().symbol, '│');
assert_eq!(buffer.get(0, 2).unwrap().symbol, '│');
assert_eq!(buffer.get(0, 3).unwrap().symbol, '│');
assert_eq!(buffer.get(9, 1).unwrap().symbol, '│');
assert_eq!(buffer.get(9, 2).unwrap().symbol, '│');
assert_eq!(buffer.get(9, 3).unwrap().symbol, '│');
}
#[test]
fn test_resizable_render_dots_style() {
let r = Resizable::new(10, 5).style(ResizeStyle::Dots);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().symbol, '●');
assert_eq!(buffer.get(9, 0).unwrap().symbol, '●');
assert_eq!(buffer.get(0, 4).unwrap().symbol, '●');
assert_eq!(buffer.get(9, 4).unwrap().symbol, '●');
}
#[test]
fn test_resizable_render_hidden_style() {
let r = Resizable::new(10, 5).style(ResizeStyle::Hidden);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().symbol, ' ');
assert_eq!(buffer.get(9, 0).unwrap().symbol, ' ');
}
#[test]
fn test_resizable_render_subtle_not_hovered() {
let r = Resizable::new(10, 5).style(ResizeStyle::Subtle);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().symbol, ' ');
}
#[test]
fn test_resizable_render_subtle_hovered() {
let mut r = Resizable::new(10, 5).style(ResizeStyle::Subtle);
r.set_hovered(Some(ResizeHandle::TopLeft));
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().symbol, '┌');
}
#[test]
fn test_resizable_render_resizing_active_color() {
let mut r = Resizable::new(10, 5)
.style(ResizeStyle::Border)
.active_color(Color::RED);
r.start_resize(ResizeHandle::BottomRight);
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(0, 0).unwrap().fg, Some(Color::RED));
}
#[test]
fn test_resizable_render_hovered_corner_highlight() {
let mut r = Resizable::new(10, 5)
.style(ResizeStyle::Border)
.active_color(Color::CYAN);
r.set_hovered(Some(ResizeHandle::TopRight));
let mut buffer = Buffer::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(9, 0).unwrap().fg, Some(Color::CYAN));
}
#[test]
fn test_resizable_id() {
let r = Resizable::new(20, 10).element_id("test-resizable");
assert_eq!(View::id(&r), Some("test-resizable"));
}
#[test]
fn test_resizable_classes() {
let r = Resizable::new(20, 10)
.class("resizable")
.class("interactive");
assert!(r.has_class("resizable"));
assert!(r.has_class("interactive"));
assert!(!r.has_class("other"));
}
#[test]
fn test_resizable_styled_view_methods() {
let mut r = Resizable::new(20, 10);
r.set_id("my-resizable");
assert_eq!(View::id(&r), Some("my-resizable"));
r.add_class("active");
assert!(r.has_class("active"));
r.remove_class("active");
assert!(!r.has_class("active"));
r.toggle_class("selected");
assert!(r.has_class("selected"));
r.toggle_class("selected");
assert!(!r.has_class("selected"));
}
#[test]
fn test_resizable_meta() {
let r = Resizable::new(20, 10)
.element_id("test")
.class("widget")
.class("resizable");
let meta = r.meta();
assert_eq!(meta.id, Some("test".to_string()));
assert!(meta.classes.contains("widget"));
assert!(meta.classes.contains("resizable"));
}
#[test]
fn test_resizable_foreground_color() {
let r = Resizable::new(20, 10).fg(Color::RED);
let _ = r;
}
#[test]
fn test_resizable_background_color() {
let r = Resizable::new(20, 10).bg(Color::BLUE);
let _ = r;
}
#[test]
fn test_resize_handle_all_contains_all() {
assert_eq!(ResizeHandle::ALL.len(), 8);
assert!(ResizeHandle::ALL.contains(&ResizeHandle::Top));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::Bottom));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::Left));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::Right));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::TopLeft));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::TopRight));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::BottomLeft));
assert!(ResizeHandle::ALL.contains(&ResizeHandle::BottomRight));
}
#[test]
fn test_resize_handle_edges_only() {
assert_eq!(ResizeHandle::EDGES.len(), 4);
assert!(ResizeHandle::EDGES.contains(&ResizeHandle::Top));
assert!(ResizeHandle::EDGES.contains(&ResizeHandle::Bottom));
assert!(ResizeHandle::EDGES.contains(&ResizeHandle::Left));
assert!(ResizeHandle::EDGES.contains(&ResizeHandle::Right));
assert!(!ResizeHandle::EDGES.contains(&ResizeHandle::TopLeft));
}
#[test]
fn test_resize_handle_corners_only() {
assert_eq!(ResizeHandle::CORNERS.len(), 4);
assert!(ResizeHandle::CORNERS.contains(&ResizeHandle::TopLeft));
assert!(ResizeHandle::CORNERS.contains(&ResizeHandle::TopRight));
assert!(ResizeHandle::CORNERS.contains(&ResizeHandle::BottomLeft));
assert!(ResizeHandle::CORNERS.contains(&ResizeHandle::BottomRight));
assert!(!ResizeHandle::CORNERS.contains(&ResizeHandle::Top));
}
#[test]
fn test_resizable_size_one_by_one() {
let mut r = Resizable::new(1, 1).min_size(1, 1);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(-100, -100);
assert_eq!(r.size(), (1, 1));
}
#[test]
fn test_resizable_large_resize() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(1000, 1000);
assert_eq!(r.size(), (1020, 1010));
}
#[test]
fn test_resizable_negative_delta_positive_resize() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::TopLeft);
r.apply_delta(-5, -5);
assert_eq!(r.size(), (25, 15));
}
#[test]
fn test_resizable_positive_delta_negative_resize() {
let mut r = Resizable::new(30, 20);
r.start_resize(ResizeHandle::TopLeft);
r.apply_delta(5, 5);
assert_eq!(r.size(), (25, 15));
}
#[test]
fn test_resizable_chain_builder_methods() {
let r = Resizable::new(20, 10)
.min_size(10, 5)
.max_size(50, 30)
.handles(ResizeHandle::CORNERS)
.style(ResizeStyle::Dots)
.handle_color(Color::RED)
.active_color(Color::GREEN)
.preserve_aspect_ratio()
.snap_to_grid(5, 5);
assert_eq!(r.size(), (20, 10));
let mut r = r;
r.set_size(5, 2);
assert_eq!(r.size(), (10, 5));
r.set_size(100, 50);
let (w, h) = r.size();
assert_eq!(w, 50);
assert!(h <= 30);
}
#[test]
fn test_resizable_callback_invoked_on_resize() {
use std::cell::Cell;
use std::rc::Rc;
let call_count = Rc::new(Cell::new(0));
let last_width = Rc::new(Cell::new(0u16));
let last_height = Rc::new(Cell::new(0u16));
let count_clone = call_count.clone();
let width_clone = last_width.clone();
let height_clone = last_height.clone();
let mut r = Resizable::new(20, 10).on_resize(move |w, h| {
count_clone.set(count_clone.get() + 1);
width_clone.set(w);
height_clone.set(h);
});
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(5, 3);
r.apply_delta(2, 1);
assert_eq!(call_count.get(), 2);
assert_eq!(last_width.get(), 27);
assert_eq!(last_height.get(), 14);
}
#[test]
fn test_resizable_callback_not_invoked_when_no_change() {
use std::cell::Cell;
use std::rc::Rc;
let called = Rc::new(Cell::new(false));
let called_clone = called.clone();
let mut r = Resizable::new(20, 10)
.max_size(20, 10)
.on_resize(move |_w, _h| {
called_clone.set(true);
});
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(5, 5);
assert!(!called.get());
}
#[test]
fn test_resizable_render_with_offset_area() {
let r = Resizable::new(10, 5).style(ResizeStyle::Border);
let mut buffer = Buffer::new(30, 20);
let area = Rect::new(10, 10, 20, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
r.render(&mut ctx);
assert_eq!(buffer.get(10, 10).unwrap().symbol, '┌');
assert_eq!(buffer.get(19, 10).unwrap().symbol, '┐');
assert_eq!(buffer.get(10, 14).unwrap().symbol, '└');
assert_eq!(buffer.get(19, 14).unwrap().symbol, '┘');
}
#[test]
fn test_resizable_hit_test_all_handles() {
let r = Resizable::new(20, 10);
let area = Rect::new(0, 0, 20, 10);
let handles = [
(2, 0, ResizeHandle::Top), (17, 0, ResizeHandle::Top), (2, 9, ResizeHandle::Bottom), (17, 9, ResizeHandle::Bottom), (0, 2, ResizeHandle::Left), (0, 7, ResizeHandle::Left), (19, 2, ResizeHandle::Right), (19, 7, ResizeHandle::Right), (0, 0, ResizeHandle::TopLeft), (19, 0, ResizeHandle::TopRight), (0, 9, ResizeHandle::BottomLeft), (19, 9, ResizeHandle::BottomRight), ];
for (x, y, expected) in handles {
assert_eq!(
r.handle_at(x, y, area),
Some(expected),
"Failed at ({}, {})",
x,
y
);
}
}
#[test]
fn test_resizable_aspect_ratio_zero_height_protection() {
let mut r = Resizable::new(20, 10).preserve_aspect_ratio();
r.set_size(30, 0);
let (_w, h) = r.size();
assert!(h > 0);
}
#[test]
fn test_resizable_multiple_resize_operations() {
let mut r = Resizable::new(20, 10);
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(10, 5);
r.end_resize();
r.start_resize(ResizeHandle::TopLeft);
r.apply_delta(-5, -3);
r.end_resize();
r.start_resize(ResizeHandle::Right);
r.apply_delta(15, 0);
r.end_resize();
assert_eq!(r.size(), (50, 18));
}
#[test]
fn test_resizable_no_callback_when_resizing_same_size() {
use std::cell::Cell;
use std::rc::Rc;
let called = Rc::new(Cell::new(false));
let called_clone = called.clone();
let mut r = Resizable::new(20, 10)
.max_size(20, 10)
.on_resize(move |_w, _h| {
called_clone.set(true);
});
r.start_resize(ResizeHandle::BottomRight);
r.apply_delta(5, 5);
assert!(!called.get());
}