use super::*;
#[test]
fn frames_is_ten_braille_spinner_glyphs() {
assert_eq!(FRAMES.len(), 10);
assert_eq!(FRAMES[0], "⠋");
assert_eq!(FRAMES[9], "⠏");
}
#[test]
fn bar_width_is_twenty_two_cells() {
assert_eq!(BAR_WIDTH, 22);
let full = render_progress_bar(1.0, BAR_WIDTH, false);
assert_eq!(full.chars().count(), 22);
assert_eq!(full.chars().filter(|&c| c == '█').count(), 22);
}
#[test]
fn every_phase_ticker_shares_one_frames_and_bar_width_owner() {
fn sweep_cells(line: &str) -> usize {
line.chars().filter(|&c| c == '█' || c == '░').count()
}
for frame in 0..FRAMES.len() {
let scan = render_ticker_line(0, 0, 0, 0.0, frame, false);
let verify = render_verification_ticker_line(1, 0.0, frame, false);
let report = render_reporting_ticker_line(1, 0.0, frame, false);
let want = FRAMES[frame % FRAMES.len()];
assert_eq!(scan.chars().next().unwrap().to_string(), want);
assert_eq!(verify.chars().next().unwrap().to_string(), want);
assert_eq!(report.chars().next().unwrap().to_string(), want);
assert_eq!(sweep_cells(&scan), BAR_WIDTH);
assert_eq!(sweep_cells(&verify), BAR_WIDTH);
assert_eq!(sweep_cells(&report), BAR_WIDTH);
}
}
#[test]
fn ticker_clamps_transient_scanned_over_total_overshoot() {
let line = render_ticker_line(1001, 1000, 3, 2.0, 0, false);
assert!(
line.contains("100%"),
"overshoot must clamp to 100%, not >100%; line={line}"
);
assert!(
!line.contains("101%") && !line.contains("100.1"),
"no percentage above 100 may render; line={line}"
);
assert!(
line.contains("1000/1000"),
"the displayed ratio must clamp to total, not show 1001/1000; line={line}"
);
assert!(
line.contains("finalizing"),
"scanned >= total reads as finalizing; line={line}"
);
assert_eq!(
line.chars().filter(|&c| c == '█').count(),
BAR_WIDTH,
"a clamped-full bar is entirely filled; line={line}"
);
assert_eq!(
line.chars().filter(|&c| c == '░').count(),
0,
"a full bar carries no dim rail; line={line}"
);
}
#[test]
fn ticker_at_exact_completion_shows_100_percent_no_eta() {
let line = render_ticker_line(500, 500, 0, 1.0, 0, false);
assert!(line.contains("100%"), "line={line}");
assert!(line.contains("500/500"), "line={line}");
assert!(line.contains("finalizing"), "line={line}");
assert!(!line.contains("eta"), "no eta once complete; line={line}");
}
#[test]
fn count_nouns_pluralize_on_the_boundary() {
assert_eq!(secret_noun(0), "secrets");
assert_eq!(secret_noun(1), "secret");
assert_eq!(secret_noun(2), "secrets");
assert_eq!(finding_noun(0), "findings");
assert_eq!(finding_noun(1), "finding");
assert_eq!(finding_noun(2), "findings");
}
#[test]
fn phase_tickers_use_singular_noun_for_one_item() {
let verify_one = render_verification_ticker_line(1, 0.0, 0, false);
assert!(
verify_one.contains(" 1 secret ") && !verify_one.contains("secrets"),
"single verify item is singular; line={verify_one}"
);
let report_two = render_reporting_ticker_line(2, 0.0, 0, false);
assert!(
report_two.contains(" 2 findings "),
"two report items are plural; line={report_two}"
);
}