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};

fn render(name: &str, spin: Spin, state: &SpinState) {
    let backend = TestBackend::new(20, 1);
    let mut terminal = Terminal::new(backend).unwrap();
    terminal
        .draw(|f| f.render_stateful_widget(spin, f.area(), &mut state.clone()))
        .unwrap();
    assert_snapshot!(name, terminal.backend());
}

// ── state: tick ──

#[test]
fn tick_advances_frame() {
    let mut s = SpinState::default();
    s.tick(4);
    assert_eq!(s.frame, 1);
    s.tick(4);
    assert_eq!(s.frame, 2);
}

#[test]
fn tick_wraps_around() {
    let mut s = SpinState { frame: 3, ..SpinState::default() };
    s.tick(4);
    assert_eq!(s.frame, 0);
}

#[test]
fn tick_does_nothing_when_finished() {
    let mut s = SpinState { finished: true, frame: 2, ..SpinState::default() };
    s.tick(4);
    assert_eq!(s.frame, 2);
}

#[test]
fn tick_with_zero_frames_does_nothing() {
    let mut s = SpinState::default();
    s.tick(0);
    assert_eq!(s.frame, 0);
}

// ── state: scroll delegation ──

#[test]
fn output_next_delegates_to_scroll_list() {
    let mut s = SpinState::default();
    s.scroll_list.select(Some(0));
    s.output_next(3);
    assert_eq!(s.scroll_list.list_state.selected(), Some(1));
}

#[test]
fn output_previous_delegates_to_scroll_list() {
    let mut s = SpinState::default();
    s.scroll_list.select(Some(2));
    s.output_previous();
    assert_eq!(s.scroll_list.list_state.selected(), Some(1));
}

#[test]
fn output_last_delegates_to_scroll_list() {
    let mut s = SpinState::default();
    s.output_last(5);
    assert_eq!(s.scroll_list.list_state.selected(), Some(4));
}

// ── snapshots ──

#[test]
fn snapshot_default() {
    let state = SpinState { frame: 0, ..SpinState::default() };
    render("spin_default", Spin::new(), &state);
}

#[test]
fn snapshot_finished_ok() {
    let state = SpinState { finished: true, exit_code: Some(0), ..SpinState::default() };
    render("spin_finished_ok", Spin::new(), &state);
}

#[test]
fn snapshot_finished_fail() {
    let state = SpinState { finished: true, exit_code: Some(1), ..SpinState::default() };
    render("spin_finished_fail", Spin::new(), &state);
}

#[test]
fn snapshot_custom_frames() {
    let frames: &[&str] = &["A", "B", "C"];
    let state = SpinState { frame: 1, ..SpinState::default() };
    let spin = Spin::new().frames(frames);
    render("spin_custom_frames", spin, &state);
}