use dotmax::{BrailleGrid, Color, TerminalRenderer, TerminalType};
macro_rules! require_terminal {
() => {
match TerminalRenderer::new() {
Ok(r) => r,
Err(_) => {
return;
}
}
};
}
#[test]
fn test_render_10x10_grid() {
let mut grid = BrailleGrid::new(10, 10).expect("Failed to create 10×10 grid");
grid.set_dot(5, 5).expect("Failed to set dot at (5,5)");
grid.set_dot(10, 10).expect("Failed to set dot at (10,10)");
grid.set_dot(15, 15).expect("Failed to set dot at (15,15)");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Rendering 10×10 grid should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup terminal");
}
#[test]
fn test_rendering_pipeline_with_braille_chars() {
let mut grid = BrailleGrid::new(20, 10).expect("Failed to create grid");
for i in 0..10 {
grid.set_dot(i * 2, i * 4).expect("Failed to set dot");
}
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(result.is_ok(), "Render should succeed: {:?}", result.err());
let (width, height) = renderer
.get_terminal_size()
.expect("Failed to get terminal size");
assert!(
width > 0 && height > 0,
"Terminal should have positive size"
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_clear_terminal() {
let mut renderer = require_terminal!();
let result = renderer.clear();
assert!(result.is_ok(), "Clear should succeed: {:?}", result.err());
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_get_terminal_size() {
let renderer = require_terminal!();
let result = renderer.get_terminal_size();
assert!(
result.is_ok(),
"Get size should succeed: {:?}",
result.err()
);
let (width, height) = result.unwrap();
assert!(
width >= 40,
"Terminal width should be at least 40, got {width}"
);
assert!(
height >= 12,
"Terminal height should be at least 12, got {height}"
);
}
#[test]
fn test_error_handling_terminal_too_small() {
let result = TerminalRenderer::new();
if let Ok(mut renderer) = result {
renderer.cleanup().expect("Cleanup failed");
}
}
#[test]
fn test_render_empty_grid() {
let grid = BrailleGrid::new(10, 10).expect("Failed to create grid");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Rendering empty grid should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_render_large_grid() {
let mut grid = BrailleGrid::new(80, 24).expect("Failed to create 80×24 grid");
for y in 0..24 * 4 {
for x in 0..80 * 2 {
if (x + y) % 3 == 0 {
grid.set_dot(x, y).expect("Failed to set dot");
}
}
}
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Rendering 80×24 grid should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_sequential_renders() {
let mut grid = BrailleGrid::new(20, 20).expect("Failed to create grid");
let mut renderer = require_terminal!();
for frame in 0..5 {
grid.set_dot(frame * 2, frame * 4)
.expect("Failed to set dot");
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Render frame {} should succeed: {:?}",
frame,
result.err()
);
}
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_terminal_resize_workflow() {
let mut renderer = require_terminal!();
let (cols, rows) = renderer
.get_terminal_size()
.expect("Failed to get terminal size");
let mut grid = BrailleGrid::new(cols as usize, rows as usize)
.expect("Failed to create grid matching terminal size");
grid.set_dot(10, 10).expect("Failed to set dot at (10, 10)");
grid.set_dot(20, 20).expect("Failed to set dot at (20, 20)");
grid.set_dot(30, 30).expect("Failed to set dot at (30, 30)");
renderer
.render(&grid)
.expect("Failed to render initial grid");
let new_width = (cols as usize).max(50); let new_height = (rows as usize).max(30);
grid.resize(new_width, new_height)
.expect("Failed to resize grid");
assert_eq!(
grid.dimensions(),
(new_width, new_height),
"Grid dimensions should match resize request"
);
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Rendering resized grid should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_resize_shrink_without_terminal() {
let mut grid = BrailleGrid::new(50, 30).expect("Failed to create grid");
grid.set_dot(10, 10).expect("Failed to set dot");
grid.set_dot(80, 100).expect("Failed to set dot");
grid.resize(20, 15).expect("Failed to resize");
assert_eq!(grid.dimensions(), (20, 15));
grid.set_dot(15, 15)
.expect("Should be able to set dots after resize");
}
#[test]
fn test_colored_rendering_workflow() {
let mut grid = BrailleGrid::new(20, 20).expect("Failed to create grid");
grid.enable_color_support();
grid.set_dot(10, 10).expect("Failed to set dot");
grid.set_cell_color(5, 2, Color::rgb(255, 0, 0))
.expect("Failed to set red color");
grid.set_dot(20, 20).expect("Failed to set dot");
grid.set_cell_color(10, 5, Color::rgb(0, 255, 0))
.expect("Failed to set green color");
grid.set_dot(30, 30).expect("Failed to set dot");
grid.set_cell_color(15, 7, Color::rgb(0, 0, 255))
.expect("Failed to set blue color");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Colored rendering should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_monochrome_fallback() {
let mut grid = BrailleGrid::new(10, 10).expect("Failed to create grid");
grid.enable_color_support();
grid.set_dot(5, 5).expect("Failed to set dot");
grid.set_dot(10, 10).expect("Failed to set dot");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Monochrome rendering should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_mixed_colored_and_monochrome_cells() {
let mut grid = BrailleGrid::new(20, 20).expect("Failed to create grid");
grid.enable_color_support();
grid.set_dot(10, 10).expect("Failed to set dot");
grid.set_cell_color(5, 2, Color::rgb(255, 128, 0))
.expect("Failed to set orange color");
grid.set_dot(20, 20).expect("Failed to set dot");
grid.set_dot(30, 30).expect("Failed to set dot");
grid.set_cell_color(15, 7, Color::black())
.expect("Failed to set black color");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Mixed rendering should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_color_rendering_with_predefined_colors() {
let mut grid = BrailleGrid::new(10, 10).expect("Failed to create grid");
grid.enable_color_support();
grid.set_dot(0, 0).expect("Failed to set dot");
grid.set_cell_color(0, 0, Color::black())
.expect("Failed to set black");
grid.set_dot(2, 2).expect("Failed to set dot");
grid.set_cell_color(1, 0, Color::white())
.expect("Failed to set white");
grid.set_dot(4, 4).expect("Failed to set dot");
grid.set_cell_color(2, 1, Color::rgb(255, 0, 255))
.expect("Failed to set magenta");
let mut renderer = require_terminal!();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Predefined color rendering should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_clear_colors_and_rerender() {
let mut grid = BrailleGrid::new(10, 10).expect("Failed to create grid");
grid.enable_color_support();
grid.set_dot(10, 10).expect("Failed to set dot");
grid.set_cell_color(5, 2, Color::rgb(255, 0, 0))
.expect("Failed to set color");
let mut renderer = require_terminal!();
renderer.render(&grid).expect("Initial render failed");
grid.clear_colors();
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Render after clear_colors should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}
#[test]
fn test_terminal_type_detection() {
let terminal_type = TerminalType::detect();
match terminal_type {
TerminalType::WindowsTerminal
| TerminalType::Wsl
| TerminalType::WindowsConsole
| TerminalType::MacOsTerminal
| TerminalType::LinuxNative
| TerminalType::Unknown => {
}
}
let name = terminal_type.name();
assert!(!name.is_empty(), "Terminal type name should not be empty");
}
#[test]
fn test_terminal_capabilities_include_type() {
let renderer = require_terminal!();
let caps = renderer.capabilities();
let _ = caps.terminal_type;
let name = caps.terminal_type.name();
assert!(!name.is_empty(), "Terminal type should be detected");
assert!(caps.supports_unicode, "Should support Unicode");
}
#[test]
fn test_viewport_offset_calculation() {
let test_cases = vec![
(TerminalType::WindowsTerminal, 24, 0),
(TerminalType::WindowsTerminal, 100, 0),
(TerminalType::Wsl, 20, 0),
(TerminalType::Wsl, 21, 12),
(TerminalType::Wsl, 53, 12),
(TerminalType::WindowsConsole, 20, 0),
(TerminalType::WindowsConsole, 21, 12),
(TerminalType::WindowsConsole, 74, 12),
(TerminalType::WindowsConsole, 100, 12),
(TerminalType::MacOsTerminal, 24, 0),
(TerminalType::LinuxNative, 24, 0),
(TerminalType::Unknown, 24, 0),
];
for (terminal_type, height, expected_offset) in test_cases {
let offset = terminal_type.viewport_height_offset(height);
assert_eq!(
offset,
expected_offset,
"{} with height {} should have offset {}",
terminal_type.name(),
height,
expected_offset
);
}
}
#[test]
fn test_get_terminal_size_uses_viewport_detection() {
let renderer = require_terminal!();
let (width, height) = renderer
.get_terminal_size()
.expect("Failed to get terminal size");
assert!(width > 0, "Width should be positive");
assert!(height > 0, "Height should be positive");
assert!(
height >= 12,
"Height should be at least 12 after viewport adjustment"
);
}
#[test]
fn test_rendering_respects_viewport_dimensions() {
let mut renderer = require_terminal!();
let (width, height) = renderer
.get_terminal_size()
.expect("Failed to get terminal size");
let mut grid = BrailleGrid::new(width as usize, height as usize)
.expect("Failed to create grid matching viewport size");
for y in 0..height as usize * 4 {
for x in 0..width as usize * 2 {
if (x + y) % 5 == 0 {
grid.set_dot(x, y).expect("Failed to set dot");
}
}
}
let result = renderer.render(&grid);
assert!(
result.is_ok(),
"Rendering with viewport-adjusted size should succeed: {:?}",
result.err()
);
renderer.cleanup().expect("Failed to cleanup");
}