use callisto_cli::cli::{GlobalArgs, OutputFormat, StatusArgs};
use callisto_cli::commands;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_e2e_workspace_init_add_and_status() {
let tmp = TempDir::new().unwrap();
let root = tmp.path();
let _res = std::process::Command::new("git").arg("init").current_dir(root).output();
let cargo_toml = r#"[workspace]
members = ["crates/*"]
resolver = "2"
"#;
fs::write(root.join("Cargo.toml"), cargo_toml).unwrap();
let crate_dir = root.join("crates/my-app");
fs::create_dir_all(&crate_dir).unwrap();
let crate_toml = r#"[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
"#;
fs::write(crate_dir.join("Cargo.toml"), crate_toml).unwrap();
let global = GlobalArgs {
format: OutputFormat::Json,
cwd: root.to_path_buf(),
dry_run: false,
};
let init_res = commands::init::handle(callisto_cli::cli::InitArgs { yes: true }, &global);
assert!(init_res.is_ok());
assert!(root.join("callisto.toml").exists());
let add_res = commands::add::handle(
callisto_cli::cli::AddArgs {
packages: vec!["my-app:minor".to_string()],
summary: Some("Added new feature".to_string()),
},
&global,
);
assert!(add_res.is_ok());
let changeset_files: Vec<_> = fs::read_dir(root.join(".changeset"))
.unwrap()
.flatten()
.filter(|e| {
e.path().extension().and_then(|ext| ext.to_str()) == Some("md")
&& e.path().file_name().and_then(|n| n.to_str()) != Some("README.md")
})
.collect();
assert_eq!(changeset_files.len(), 1);
let status_res = commands::status::handle(
StatusArgs {
strict: false,
strict_graph: false,
check: false,
},
&global,
);
assert!(status_res.is_ok());
}
#[test]
fn test_status_matches_ecosystem_qualified_changeset_entry() {
use std::process::ExitCode;
let tmp = TempDir::new().unwrap();
let root = tmp.path();
drop(std::process::Command::new("git").arg("init").current_dir(root).output());
fs::write(
root.join("Cargo.toml"),
"[workspace]\nmembers = [\"crates/*\"]\nresolver = \"2\"\n",
)
.unwrap();
let crate_dir = root.join("crates/my-app");
fs::create_dir_all(&crate_dir).unwrap();
fs::write(
crate_dir.join("Cargo.toml"),
"[package]\nname = \"my-app\"\nversion = \"0.1.0\"\nedition = \"2021\"\n",
)
.unwrap();
let global = GlobalArgs {
format: OutputFormat::Json,
cwd: root.to_path_buf(),
dry_run: false,
};
commands::init::handle(callisto_cli::cli::InitArgs { yes: true }, &global).unwrap();
let changeset_dir = root.join(".changeset");
fs::write(
changeset_dir.join("fix-ecosystem-name.md"),
"---\n\"cargo/my-app\": patch\n---\n\nFix using ecosystem-qualified name.\n",
)
.unwrap();
let code = commands::status::handle(
StatusArgs {
strict: false,
strict_graph: false,
check: true,
},
&global,
)
.unwrap();
assert_eq!(
format!("{code:?}"),
format!("{:?}", ExitCode::FAILURE),
"status --check must detect a pending changeset whose entry uses an \
ecosystem-qualified name (cargo/my-app) for a package registered as my-app"
);
}
#[test]
fn test_status_check_exit_codes() {
use std::process::ExitCode;
let tmp = TempDir::new().unwrap();
let root = tmp.path();
drop(std::process::Command::new("git").arg("init").current_dir(root).output());
fs::write(
root.join("Cargo.toml"),
"[workspace]\nmembers = [\"crates/*\"]\nresolver = \"2\"\n",
)
.unwrap();
let crate_dir = root.join("crates/my-app");
fs::create_dir_all(&crate_dir).unwrap();
fs::write(
crate_dir.join("Cargo.toml"),
"[package]\nname = \"my-app\"\nversion = \"0.1.0\"\nedition = \"2021\"\n",
)
.unwrap();
let global = GlobalArgs {
format: OutputFormat::Json,
cwd: root.to_path_buf(),
dry_run: false,
};
commands::init::handle(callisto_cli::cli::InitArgs { yes: true }, &global).unwrap();
let check_args = StatusArgs {
strict: false,
strict_graph: false,
check: true,
};
let clean_code = commands::status::handle(check_args.clone(), &global).unwrap();
let expected_clean = ExitCode::from(2u8);
assert_ne!(
format!("{clean_code:?}"),
format!("{:?}", ExitCode::SUCCESS),
"clean workspace with --check must not return exit code 0"
);
assert_eq!(
format!("{clean_code:?}"),
format!("{expected_clean:?}"),
"clean workspace with --check must return exit code 2"
);
commands::add::handle(
callisto_cli::cli::AddArgs {
packages: vec!["my-app:patch".to_string()],
summary: Some("test fix".to_string()),
},
&global,
)
.unwrap();
let pending_code = commands::status::handle(check_args.clone(), &global).unwrap();
assert_eq!(
format!("{pending_code:?}"),
format!("{:?}", ExitCode::FAILURE),
"workspace with pending changeset and --check must return exit code 1 (FAILURE)"
);
}
#[test]
fn test_status_default_exit_code_clean_workspace() {
let tmp = TempDir::new().unwrap();
let root = tmp.path();
drop(std::process::Command::new("git").arg("init").current_dir(root).output());
fs::write(
root.join("Cargo.toml"),
"[workspace]\nmembers = [\"crates/*\"]\nresolver = \"2\"\n",
)
.unwrap();
let crate_dir = root.join("crates/lib-a");
fs::create_dir_all(&crate_dir).unwrap();
fs::write(
crate_dir.join("Cargo.toml"),
"[package]\nname = \"lib-a\"\nversion = \"1.0.0\"\nedition = \"2021\"\n",
)
.unwrap();
let global = GlobalArgs {
format: OutputFormat::Json,
cwd: root.to_path_buf(),
dry_run: false,
};
commands::init::handle(callisto_cli::cli::InitArgs { yes: true }, &global).unwrap();
let code = commands::status::handle(
StatusArgs {
strict: false,
strict_graph: false,
check: false,
},
&global,
)
.unwrap();
assert_eq!(
format!("{code:?}"),
format!("{:?}", std::process::ExitCode::SUCCESS),
"status without --check on a clean workspace must return exit code 0"
);
}