Skip to content

Commit 551cb23

Browse files
committed
Call tests/tools/run-bindgen.py from cargo test
Fixes #51
1 parent c23cfa2 commit 551cb23

File tree

3 files changed

+125
-3
lines changed

3 files changed

+125
-3
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ before_script:
4040

4141
script:
4242
- cargo build --verbose --features llvm_stable
43-
- make test
43+
- cargo test --features llvm_stable
4444
- git add -A
4545
- git diff @
4646
- git diff-index --quiet HEAD

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ $(BINDGEN):
1212
[ -f $@ ] || cargo build --features llvm_stable
1313

1414
.PHONY: test
15-
test: regen-tests
16-
@echo > /dev/null
15+
test:
16+
cargo test --features llvm_stable
1717

1818

1919
.PHONY: regen-tests

tests/tests.rs

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use std::env;
2+
use std::fs;
3+
use std::io::Read;
4+
use std::path::{Path, PathBuf};
5+
use std::process;
6+
7+
fn spawn_run_bindgen<P, Q, R>(run_bindgen: P, bindgen: Q, header: R) -> process::Child
8+
where P: AsRef<Path>,
9+
Q: AsRef<Path>,
10+
R: AsRef<Path>
11+
{
12+
let run_bindgen = run_bindgen.as_ref();
13+
let bindgen = bindgen.as_ref();
14+
let header = header.as_ref();
15+
16+
// Convert from "tests/headers/foo.hpp" to "tests/expectations/foo.rs" by
17+
// saving the filename, popping off "headers/foo.hpp", pushing
18+
// "expectations", pushing the saved filename, and finally modifying the
19+
// extension.
20+
21+
let mut expected = PathBuf::from(header);
22+
let file_name = expected.file_name()
23+
.expect("Should have filename")
24+
.to_os_string();
25+
expected.pop();
26+
expected.pop();
27+
expected.push("expectations");
28+
expected.push(file_name);
29+
expected.set_extension("rs");
30+
31+
process::Command::new(run_bindgen)
32+
.arg(bindgen)
33+
.arg(header)
34+
.stdout(process::Stdio::piped())
35+
.stderr(process::Stdio::piped())
36+
.arg(expected)
37+
.spawn()
38+
.expect("Should be able to spawn run-bindgen.py child process")
39+
}
40+
41+
#[test]
42+
fn run_bindgen_tests() {
43+
let crate_root = env::var("CARGO_MANIFEST_DIR")
44+
.expect("should have CARGO_MANIFEST_DIR environment variable");
45+
46+
let mut run_bindgen = PathBuf::from(&crate_root);
47+
run_bindgen.push("tests");
48+
run_bindgen.push("tools");
49+
run_bindgen.push("run-bindgen.py");
50+
51+
let mut bindgen = PathBuf::from(&crate_root);
52+
bindgen.push("target");
53+
bindgen.push("debug");
54+
bindgen.push("bindgen");
55+
if !bindgen.is_file() {
56+
panic!("{} is not a file! Build bindgen before running tests.",
57+
bindgen.display());
58+
}
59+
60+
let mut headers_dir = PathBuf::from(&crate_root);
61+
headers_dir.push("tests");
62+
headers_dir.push("headers");
63+
64+
let entries = fs::read_dir(&headers_dir)
65+
.expect("Should read directory")
66+
.map(|result| result.expect("Should read directory entry"));
67+
68+
let tests = entries.filter(|entry| {
69+
match entry.path().extension().map(|s| s.to_str()) {
70+
Some(Some("h")) |
71+
Some(Some("hpp")) => true,
72+
_ => false,
73+
}
74+
});
75+
76+
// First spawn all child processes and collect them, then wait on each
77+
// one. This runs the tests in parallel rather than serially.
78+
79+
let children: Vec<_> = tests.map(|entry| {
80+
let child = spawn_run_bindgen(run_bindgen.clone(), bindgen.clone(), entry.path());
81+
(entry.path(), child)
82+
})
83+
.collect();
84+
85+
let failures: Vec<_> = children.into_iter()
86+
.filter_map(|(path, mut child)| {
87+
let passed = child.wait()
88+
.expect("Should wait on child process")
89+
.success();
90+
91+
if passed { None } else { Some((path, child)) }
92+
})
93+
.collect();
94+
95+
let num_failures = failures.len();
96+
97+
for (path, child) in failures {
98+
println!("FAIL: {}", path.display());
99+
100+
let mut buf = String::new();
101+
102+
child.stdout
103+
.expect("should have stdout piped")
104+
.read_to_string(&mut buf)
105+
.expect("should read child's stdout");
106+
for line in buf.lines() {
107+
println!("child stdout> {}", line);
108+
}
109+
110+
child.stderr
111+
.expect("should have stderr piped")
112+
.read_to_string(&mut buf)
113+
.expect("should read child's stderr");
114+
for line in buf.lines() {
115+
println!("child stderr> {}", line);
116+
}
117+
}
118+
119+
if num_failures > 0 {
120+
panic!("{} test failures!", num_failures);
121+
}
122+
}

0 commit comments

Comments
 (0)