cli_init.rs

  1use assert_cmd::Command;
  2use predicates::prelude::*;
  3use tempfile::TempDir;
  4
  5fn td(home: &TempDir) -> Command {
  6    let mut cmd = Command::cargo_bin("td").unwrap();
  7    cmd.env("HOME", home.path());
  8    cmd
  9}
 10
 11#[test]
 12fn init_creates_project_snapshot_and_binding() {
 13    let tmp = TempDir::new().unwrap();
 14
 15    td(&tmp)
 16        .args(["init", "demo"])
 17        .current_dir(&tmp)
 18        .assert()
 19        .success()
 20        .stderr(predicate::str::contains("initialized project 'demo'"));
 21
 22    let root = tmp.path().join(".local/share/td");
 23    assert!(root.join("projects/demo/base.loro").is_file());
 24    assert!(root.join("projects/demo/changes").is_dir());
 25
 26    let bindings_path = root.join("bindings.json");
 27    assert!(bindings_path.is_file());
 28    let bindings: serde_json::Value =
 29        serde_json::from_str(&std::fs::read_to_string(bindings_path).unwrap()).unwrap();
 30    let canonical_cwd = std::fs::canonicalize(tmp.path()).unwrap();
 31    assert_eq!(
 32        bindings["bindings"][canonical_cwd.to_string_lossy().as_ref()]
 33            .as_str()
 34            .unwrap(),
 35        "demo"
 36    );
 37}
 38
 39#[test]
 40fn init_fails_when_project_already_exists() {
 41    let tmp = TempDir::new().unwrap();
 42
 43    td(&tmp)
 44        .args(["init", "demo"])
 45        .current_dir(&tmp)
 46        .assert()
 47        .success();
 48
 49    td(&tmp)
 50        .args(["init", "demo"])
 51        .current_dir(&tmp)
 52        .assert()
 53        .failure()
 54        .stderr(predicate::str::contains("already exists"));
 55}
 56
 57#[test]
 58fn use_binds_another_directory_to_existing_project() {
 59    let tmp = TempDir::new().unwrap();
 60    let other = tmp.path().join("other");
 61    std::fs::create_dir_all(&other).unwrap();
 62
 63    td(&tmp)
 64        .args(["init", "demo"])
 65        .current_dir(&tmp)
 66        .assert()
 67        .success();
 68
 69    td(&tmp)
 70        .args(["create", "Created from original binding"])
 71        .current_dir(&tmp)
 72        .assert()
 73        .success();
 74
 75    td(&tmp)
 76        .args(["use", "demo"])
 77        .current_dir(&other)
 78        .assert()
 79        .success();
 80
 81    td(&tmp)
 82        .args(["list"])
 83        .current_dir(&other)
 84        .assert()
 85        .success()
 86        .stdout(predicate::str::contains("Created from original binding"));
 87}
 88
 89#[test]
 90fn init_json_outputs_success() {
 91    let tmp = TempDir::new().unwrap();
 92
 93    td(&tmp)
 94        .args(["--json", "init", "demo"])
 95        .current_dir(&tmp)
 96        .assert()
 97        .success()
 98        .stdout(predicate::str::contains(r#""success":true"#))
 99        .stdout(predicate::str::contains(r#""project":"demo""#));
100}
101
102#[test]
103fn projects_lists_all_initialized_projects() {
104    let tmp = TempDir::new().unwrap();
105    let api_dir = tmp.path().join("api");
106    let web_dir = tmp.path().join("web");
107    std::fs::create_dir_all(&api_dir).unwrap();
108    std::fs::create_dir_all(&web_dir).unwrap();
109
110    td(&tmp)
111        .args(["init", "api"])
112        .current_dir(&api_dir)
113        .assert()
114        .success();
115
116    td(&tmp)
117        .args(["init", "web"])
118        .current_dir(&web_dir)
119        .assert()
120        .success();
121
122    td(&tmp)
123        .args(["projects"])
124        .current_dir(&api_dir)
125        .assert()
126        .success()
127        .stdout(predicate::str::contains("api"))
128        .stdout(predicate::str::contains("web"));
129}