1use assert_cmd::Command;
2use predicates::prelude::*;
3use tempfile::TempDir;
4
5fn td() -> Command {
6 Command::cargo_bin("td").unwrap()
7}
8
9#[test]
10fn init_creates_td_directory_and_database() {
11 let tmp = TempDir::new().unwrap();
12
13 td().arg("init")
14 .current_dir(&tmp)
15 .assert()
16 .success()
17 .stderr(predicate::str::contains("initialized .td/"));
18
19 assert!(tmp.path().join(".td").is_dir());
20 assert!(tmp.path().join(".td/tasks.db").is_file());
21}
22
23#[test]
24fn init_creates_schema_with_expected_tables() {
25 let tmp = TempDir::new().unwrap();
26
27 td().arg("init").current_dir(&tmp).assert().success();
28
29 let conn = rusqlite::Connection::open(tmp.path().join(".td/tasks.db")).unwrap();
30
31 // Verify all three tables exist by querying sqlite_master.
32 let tables: Vec<String> = conn
33 .prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
34 .unwrap()
35 .query_map([], |row| row.get(0))
36 .unwrap()
37 .map(|r| r.unwrap())
38 .collect();
39
40 assert!(tables.contains(&"tasks".to_string()));
41 assert!(tables.contains(&"labels".to_string()));
42 assert!(tables.contains(&"blockers".to_string()));
43}
44
45#[test]
46fn init_fails_when_already_initialized() {
47 let tmp = TempDir::new().unwrap();
48
49 td().arg("init").current_dir(&tmp).assert().success();
50
51 td().arg("init")
52 .current_dir(&tmp)
53 .assert()
54 .failure()
55 .stderr(predicate::str::contains("already initialized"));
56}
57
58#[test]
59fn init_stealth_adds_gitignore_entry() {
60 let tmp = TempDir::new().unwrap();
61
62 td().args(["init", "--stealth"])
63 .current_dir(&tmp)
64 .assert()
65 .success();
66
67 let gitignore = std::fs::read_to_string(tmp.path().join(".gitignore")).unwrap();
68 assert!(gitignore.contains(".td/"));
69}
70
71#[test]
72fn init_json_outputs_success() {
73 let tmp = TempDir::new().unwrap();
74
75 td().args(["--json", "init"])
76 .current_dir(&tmp)
77 .assert()
78 .success()
79 .stdout(predicate::str::contains(r#"{"success":true}"#));
80}