use std::fs;
use std::process::Command;
use tempfile::TempDir;
#[test]
fn test_status_flag_prints_counts() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn foo() {}\nfn bar() { foo(); }").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
graph.index_references(&path_str, &source).unwrap();
}
let output = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.output()
.expect("Failed to execute magellan status");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success(), "Process should exit successfully");
assert!(
stdout.contains("files: 1"),
"Expected 'files: 1' in output, got: {}",
stdout
);
assert!(
stdout.contains("symbols: 2"),
"Expected 'symbols: 2' in output, got: {}",
stdout
);
assert!(
stdout.contains("references: 1"),
"Expected 'references: 1' in output, got: {}",
stdout
);
}
#[test]
fn test_status_json_output_structure() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn foo() {}\nfn bar() { foo(); }").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
graph.index_references(&path_str, &source).unwrap();
}
let output = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
output.status.success(),
"Process should exit successfully: {}",
stdout
);
let json: serde_json::Value =
serde_json::from_str(&stdout).expect("Output should be valid JSON");
assert_eq!(json["schema_version"], "1.0.0");
assert!(json["execution_id"].is_string());
assert!(json["data"].is_object());
let data = &json["data"];
assert_eq!(data["files"], 1);
assert_eq!(data["symbols"], 2);
assert!(data["references"].is_number());
assert!(data["calls"].is_number());
assert!(data["code_chunks"].is_number());
}
#[test]
fn test_status_deterministic_ordering() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn foo() {}\nfn bar() { foo(); }").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
graph.index_references(&path_str, &source).unwrap();
}
let output1 = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let output2 = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let stdout1 = String::from_utf8_lossy(&output1.stdout);
let stdout2 = String::from_utf8_lossy(&output2.stdout);
assert!(output1.status.success());
assert!(output2.status.success());
let json1: serde_json::Value = serde_json::from_str(&stdout1).unwrap();
let json2: serde_json::Value = serde_json::from_str(&stdout2).unwrap();
assert_ne!(
json1["execution_id"], json2["execution_id"],
"execution_id should be unique per run"
);
assert_eq!(
json1["data"], json2["data"],
"data should be identical across runs (deterministic)"
);
assert_eq!(json1["schema_version"], json2["schema_version"]);
}
#[test]
fn test_status_schema_version_present() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn test() {}").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
}
let output = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("\"schema_version\""),
"Missing schema_version field"
);
assert!(
stdout.contains("\"1.0.0\""),
"Missing or incorrect schema version value"
);
}
#[test]
fn test_execution_id_unique() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn test() {}").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
}
let output1 = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let output2 = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.arg("--output")
.arg("json")
.output()
.expect("Failed to execute magellan status");
let stdout1 = String::from_utf8_lossy(&output1.stdout);
let stdout2 = String::from_utf8_lossy(&output2.stdout);
let json1: serde_json::Value = serde_json::from_str(&stdout1).unwrap();
let json2: serde_json::Value = serde_json::from_str(&stdout2).unwrap();
let id1 = json1["execution_id"].as_str().unwrap();
let id2 = json2["execution_id"].as_str().unwrap();
assert_ne!(id1, id2, "execution_id should be unique per run");
assert!(!id1.is_empty(), "execution_id should not be empty");
assert!(!id2.is_empty(), "execution_id should not be empty");
}
#[test]
fn test_status_human_mode_unchanged() {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path().to_path_buf();
let db_path = temp_dir.path().join("magellan.db");
let file_path = root_path.join("test.rs");
let bin_path = std::env::var("CARGO_BIN_EXE_magellan").unwrap_or_else(|_| {
let mut path = std::env::current_exe().unwrap();
path.pop();
path.pop();
path.push("magellan");
path.to_str().unwrap().to_string()
});
fs::write(&file_path, b"fn foo() {}\nfn bar() { foo(); }").unwrap();
{
let mut graph = magellan::CodeGraph::open(&db_path).unwrap();
let source = fs::read(&file_path).unwrap();
let path_str = file_path.to_string_lossy().to_string();
graph.index_file(&path_str, &source).unwrap();
graph.index_references(&path_str, &source).unwrap();
}
let output = Command::new(&bin_path)
.arg("status")
.arg("--db")
.arg(&db_path)
.output()
.expect("Failed to execute magellan status");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(
stdout.contains("files: 1"),
"Should show files count in human format"
);
assert!(
stdout.contains("symbols: 2"),
"Should show symbols count in human format"
);
assert!(
stdout.contains("calls:"),
"Should show calls count in human format"
);
assert!(
!stdout.contains("schema_version"),
"Should not have JSON fields in human mode"
);
assert!(
!stdout.contains("execution_id"),
"Should not have JSON fields in human mode"
);
}