use eye_declare::{Element, Fluent, col, text};
use eye_declare_engine::Engine;
use eye_declare_engine::frame::Frame;
use eye_declare_engine::test_terminal::TestTerminal;
use ratatui_core::buffer::Buffer;
use ratatui_core::layout::Rect;
fn to_frame(el: &impl Element, width: u16) -> Frame {
let height = el.height(width);
let area = Rect::new(0, 0, width, height);
let mut buf = Buffer::empty(area);
el.render(area, &mut buf);
Frame::new(buf)
}
#[test]
fn tail_reaches_the_terminal() {
let tail = col().child(text("hello")).child(text("world"));
let mut engine = Engine::new(10, 24);
let mut term = TestTerminal::new(10, 24);
term.feed(&engine.present(to_frame(&tail, 10), None));
assert_eq!(term.viewport_lines()[0], "hello");
assert_eq!(term.viewport_lines()[1], "world");
}
#[test]
fn tail_rerender_diffs_to_minimal_output() {
let mut engine = Engine::new(10, 24);
let mut term = TestTerminal::new(10, 24);
let tail = |busy: bool| {
col()
.child(text("status"))
.when(busy, |c| c.child(text("busy")))
};
term.feed(&engine.present(to_frame(&tail(true), 10), None));
assert_eq!(term.viewport_lines()[1], "busy");
let bytes = engine.present(to_frame(&tail(true), 10), None);
assert!(bytes.len() <= 8, "identical tail should be near-empty diff");
term.feed(&engine.present(to_frame(&tail(false), 10), None));
assert_eq!(term.viewport_lines()[1], "");
}
#[test]
fn wrapped_text_measures_and_renders_consistently() {
let tail = col().child(text("hello world, this wraps"));
let width = 8;
let frame = to_frame(&tail, width);
assert!(frame.area().height >= 3);
let mut engine = Engine::new(width, 24);
let mut term = TestTerminal::new(8, 24);
term.feed(&engine.present(frame, None));
assert_eq!(term.viewport_lines()[0], "hello");
}
#[test]
fn commit_block_above_live_tail() {
let width = 12;
let mut engine = Engine::new(width, 24);
let mut term = TestTerminal::new(12, 24);
let tail = col().child(text("> input"));
term.feed(&engine.present(to_frame(&tail, width), None));
assert_eq!(term.viewport_lines()[0], "> input");
let block = col().child(text("you: hi"));
let block_height = block.height(width);
let stacked = col().child(block).child(text("> input"));
term.feed(&engine.present(to_frame(&stacked, width), None));
term.feed(&engine.commit_scrolled(block_height));
assert_eq!(term.viewport_lines()[0], "you: hi");
assert_eq!(term.viewport_lines()[1], "> input");
let tail2 = col().child(text("> inputx"));
term.feed(&engine.present(to_frame(&tail2, width), None));
assert_eq!(term.viewport_lines()[0], "you: hi");
assert_eq!(term.viewport_lines()[1], "> inputx");
}
#[test]
fn growing_tail_from_empty_keeps_cursor_sync() {
let width = 18;
let mut engine = Engine::new(width, 18);
let mut term = TestTerminal::new(18, 18);
term.feed(&engine.present(to_frame(&col(), width), None));
term.feed(&engine.present(to_frame(&col().child(text("")), width), None));
let tail = col().child(text("%")).child(text(""));
term.feed(&engine.present(to_frame(&tail, width), None));
assert_eq!(
term.viewport_lines()[0],
"%",
"content painted one row below the region origin: {:?}",
term.viewport_lines()
);
}
#[test]
fn wide_glyph_survives_tail_height_change() {
let width = 13;
let mut engine = Engine::new(width, 9);
let mut term = TestTerminal::new(13, 9);
term.feed(&engine.present(to_frame(&col(), width), None));
term.feed(&engine.present(
to_frame(&col().child(text("!*")).child(text("")), width),
None,
));
term.feed(&engine.present(to_frame(&col().child(text("日")), width), None));
assert_eq!(term.viewport_lines()[0], "日");
}