use std::fs;
use std::process::Command;
use tempfile::tempdir;
#[test]
fn test_cli_help() {
let output = Command::new("cargo")
.args(["run", "--", "--help"])
.output()
.expect("Failed to run skeletor help");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Skeletor"));
assert!(stdout.contains("apply"));
assert!(stdout.contains("snapshot"));
assert!(stdout.contains("info"));
}
#[test]
fn test_cli_apply_integration() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("test.yml");
let config_content = r#"
directories:
hello_world:
main.rs: |
fn main() {
println!("Hello, World!");
}
Cargo.toml: |
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
docs:
README.md: "Hello World Documentation"
"#;
fs::write(&config_file, config_content).unwrap();
let project_root = std::env::current_dir().unwrap();
let mut binary_path = project_root.join("target/debug/skeletor");
if !binary_path.exists() {
binary_path = project_root.join("target/debug/skeletor.exe"); }
if !binary_path.exists() {
binary_path = project_root.join("target/release/skeletor"); }
if !binary_path.exists() {
binary_path = project_root.join("target/release/skeletor.exe"); }
if !binary_path.exists() {
let build_output = Command::new("cargo")
.args(["build", "--bin", "skeletor"])
.current_dir(&project_root)
.output()
.expect("Failed to run cargo build");
if !build_output.status.success() {
panic!("Failed to build skeletor binary: {}",
String::from_utf8_lossy(&build_output.stderr));
}
binary_path = project_root.join("target/debug/skeletor");
if !binary_path.exists() {
binary_path = project_root.join("target/debug/skeletor.exe");
}
if !binary_path.exists() {
panic!("Could not find skeletor binary even after building. Tried:\n- target/debug/skeletor\n- target/debug/skeletor.exe\n- target/release/skeletor\n- target/release/skeletor.exe");
}
}
let output = Command::new(&binary_path)
.args(["apply", config_file.to_str().unwrap()])
.current_dir(&temp_dir)
.output()
.map_err(|e| format!("Failed to execute skeletor binary at {:?}: {}", binary_path, e))
.expect("Failed to run skeletor apply");
assert!(output.status.success(), "Apply command failed: {}",
String::from_utf8_lossy(&output.stderr));
assert!(temp_dir.path().join("hello_world/main.rs").exists());
assert!(temp_dir.path().join("hello_world/Cargo.toml").exists());
assert!(temp_dir.path().join("docs/README.md").exists());
let main_content = fs::read_to_string(temp_dir.path().join("hello_world/main.rs")).unwrap();
assert!(main_content.contains("println!(\"Hello, World!\");"));
}
#[test]
fn test_cli_apply_dry_run() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("test.yml");
let config_content = r#"
directories:
test_dir:
file.txt: "content"
"#;
fs::write(&config_file, config_content).unwrap();
let output = Command::new("cargo")
.args(["run", "--", "apply", "--dry-run", config_file.to_str().unwrap()])
.output()
.expect("Failed to run skeletor apply --dry-run");
assert!(output.status.success(), "Apply dry-run failed. stderr: {}",
String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Dry run"));
assert!(!temp_dir.path().join("test_dir").exists());
}
#[test]
fn test_cli_snapshot_integration() {
let temp_dir = tempdir().unwrap();
fs::create_dir_all(temp_dir.path().join("src")).unwrap();
fs::write(temp_dir.path().join("src/main.rs"), "fn main() {}").unwrap();
fs::write(temp_dir.path().join("README.md"), "# Test Project").unwrap();
let binary_path = std::env::current_dir().unwrap().join("target/debug/skeletor");
let output = Command::new(binary_path)
.args(["snapshot", "."]) .current_dir(&temp_dir) .output()
.expect("Failed to run skeletor snapshot");
assert!(output.status.success(), "Snapshot command failed: {}",
String::from_utf8_lossy(&output.stderr));
let snapshot_file = temp_dir.path().join(".skeletorrc");
assert!(snapshot_file.exists(), "Snapshot file should be created");
let snapshot_content = fs::read_to_string(snapshot_file).unwrap();
assert!(snapshot_content.contains("directories:"));
assert!(snapshot_content.contains("src"));
assert!(snapshot_content.contains("main.rs"));
}
#[test]
fn test_cli_info_integration() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("config.yml");
let config_content = r#"
created: "2024-01-01T00:00:00Z"
directories:
src:
main.rs: "fn main() {}"
stats:
files: 1
directories: 1
"#;
fs::write(&config_file, config_content).unwrap();
let output = Command::new("cargo")
.args(["run", "--", "info", config_file.to_str().unwrap()])
.output()
.expect("Failed to run skeletor info");
assert!(output.status.success(), "Info command failed: {}",
String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Created:"), "Expected 'Created:' in output: {}", stdout);
assert!(stdout.contains("2024-01-01"));
}
#[test]
fn test_cli_error_missing_config() {
let output = Command::new("cargo")
.args(["run", "--", "apply", "nonexistent.yml"])
.output()
.expect("Failed to run skeletor with missing config");
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains("error:") || stderr.contains("Error") || stderr.contains("not found"));
}
#[test]
fn test_cli_apply_with_output_directory() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("test.yml");
let output_dir = temp_dir.path().join("output");
let config_content = r#"directories:
src:
main.rs: |
fn main() {
println!("Hello from output dir!");
}
README.md: "Test Project Documentation"
"#;
fs::write(&config_file, config_content).unwrap();
let output = Command::new("cargo")
.args([
"run", "--", "apply",
config_file.to_str().unwrap(),
"-o", output_dir.to_str().unwrap()
])
.output()
.expect("Failed to run skeletor apply with -o");
assert!(output.status.success(), "Apply command with -o failed: {}",
String::from_utf8_lossy(&output.stderr));
assert!(output_dir.join("src/main.rs").exists(), "main.rs should exist in output directory");
assert!(output_dir.join("README.md").exists(), "README.md should exist in output directory");
let main_content = fs::read_to_string(output_dir.join("src/main.rs")).unwrap();
assert!(main_content.contains("Hello from output dir!"));
assert!(!temp_dir.path().join("src").exists(), "Files should not be in root directory");
}
#[test]
fn test_cli_apply_with_output_long_flag() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("test.yml");
let output_dir = temp_dir.path().join("output_long");
let config_content = r#"
directories:
test_file.txt: "test content"
"#;
fs::write(&config_file, config_content).unwrap();
let output = Command::new("cargo")
.args([
"run", "--", "apply",
config_file.to_str().unwrap(),
"--output", output_dir.to_str().unwrap()
])
.output()
.expect("Failed to run skeletor apply with --output");
assert!(output.status.success(), "Apply command with --output failed: {}",
String::from_utf8_lossy(&output.stderr));
assert!(output_dir.join("test_file.txt").exists(), "test_file.txt should exist in output directory");
}
#[test]
fn test_cli_apply_output_with_overwrite() {
let temp_dir = tempdir().unwrap();
let config_file = temp_dir.path().join("test.yml");
let output_dir = temp_dir.path().join("output_overwrite");
let config_content = r#"
directories:
test.txt: "initial content"
"#;
fs::write(&config_file, config_content).unwrap();
fs::create_dir_all(&output_dir).unwrap();
fs::write(output_dir.join("test.txt"), "existing content").unwrap();
let output = Command::new("cargo")
.args([
"run", "--", "apply",
config_file.to_str().unwrap(),
"-o", output_dir.to_str().unwrap(),
"--overwrite"
])
.output()
.expect("Failed to run skeletor apply with -o and --overwrite");
assert!(output.status.success(), "Apply command with -o and --overwrite failed: {}",
String::from_utf8_lossy(&output.stderr));
let content = fs::read_to_string(output_dir.join("test.txt")).unwrap();
assert_eq!(content, "initial content", "File should be overwritten with new content");
}
#[test]
fn test_cli_version() {
let output = Command::new("cargo")
.args(["run", "--", "--version"])
.output()
.expect("Failed to run skeletor --version");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Skeletor"));
assert!(stdout.contains(env!("CARGO_PKG_VERSION")));
}