use std::fs;
use std::path::PathBuf;
use std::process::Command;
fn create_test_project(name: &str, is_cpp: bool) -> PathBuf {
let temp_dir = std::env::temp_dir().join("caxe_tests").join(name);
if temp_dir.exists() {
fs::remove_dir_all(&temp_dir).ok();
}
fs::create_dir_all(&temp_dir).expect("Failed to create test directory");
fs::create_dir_all(temp_dir.join("src")).expect("Failed to create src directory");
let edition = if is_cpp { "c++17" } else { "c17" };
let ext = if is_cpp { "cpp" } else { "c" };
let cx_toml = format!(
r#"[package]
name = "{name}"
version = "0.1.0"
edition = "{edition}"
[build]
sources = ["src/main.{ext}"]
"#
);
fs::write(temp_dir.join("cx.toml"), cx_toml).expect("Failed to write cx.toml");
let main_content = if is_cpp {
r#"#include <iostream>
int main() {
std::cout << "Hello from test!" << std::endl;
return 0;
}
"#
} else {
r#"#include <stdio.h>
int main() {
printf("Hello from test!\n");
return 0;
}
"#
};
fs::write(
temp_dir.join("src").join(format!("main.{ext}")),
main_content,
)
.expect("Failed to write main source file");
temp_dir
}
fn get_cx_binary() -> PathBuf {
let mut path = std::env::current_exe().expect("Failed to get current exe");
path.pop(); path.pop(); path.join("cx.exe") }
#[test]
fn test_build_simple_cpp_project() {
let project_dir = create_test_project("test_cpp_build", true);
let cx = get_cx_binary();
if !cx.exists() {
eprintln!("Skipping test: cx binary not found at {:?}", cx);
return;
}
let output = Command::new(&cx)
.arg("build")
.current_dir(&project_dir)
.output()
.expect("Failed to execute cx build");
assert!(
output.status.success(),
"Build failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let _binary = if cfg!(windows) {
project_dir
.join("build")
.join("debug")
.join("test_cpp_build.exe")
} else {
project_dir
.join("build")
.join("debug")
.join("test_cpp_build")
};
assert!(
project_dir.join("build").exists() || project_dir.join(".cx").join("build").exists(),
"Build directory not created"
);
fs::remove_dir_all(&project_dir).ok();
}
#[test]
fn test_build_simple_c_project() {
let project_dir = create_test_project("test_c_build", false);
let cx = get_cx_binary();
if !cx.exists() {
eprintln!("Skipping test: cx binary not found at {:?}", cx);
return;
}
let output = Command::new(&cx)
.arg("build")
.current_dir(&project_dir)
.output()
.expect("Failed to execute cx build");
assert!(
output.status.success(),
"Build failed: {}",
String::from_utf8_lossy(&output.stderr)
);
fs::remove_dir_all(&project_dir).ok();
}
#[test]
fn test_build_release_mode() {
let project_dir = create_test_project("test_release_build", true);
let cx = get_cx_binary();
if !cx.exists() {
eprintln!("Skipping test: cx binary not found at {:?}", cx);
return;
}
let output = Command::new(&cx)
.args(["build", "--release"])
.current_dir(&project_dir)
.output()
.expect("Failed to execute cx build --release");
assert!(
output.status.success(),
"Release build failed: {}",
String::from_utf8_lossy(&output.stderr)
);
fs::remove_dir_all(&project_dir).ok();
}
#[test]
fn test_dry_run_mode() {
let project_dir = create_test_project("test_dry_run", true);
let cx = get_cx_binary();
if !cx.exists() {
eprintln!("Skipping test: cx binary not found at {:?}", cx);
return;
}
let output = Command::new(&cx)
.args(["build", "--dry-run"])
.current_dir(&project_dir)
.output()
.expect("Failed to execute cx build --dry-run");
assert!(
output.status.success(),
"Dry run failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("Would execute") || stdout.contains("DRY RUN") || output.status.success(),
"Dry run should indicate what would be done"
);
fs::remove_dir_all(&project_dir).ok();
}