hefesto-widgets 0.7.3

Ratatui widgets for the Hefesto TUI toolkit: popups, scrollable lists, trees, text input and spinners
Documentation
use super::*;
use insta::assert_snapshot;
use ratatui::{backend::TestBackend, Terminal};

use crate::{Badge, BadgeAnchor, BadgeStack};

fn render_stateful(name: &str, popup: FileBrowserPopup, state: &mut FileBrowserState) {
    let backend = TestBackend::new(60, 20);
    let mut terminal = Terminal::new(backend).unwrap();
    terminal
        .draw(|f| f.render_stateful_widget(popup, f.area(), state))
        .unwrap();
    assert_snapshot!(name, terminal.backend());
}

fn make_state() -> FileBrowserState {
    FileBrowserState {
        entries: vec![
            FileEntry {
                name: "Documentos".to_string(),
                is_dir: true,
                path: "/home/user/Documentos".into(),
            },
            FileEntry {
                name: "foto.jpg".to_string(),
                is_dir: false,
                path: "/home/user/foto.jpg".into(),
            },
            FileEntry {
                name: "notas.txt".to_string(),
                is_dir: false,
                path: "/home/user/notas.txt".into(),
            },
        ],
        items: vec![
            ("📁 Documentos".to_string(), Style::new().fg(Color::Cyan)),
            ("📄 foto.jpg".to_string(), Style::default()),
            ("📄 notas.txt".to_string(), Style::default()),
        ],
        cwd: "/home/user".into(),
        choose_popup_state: ChoosePopupState::default(),
        show_hidden: false,
    }
}

// ── resolve_rect ──

#[test]
fn resolve_rect_with_fixed_height() {
    let popup = FileBrowserPopup::new()
        .width(PopupSize::Fixed(30))
        .height(PopupSize::Fixed(10));
    let state = make_state();
    let rect = popup.resolve_rect(Rect::new(0, 0, 100, 50), &state);
    assert_eq!(rect.width, 30);
    assert_eq!(rect.height, 10);
}

#[test]
fn resolve_rect_auto_uses_auto_height() {
    let popup = FileBrowserPopup::new();
    let state = make_state();
    let auto_h = popup.auto_height(&state, Rect::new(0, 0, 100, 50));
    assert_eq!(auto_h, 8);
    let rect = popup.resolve_rect(Rect::new(0, 0, 100, 50), &state);
    assert_eq!(rect.height, 8);
}

// ── snapshots ──

#[test]
fn snapshot_default() {
    let popup = FileBrowserPopup::new();
    let mut state = make_state();
    render_stateful("file_browser_default", popup, &mut state);
}

#[test]
fn snapshot_bg_color() {
    let popup = FileBrowserPopup::new()
        .bg_color(Color::Blue);
    let mut state = make_state();
    render_stateful("file_browser_bg_color", popup, &mut state);
}

#[test]
fn snapshot_with_height() {
    let popup = FileBrowserPopup::new().height(PopupSize::Fixed(15));
    let mut state = make_state();
    render_stateful("file_browser_with_height", popup, &mut state);
}

#[test]
fn snapshot_with_position() {
    let popup = FileBrowserPopup::new().position(5, 5);
    let mut state = make_state();
    render_stateful("file_browser_with_position", popup, &mut state);
}

// ── badges integration ──

#[test]
fn snapshot_with_badges() {
    let badges = BadgeStack::new()
        .push(Badge::new(" main", Color::Green).anchor(BadgeAnchor::TopLeft));
    let popup = FileBrowserPopup::new()
        .height(PopupSize::Fixed(10))
        .badges(badges);
    let mut state = make_state();
    render_stateful("file_browser_with_badges", popup, &mut state);
}