summaryrefslogtreecommitdiff
path: root/tests/tests.rs
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-01-22 12:58:12 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-01-23 10:22:08 +0100
commitb83da2729fc83663f979da05201920e039ae3c3f (patch)
tree27e1c8b1b7f0fef74b064740238da843d4cfc1f6 /tests/tests.rs
parent7373a4258f652c23e5fe00ad14740393caa40082 (diff)
Unify under the `bindgen` name.
Diffstat (limited to 'tests/tests.rs')
-rw-r--r--tests/tests.rs140
1 files changed, 140 insertions, 0 deletions
diff --git a/tests/tests.rs b/tests/tests.rs
new file mode 100644
index 00000000..05c8ad2c
--- /dev/null
+++ b/tests/tests.rs
@@ -0,0 +1,140 @@
+extern crate clap;
+extern crate diff;
+extern crate bindgen;
+extern crate shlex;
+
+use bindgen::Builder;
+use std::fs;
+use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Write};
+use std::path::PathBuf;
+
+#[path="../src/options.rs"]
+mod options;
+use options::builder_from_flags;
+
+fn compare_generated_header(header: &PathBuf,
+ builder: Builder)
+ -> Result<(), Error> {
+ let file_name = try!(header.file_name()
+ .ok_or(Error::new(ErrorKind::Other, "spawn_bindgen expects a file")));
+
+ let mut expected = PathBuf::from(header);
+ expected.pop();
+ expected.pop();
+ expected.push("expectations");
+ expected.push("tests");
+ expected.push(file_name);
+ expected.set_extension("rs");
+
+ // We skip the generate() error here so we get a full diff below
+ let output = match builder.generate() {
+ Ok(bindings) => bindings.to_string(),
+ Err(_) => "".to_string(),
+ };
+
+ let mut buffer = String::new();
+ {
+ if let Ok(expected_file) = fs::File::open(&expected) {
+ try!(BufReader::new(expected_file).read_to_string(&mut buffer));
+ }
+ }
+
+ if output == buffer {
+ if !output.is_empty() {
+ return Ok(());
+ }
+ return Err(Error::new(ErrorKind::Other,
+ "Something's gone really wrong!"));
+ }
+
+ println!("diff expected generated");
+ println!("--- expected: {:?}", expected);
+ println!("+++ generated from: {:?}", header);
+
+ for diff in diff::lines(&buffer, &output) {
+ match diff {
+ diff::Result::Left(l) => println!("-{}", l),
+ diff::Result::Both(l, _) => println!(" {}", l),
+ diff::Result::Right(r) => println!("+{}", r),
+ }
+ }
+
+ // Override the diff.
+ {
+ let mut expected_file = try!(fs::File::create(&expected));
+ try!(expected_file.write_all(output.as_bytes()));
+ }
+
+ Err(Error::new(ErrorKind::Other, "Header and binding differ!"))
+}
+
+fn create_bindgen_builder(header: &PathBuf)
+ -> Result<Option<Builder>, Error> {
+ let source = try!(fs::File::open(header));
+ let reader = BufReader::new(source);
+
+ // Scoop up bindgen-flags from test header
+ let mut flags = Vec::with_capacity(2);
+
+ for line in reader.lines().take(2) {
+ let line = try!(line);
+ if line.contains("bindgen-flags: ") {
+ let extra_flags = line.split("bindgen-flags: ")
+ .last()
+ .and_then(shlex::split)
+ .unwrap();
+ flags.extend(extra_flags.into_iter());
+ } else if line.contains("bindgen-unstable") &&
+ cfg!(feature = "llvm_stable") {
+ return Ok(None);
+ }
+ }
+
+ // Fool builder_from_flags() into believing it has real env::args_os...
+ // - add "bindgen" as executable name 0th element
+ // - add header filename as 1st element
+ // - prepend raw lines so they're in the right order for expected output
+ // - append the test header's bindgen flags
+ let header_str = try!(header.to_str()
+ .ok_or(Error::new(ErrorKind::Other, "Invalid header file name")));
+
+ let prepend = ["bindgen",
+ header_str,
+ "--raw-line",
+ "",
+ "--raw-line",
+ "#![allow(non_snake_case)]",
+ "--raw-line",
+ ""];
+
+ let args = prepend.into_iter()
+ .map(ToString::to_string)
+ .chain(flags.into_iter());
+
+ builder_from_flags(args)
+ .map(|(builder, _)| Some(builder.no_unstable_rust()))
+}
+
+macro_rules! test_header {
+ ($function:ident, $header:expr) => (
+ #[test]
+ fn $function() {
+ let header = PathBuf::from($header);
+ let result = create_bindgen_builder(&header)
+ .and_then(|builder| {
+ if let Some(builder) = builder {
+ compare_generated_header(&header, builder)
+ } else {
+ Ok(())
+ }
+ });
+
+ if let Err(err) = result {
+ panic!("{}", err);
+ }
+ }
+ )
+}
+
+// This file is generated by build.rs
+include!(concat!(env!("OUT_DIR"), "/tests.rs"));