mod helpers;
use helpers::TestEnv;
use rustodo::cli::AddArgs;
use rustodo::commands::task;
use rustodo::models::Priority;
fn add_simple(env: &TestEnv, text: &str) -> usize {
task::add::execute(
env.storage(),
AddArgs {
text: text.to_string(),
priority: Priority::Medium,
tag: vec![],
project: None,
due: None,
recurrence: None,
depends_on: vec![],
},
)
.unwrap();
env.task_count()
}
#[test]
fn test_remove_single_task() {
let env = TestEnv::new();
add_simple(&env, "Task to remove");
let result = task::remove::execute(env.storage(), 1, true);
assert!(result.is_ok());
assert_eq!(env.task_count(), 0);
}
#[test]
fn test_remove_reduces_task_count() {
let env = TestEnv::new();
add_simple(&env, "Task A");
add_simple(&env, "Task B");
add_simple(&env, "Task C");
task::remove::execute(env.storage(), 2, true).unwrap();
assert_eq!(env.task_count(), 2);
}
#[test]
fn test_remove_first_task() {
let env = TestEnv::new();
add_simple(&env, "First");
add_simple(&env, "Second");
add_simple(&env, "Third");
task::remove::execute(env.storage(), 1, true).unwrap();
let tasks = env.load_tasks();
assert_eq!(tasks.len(), 2);
assert_eq!(tasks[0].text, "Second");
assert_eq!(tasks[1].text, "Third");
}
#[test]
fn test_remove_middle_task() {
let env = TestEnv::new();
add_simple(&env, "First");
add_simple(&env, "Middle");
add_simple(&env, "Last");
task::remove::execute(env.storage(), 2, true).unwrap();
let tasks = env.load_tasks();
assert_eq!(tasks.len(), 2);
assert_eq!(tasks[0].text, "First");
assert_eq!(tasks[1].text, "Last");
}
#[test]
fn test_remove_last_task() {
let env = TestEnv::new();
add_simple(&env, "First");
add_simple(&env, "Last");
task::remove::execute(env.storage(), 2, true).unwrap();
let tasks = env.load_tasks();
assert_eq!(tasks.len(), 1);
assert_eq!(tasks[0].text, "First");
}
#[test]
fn test_remove_correct_task_by_text() {
let env = TestEnv::new();
add_simple(&env, "Keep me");
add_simple(&env, "Remove me");
add_simple(&env, "Keep me too");
task::remove::execute(env.storage(), 2, true).unwrap();
let tasks = env.load_tasks();
assert_eq!(tasks.len(), 2);
assert!(tasks.iter().all(|t| t.text != "Remove me"));
assert!(tasks.iter().any(|t| t.text == "Keep me"));
assert!(tasks.iter().any(|t| t.text == "Keep me too"));
}
#[test]
fn test_remove_with_yes_flag_skips_confirmation() {
let env = TestEnv::new();
add_simple(&env, "Task");
let result = task::remove::execute(env.storage(), 1, true);
assert!(result.is_ok());
assert_eq!(env.task_count(), 0);
}
#[test]
fn test_remove_id_zero_fails() {
let env = TestEnv::new();
add_simple(&env, "Task");
let result = task::remove::execute(env.storage(), 0, true);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("invalid"));
}
#[test]
fn test_remove_id_out_of_range_fails() {
let env = TestEnv::new();
add_simple(&env, "Task");
let result = task::remove::execute(env.storage(), 99, true);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("invalid"));
}
#[test]
fn test_remove_from_empty_storage_fails() {
let env = TestEnv::new();
let result = task::remove::execute(env.storage(), 1, true);
assert!(result.is_err());
}
#[test]
fn test_remove_all_tasks_one_by_one() {
let env = TestEnv::new();
add_simple(&env, "A");
add_simple(&env, "B");
add_simple(&env, "C");
task::remove::execute(env.storage(), 1, true).unwrap();
task::remove::execute(env.storage(), 1, true).unwrap();
task::remove::execute(env.storage(), 1, true).unwrap();
assert_eq!(env.task_count(), 0);
}
#[test]
fn test_remove_preserves_task_metadata() {
let env = TestEnv::new();
add_simple(&env, "Keep this");
task::add::execute(
env.storage(),
AddArgs {
text: "Remove this".to_string(),
priority: Priority::High,
tag: vec!["work".to_string()],
project: None,
due: None,
recurrence: None,
depends_on: vec![],
},
)
.unwrap();
task::remove::execute(env.storage(), 2, true).unwrap();
let tasks = env.load_tasks();
assert_eq!(tasks.len(), 1);
assert_eq!(tasks[0].text, "Keep this");
assert_eq!(tasks[0].priority, Priority::Medium);
}