use tododo::domain::priority::Priority;
use tododo::domain::validation::validate_title;
use tododo::domain::SortMode;
use tododo::domain::TodoStatus;
#[test]
fn test_sort_mode_label() {
assert_eq!(SortMode::Priority.label(), "priority");
assert_eq!(SortMode::CreatedAt.label(), "created");
}
#[test]
fn test_sort_mode_toggle() {
let mut mode = SortMode::Priority;
mode.toggle();
assert_eq!(mode, SortMode::CreatedAt);
mode.toggle();
assert_eq!(mode, SortMode::Priority);
}
#[test]
fn test_sort_mode_default() {
let mode = SortMode::default();
assert_eq!(mode, SortMode::Priority);
}
#[test]
fn test_priority_order_high_to_low() {
let priorities = vec![1, 2, 3, 4, 5];
let expected_chars = vec!["S", "A", "B", "C", ""];
for (p, expected) in priorities.iter().zip(expected_chars.iter()) {
assert_eq!(
Priority::new(*p).to_char(),
*expected,
"priority {} should be {}",
p,
expected
);
}
}
#[test]
fn test_priority_cycling_order() {
let priorities = vec![1, 2, 3, 4, 5];
let expected_next_chars = vec!["", "S", "A", "B", "C"];
for (i, ¤t) in priorities.iter().enumerate() {
let prio = Priority::new(current);
let next_prio = prio.next();
assert_eq!(
next_prio.to_char(),
expected_next_chars[i],
"Priority {} ({}) should cycle to {} but got {}",
current,
prio.to_char(),
expected_next_chars[i],
next_prio.to_char()
);
}
}
#[test]
fn test_validate_title_accepts_trimmed_input() {
let title = validate_title(" ship feature ").expect("title should be valid");
assert_eq!(title, "ship feature");
}
#[test]
fn test_validate_title_rejects_empty() {
let err = validate_title(" ").expect_err("empty title should be invalid");
assert!(err.to_string().contains("Title cannot be empty"));
}
#[test]
fn test_todo_status_string_roundtrip() {
assert_eq!(TodoStatus::Pending.as_str(), TodoStatus::PENDING);
assert_eq!(TodoStatus::Completed.as_str(), TodoStatus::COMPLETED);
assert_eq!(
TodoStatus::from_status_str(TodoStatus::PENDING),
Some(TodoStatus::Pending)
);
assert_eq!(
TodoStatus::from_status_str(TodoStatus::COMPLETED),
Some(TodoStatus::Completed)
);
assert_eq!(TodoStatus::from_status_str("unknown"), None);
}
#[test]
fn test_priority_from_char_valid() {
assert_eq!(Priority::from_char("S").unwrap(), Priority::S);
assert_eq!(Priority::from_char("A").unwrap(), Priority::A);
assert_eq!(Priority::from_char("B").unwrap(), Priority::B);
assert_eq!(Priority::from_char("C").unwrap(), Priority::C);
assert_eq!(Priority::from_char("").unwrap(), Priority::NONE);
assert_eq!(Priority::from_char("s").unwrap(), Priority::S);
assert_eq!(Priority::from_char("a").unwrap(), Priority::A);
}
#[test]
fn test_priority_from_char_invalid() {
let err = Priority::from_char("X").expect_err("X should be invalid priority");
assert!(err.to_string().contains("Invalid priority"));
let err2 = Priority::from_char("Z").expect_err("Z should be invalid priority");
assert!(err2.to_string().contains("Invalid priority"));
}
#[test]
fn test_validate_title_rejects_too_long() {
let long_title = "a".repeat(101);
let err = validate_title(&long_title).expect_err("title over 100 chars should be invalid");
assert!(err.to_string().contains("exceeds 100 characters"));
}