diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 592556b843..ae72afb603 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -122,9 +122,13 @@ You may set the `BINDGEN_OVERWRITE_EXPECTED` environment variable to overwrite the expected bindings with `bindgen`'s current output: ``` -$BINDGEN_OVERWRITE_EXPECTED=1 cargo test +$ BINDGEN_OVERWRITE_EXPECTED=1 cargo test ``` +If you're not changing command line arguments, you may want to set +`BINDGEN_DISABLE_ROUNDTRIP_TEST` to avoid a lot of tests for round-tripping of +those. + ### Testing Generated Bindings If your local changes are introducing expected modifications in the diff --git a/tests/tests.rs b/tests/tests.rs index a85803c3b9..4cf39460e3 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -17,9 +17,6 @@ use std::sync::Once; mod options; use crate::options::builder_from_flags; -/// The environment variable that determines if test expectations are overwritten. -static OVERWRITE_ENV_VAR: &str = "BINDGEN_OVERWRITE_EXPECTED"; - // Run `rustfmt` on the given source string and return a tuple of the formatted // bindings, and rustfmt's stderr. fn rustfmt(source: String) -> (String, String) { @@ -119,6 +116,7 @@ The latest `rustfmt` is required to run the `bindgen` test suite. Install fn compare_generated_header( header: &PathBuf, builder: Builder, + check_roundtrip: bool, ) -> Result<(), Error> { let file_name = header.file_name().ok_or(Error::new( ErrorKind::Other, @@ -194,6 +192,14 @@ fn compare_generated_header( ), }; + let flags = if check_roundtrip { + let mut flags = builder.command_line_flags(); + flags.insert(0, "bindgen".into()); + flags + } else { + vec![] + }; + // We skip the generate() error here so we get a full diff below let (actual, rustfmt_stderr) = match builder.generate() { Ok(bindings) => { @@ -207,37 +213,48 @@ fn compare_generated_header( let (expected, rustfmt_stderr) = rustfmt(expected); println!("{}", rustfmt_stderr); - if actual == expected { - if !actual.is_empty() { - return Ok(()); - } + if actual.is_empty() { return Err(Error::new( ErrorKind::Other, "Something's gone really wrong!", )); } - println!("{}", rustfmt_stderr); + if actual != expected { + println!("{}", rustfmt_stderr); - println!("diff expected generated"); - println!("--- expected: {:?}", looked_at.last().unwrap()); - println!("+++ generated from: {:?}", header); + println!("diff expected generated"); + println!("--- expected: {:?}", looked_at.last().unwrap()); + println!("+++ generated from: {:?}", header); - for diff in diff::lines(&expected, &actual) { - match diff { - diff::Result::Left(l) => println!("-{}", l), - diff::Result::Both(l, _) => println!(" {}", l), - diff::Result::Right(r) => println!("+{}", r), + for diff in diff::lines(&expected, &actual) { + match diff { + diff::Result::Left(l) => println!("-{}", l), + diff::Result::Both(l, _) => println!(" {}", l), + diff::Result::Right(r) => println!("+{}", r), + } } + + // Overwrite the expectation with actual output. + if env::var_os("BINDGEN_OVERWRITE_EXPECTED").is_some() { + let mut expectation_file = + fs::File::create(looked_at.last().unwrap())?; + expectation_file.write_all(actual.as_bytes())?; + } + + return Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation.")); } - // Overwrite the expectation with actual output. - if env::var_os(OVERWRITE_ENV_VAR).is_some() { - let mut expectation_file = fs::File::create(looked_at.last().unwrap())?; - expectation_file.write_all(actual.as_bytes())?; + if check_roundtrip { + let roundtrip_builder = builder_from_flags(flags.into_iter())?.0; + if let Err(e) = + compare_generated_header(&header, roundtrip_builder, false) + { + return Err(Error::new(ErrorKind::Other, format!("Checking CLI flags roundtrip errored! You probably need to fix Builder::command_line_args. {}", e))); + } } - Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation.")) + Ok(()) } fn builder() -> Builder { @@ -328,7 +345,9 @@ macro_rules! test_header { fn $function() { let header = PathBuf::from($header); let result = create_bindgen_builder(&header).and_then(|builder| { - compare_generated_header(&header, builder) + let check_roundtrip = + env::var_os("BINDGEN_DISABLE_ROUNDTRIP_TEST").is_none(); + compare_generated_header(&header, builder, check_roundtrip) }); if let Err(err) = result {