use super::*;
#[test]
fn test_new() {
let state = SpinnerState::new();
assert!(state.is_spinning());
assert_eq!(state.style(), &SpinnerStyle::Dots);
assert_eq!(state.frame_index(), 0);
assert!(state.label().is_none());
}
#[test]
fn test_default() {
let state = SpinnerState::default();
assert!(state.is_spinning());
assert_eq!(state.style(), &SpinnerStyle::Dots);
}
#[test]
fn test_with_style() {
let state = SpinnerState::with_style(SpinnerStyle::Line);
assert_eq!(state.style(), &SpinnerStyle::Line);
assert!(state.is_spinning());
}
#[test]
fn test_with_label() {
let state = SpinnerState::with_label("Loading...");
assert_eq!(state.label(), Some("Loading..."));
assert!(state.is_spinning());
}
#[test]
fn test_current_frame() {
let state = SpinnerState::new();
assert_eq!(state.current_frame(), '⠋');
}
#[test]
fn test_tick_advances_frame() {
let mut state = SpinnerState::new();
assert_eq!(state.frame_index(), 0);
assert_eq!(state.current_frame(), '⠋');
Spinner::update(&mut state, SpinnerMessage::Tick);
assert_eq!(state.frame_index(), 1);
assert_eq!(state.current_frame(), '⠙');
Spinner::update(&mut state, SpinnerMessage::Tick);
assert_eq!(state.frame_index(), 2);
assert_eq!(state.current_frame(), '⠹');
}
#[test]
fn test_tick_wraps_around() {
let mut state = SpinnerState::with_style(SpinnerStyle::Line);
Spinner::update(&mut state, SpinnerMessage::Tick); Spinner::update(&mut state, SpinnerMessage::Tick); Spinner::update(&mut state, SpinnerMessage::Tick); assert_eq!(state.frame_index(), 3);
Spinner::update(&mut state, SpinnerMessage::Tick); assert_eq!(state.frame_index(), 0);
assert_eq!(state.current_frame(), '|');
}
#[test]
fn test_tick_when_stopped() {
let mut state = SpinnerState::new();
state.set_spinning(false);
let initial_frame = state.frame_index();
Spinner::update(&mut state, SpinnerMessage::Tick);
assert_eq!(state.frame_index(), initial_frame); }
#[test]
fn test_start_stop() {
let mut state = SpinnerState::new();
assert!(state.is_spinning());
Spinner::update(&mut state, SpinnerMessage::Stop);
assert!(!state.is_spinning());
Spinner::update(&mut state, SpinnerMessage::Start);
assert!(state.is_spinning());
}
#[test]
fn test_style_frames_dots() {
let style = SpinnerStyle::Dots;
assert_eq!(style.frame_count(), 10);
assert_eq!(
style.frames(),
&['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
);
}
#[test]
fn test_style_frames_line() {
let style = SpinnerStyle::Line;
assert_eq!(style.frame_count(), 4);
assert_eq!(style.frames(), &['|', '/', '-', '\\']);
}
#[test]
fn test_style_frames_circle() {
let style = SpinnerStyle::Circle;
assert_eq!(style.frame_count(), 4);
assert_eq!(style.frames(), &['◐', '◓', '◑', '◒']);
}
#[test]
fn test_style_frames_bounce() {
let style = SpinnerStyle::Bounce;
assert_eq!(style.frame_count(), 4);
assert_eq!(style.frames(), &['⠁', '⠂', '⠄', '⠂']);
}
#[test]
fn test_custom_style() {
let custom = SpinnerStyle::Custom(vec!['◯', '◔', '◑', '◕', '●']);
assert_eq!(custom.frame_count(), 5);
assert_eq!(custom.frames(), &['◯', '◔', '◑', '◕', '●']);
}
#[test]
fn test_custom_style_empty() {
let custom = SpinnerStyle::Custom(vec![]);
assert_eq!(custom.frame_count(), 1);
assert_eq!(custom.frames(), &[' ']);
}
#[test]
fn test_set_style_resets_frame() {
let mut state = SpinnerState::new();
Spinner::update(&mut state, SpinnerMessage::Tick);
Spinner::update(&mut state, SpinnerMessage::Tick);
assert_eq!(state.frame_index(), 2);
state.set_style(SpinnerStyle::Line);
assert_eq!(state.frame_index(), 0);
}
#[test]
fn test_init() {
let state = Spinner::init();
assert!(state.is_spinning());
assert_eq!(state.style(), &SpinnerStyle::Dots);
assert!(state.label().is_none());
}
#[test]
fn test_update_returns_none() {
let mut state = SpinnerState::new();
assert_eq!(Spinner::update(&mut state, SpinnerMessage::Tick), None);
assert_eq!(Spinner::update(&mut state, SpinnerMessage::Start), None);
assert_eq!(Spinner::update(&mut state, SpinnerMessage::Stop), None);
}
#[test]
fn test_view_spinning() {
let state = SpinnerState::new();
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 5);
terminal
.draw(|frame| {
Spinner::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_stopped() {
let mut state = SpinnerState::new();
state.set_spinning(false);
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 5);
terminal
.draw(|frame| {
Spinner::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_with_label() {
let state = SpinnerState::with_label("Loading");
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 5);
terminal
.draw(|frame| {
Spinner::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_style_default() {
let style = SpinnerStyle::default();
assert_eq!(style, SpinnerStyle::Dots);
}
#[test]
fn test_full_animation_cycle() {
let mut state = SpinnerState::with_style(SpinnerStyle::Line);
let mut frames_seen = Vec::new();
for _ in 0..8 {
frames_seen.push(state.current_frame());
Spinner::update(&mut state, SpinnerMessage::Tick);
}
assert_eq!(frames_seen, vec!['|', '/', '-', '\\', '|', '/', '-', '\\']);
}
#[test]
fn test_with_disabled() {
let state = SpinnerState::new().with_disabled(true);
assert!(state.is_disabled());
}
#[test]
fn test_with_disabled_false() {
let state = SpinnerState::new().with_disabled(false);
assert!(!state.is_disabled());
}
#[test]
fn test_disabled_default_is_false() {
let state = SpinnerState::new();
assert!(!state.is_disabled());
}
#[test]
fn test_set_disabled() {
let mut state = SpinnerState::new();
assert!(!state.is_disabled());
state.set_disabled(true);
assert!(state.is_disabled());
state.set_disabled(false);
assert!(!state.is_disabled());
}
#[test]
fn test_default_matches_init() {
let default_state = SpinnerState::default();
let init_state = Spinner::init();
assert_eq!(default_state.style(), init_state.style());
assert_eq!(default_state.frame_index(), init_state.frame_index());
assert_eq!(default_state.is_spinning(), init_state.is_spinning());
assert_eq!(default_state.label(), init_state.label());
}
#[test]
fn test_annotation_emitted() {
use crate::annotation::{WidgetType, with_annotations};
let state = SpinnerState::with_label("Loading");
let (mut terminal, theme) = crate::component::test_utils::setup_render(30, 3);
let registry = with_annotations(|| {
terminal
.draw(|frame| {
Spinner::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
});
assert_eq!(registry.len(), 1);
let regions = registry.find_by_type(&WidgetType::Spinner);
assert_eq!(regions.len(), 1);
assert_eq!(regions[0].annotation.label, Some("Loading".to_string()));
}