use super::*;
#[test]
fn a_mixed_project_is_not_painted_as_one_state() {
let out = paint_status_cell("running(1), exited(1)");
let (running, exited) = out.split_once(", ").expect("both segments survive");
assert_ne!(
running.replace("running(1)", ""),
exited.replace("exited(1)", ""),
"each state must carry its own colour: {out:?}"
);
}
#[test]
fn a_clean_exit_is_not_red() {
let red = Style::new().fg_color(Some(AnsiColor::Red.into()));
let clean = paint_status_cell("Exited (0)");
assert!(
!clean.contains(&red.render().to_string()),
"a zero exit must not be red: {clean:?}"
);
let failed = paint_status_cell("Exited (7)");
assert!(
failed.contains(&red.render().to_string()),
"a non-zero exit must stay red: {failed:?}"
);
}
#[test]
fn only_a_bare_zero_counts_as_clean() {
assert!(is_clean_exit("exited (0)"));
assert!(is_clean_exit("exited(0)"));
assert!(!is_clean_exit("exited (10)"));
assert!(!is_clean_exit("exited (07)"));
}
#[test]
fn trailing_padding_survives_colourising() {
let out = paint_status_cell("running ");
assert!(out.ends_with(" "), "{out:?}");
}
#[test]
fn systemd_states_are_coloured() {
for word in ["active", "inactive", "failed", "not-found", "enabled"] {
assert!(status_style(word).is_some(), "{word} should carry a colour");
}
}
#[test]
fn paint_gates_on_enabled() {
let plain = paint(bold(), "hi", false);
assert_eq!(plain, "hi");
let coloured = paint(bold(), "hi", true);
assert!(coloured.contains("hi"));
assert!(coloured.len() > "hi".len(), "enabled paint adds ANSI codes");
assert!(coloured.starts_with('\u{1b}'), "starts with an ESC");
}
#[test]
fn colour_choice_resolution() {
temp_env::with_var_unset("NO_COLOR", || {
assert!(!colored_with(ColorChoice::Never, true));
assert!(colored_with(ColorChoice::Always, false));
assert!(colored_with(ColorChoice::Auto, true));
assert!(!colored_with(ColorChoice::Auto, false));
});
temp_env::with_var("NO_COLOR", Some("1"), || {
assert!(!colored_with(ColorChoice::Auto, true));
assert!(colored_with(ColorChoice::Always, true));
});
}
#[test]
fn status_style_is_semantic() {
assert_ne!(status_style("running"), status_style("exited (1)"));
assert_ne!(status_style("unhealthy"), status_style("healthy"));
assert!(status_style("Up 2 minutes").is_some());
assert!(status_style("paused").is_some());
assert!(status_style("created").is_some());
assert!(status_style("weird-state").is_none());
}
#[test]
fn progress_toggle_is_observable() {
let prev = progress_enabled();
set_progress(false);
assert!(!progress_enabled());
set_progress(true);
assert!(progress_enabled());
set_progress(prev);
}
#[test]
fn status_cell_pads_and_keeps_status() {
let cell = status_cell("ok", 6);
assert!(cell.contains("ok"));
assert!(cell.len() >= 6);
}
#[test]
fn every_spelling_of_one_container_gets_one_colour() {
set_project("proj");
let from_ps = identity_style("proj-web-1");
let from_logs = identity_style("web-1");
assert_eq!(
from_ps.render().to_string(),
from_logs.render().to_string(),
"the same container must be the same colour in ps and logs"
);
}
#[test]
fn an_unprefixed_label_is_keyed_on_itself() {
set_project("proj");
assert_eq!(
identity_style("web").render().to_string(),
service_style("web").render().to_string()
);
}
#[test]
fn set_services_makes_registered_names_distinct() {
set_services(&[
"colourreg-alpha".to_string(),
"colourreg-beta".to_string(),
"colourreg-gamma".to_string(),
]);
let a = service_style("colourreg-alpha").render().to_string();
let b = service_style("colourreg-beta").render().to_string();
let g = service_style("colourreg-gamma").render().to_string();
assert_ne!(a, b, "registered names must not share a colour");
assert_ne!(b, g, "registered names must not share a colour");
assert_ne!(a, g, "registered names must not share a colour");
}
#[test]
fn every_wide_palette_slot_indexes_the_narrow_palette_safely() {
for slot in 0..palette::WIDE_PALETTE.len() {
let _ = slot_to_style(slot, false);
let _ = slot_to_style(slot, true);
}
}