2023-03-08 16:26:24 +01:00
|
|
|
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");
|
2023-08-25 10:48:12 -04:00
|
|
|
assert!(
|
|
|
|
output.status.success(),
|
|
|
|
"Building test project failed: {:?}",
|
|
|
|
output
|
|
|
|
);
|
2023-03-08 16:26:24 +01:00
|
|
|
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");
|
2023-08-25 10:48:12 -04:00
|
|
|
assert!(
|
|
|
|
output.status.success(),
|
|
|
|
"Building test project failed: {:?}",
|
|
|
|
output
|
|
|
|
);
|
2023-03-08 16:26:24 +01:00
|
|
|
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"));
|