diff options
Diffstat (limited to '')
-rw-r--r-- | tests/depfile.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/tests/depfile.rs b/tests/depfile.rs new file mode 100644 index 0000000..7d629f3 --- /dev/null +++ b/tests/depfile.rs @@ -0,0 +1,108 @@ +use std::fs::read_to_string; +use std::path::PathBuf; +use std::process::Command; + +static CBINDGEN_PATH: &str = env!("CARGO_BIN_EXE_cbindgen"); + +fn test_project(project_path: &str) { + let mut cmake_cmd = Command::new("cmake"); + cmake_cmd.arg("--version"); + cmake_cmd + .output() + .expect("CMake --version failed - Is CMake installed?"); + + let mut cmake_configure = Command::new("cmake"); + let build_dir = PathBuf::from(project_path).join("build"); + if build_dir.exists() { + std::fs::remove_dir_all(&build_dir).expect("Failed to remove old build directory"); + } + let project_dir = PathBuf::from(project_path); + + let cbindgen_define = format!("-DCBINDGEN_PATH={}", CBINDGEN_PATH); + cmake_configure + .arg("-S") + .arg(project_path) + .arg("-B") + .arg(&build_dir) + .arg(cbindgen_define); + let output = cmake_configure.output().expect("Failed to execute process"); + let stdout_str = String::from_utf8(output.stdout).unwrap(); + let stderr_str = String::from_utf8(output.stderr).unwrap(); + assert!( + output.status.success(), + "Configuring test project failed: stdout: `{}`, stderr: `{}`", + stdout_str, + stderr_str + ); + let depfile_path = build_dir.join("depfile.d"); + assert!( + !depfile_path.exists(), + "depfile should not exist before building" + ); + + // Do the clean first build + let mut cmake_build = Command::new("cmake"); + cmake_build.arg("--build").arg(&build_dir); + let output = cmake_build.output().expect("Failed to execute process"); + assert!(output.status.success(), "Building test project failed"); + let out_str = String::from_utf8(output.stdout).unwrap(); + assert!( + out_str.contains("Running cbindgen"), + "cbindgen rule did not run. Output: {}", + out_str + ); + + assert!( + depfile_path.exists(), + "depfile does not exist after building" + ); + + let expected_dependencies_filepath = PathBuf::from(project_path) + .join("expectations") + .join("dependencies"); + assert!( + expected_dependencies_filepath.exists(), + "Test did not define expected dependencies. Please read the Readme.md" + ); + let expected_deps = + read_to_string(expected_dependencies_filepath).expect("Failed to read dependencies"); + let depinfo = read_to_string(depfile_path).expect("Failed to read dependencies"); + // Assumes a single rule in the file - all deps are listed to the rhs of the `:`. + let actual_deps = depinfo.split(':').collect::<Vec<_>>()[1]; + // Strip the line breaks. + let actual_deps = actual_deps.replace("\\\n", " "); + // I don't want to deal with supporting escaped whitespace when splitting at whitespace, + // so the tests don't support being run in a directory containing whitespace. + assert!( + !actual_deps.contains("\\ "), + "The tests directory may not contain any whitespace" + ); + let dep_list: Vec<&str> = actual_deps.split_ascii_whitespace().collect(); + let expected_dep_list: Vec<String> = expected_deps + .lines() + .map(|dep| project_dir.join(dep).to_str().unwrap().to_string()) + .collect(); + assert_eq!(dep_list, expected_dep_list); + + let output = cmake_build.output().expect("Failed to execute process"); + assert!(output.status.success(), "Building test project failed"); + let out_str = String::from_utf8(output.stdout).unwrap(); + assert!( + !out_str.contains("Running cbindgen"), + "cbindgen rule ran on second build" + ); + + std::fs::remove_dir_all(build_dir).expect("Failed to remove old build directory"); +} + +macro_rules! test_file { + ($test_function_name:ident, $name:expr, $file:tt) => { + #[test] + fn $test_function_name() { + test_project($file); + } + }; +} + +// This file is generated by build.rs +include!(concat!(env!("OUT_DIR"), "/depfile_tests.rs")); |