Skip to content

Commit ba80e57

Browse files
committed
Allow asserting expectations across different libclang versions
Rather than having a tests that we only run if libclang >= 3.9, this makes the test suite dynamically detect when we have different expectations for different libclang versions. It does this by adding `tests/expectations/tests/libclang-$VERSION` directories, and `testing_only_libclang_$VERSION` features that are consulted when the usual expectation file does not exist. Fixes rust-lang#697
1 parent f63eb00 commit ba80e57

25 files changed

+72
-14
lines changed

.travis.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@ env:
1717
global:
1818
- CARGO_TARGET_DIR=/tmp/bindgen
1919
matrix:
20-
- LLVM_VERSION=3.7.1 BINDGEN_FEATURES=testing_only_llvm_stable
21-
- LLVM_VERSION=3.8.1 BINDGEN_FEATURES=testing_only_llvm_stable
22-
- LLVM_VERSION=3.9.0 BINDGEN_FEATURES=
23-
- LLVM_VERSION=4.0.0 BINDGEN_FEATURES=
20+
- LLVM_VERSION=3.7.1 BINDGEN_FEATURES=testing_only_libclang_3_8
21+
- LLVM_VERSION=3.8.1 BINDGEN_FEATURES=testing_only_libclang_3_8
22+
- LLVM_VERSION=3.9.0 BINDGEN_FEATURES=testing_only_libclang_3_9
23+
- LLVM_VERSION=4.0.0 BINDGEN_FEATURES=testing_only_libclang_4
2424

2525
matrix:
2626
fast_finish: true
2727
allow_failures:
28-
- env: LLVM_VERSION=4.0.0 BINDGEN_FEATURES=
29-
- env: LLVM_VERSION=3.7.1 BINDGEN_FEATURES=testing_only_llvm_stable
28+
- env: LLVM_VERSION=3.7.1 BINDGEN_FEATURES=testing_only_libclang_3_8
3029

3130
cache:
3231
directories:

CONTRIBUTING.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ out to us in a GitHub issue, or stop by
1414
- [Testing](#testing)
1515
- [Overview](#overview)
1616
- [Running All Tests](#running-all-tests)
17+
- [Running a Single Test](#running-a-single-test)
1718
- [Authoring New Tests](#authoring-new-tests)
19+
- [Test Expectations and `libclang` Versions](#test-expectations-and-libclang-versions)
1820
- [Automatic code formatting](#automatic-code-formatting)
1921
- [Generating Graphviz Dot Files](#generating-graphviz-dot-files)
2022
- [Debug Logging](#debug-logging)
@@ -91,9 +93,17 @@ Run `cargo test` to compare generated Rust bindings to the expectations.
9193
### Running All Tests
9294

9395
```
94-
$ cargo test [--all-features]
96+
$ cargo test --features testing_only_libclang_$VERSION
9597
```
9698

99+
Where `$VERSION` is one of:
100+
101+
* `4`
102+
* `3_9`
103+
* `3_8`
104+
105+
depending on which version of `libclang` you have installed.
106+
97107
### Running a Single Test
98108

99109
To generate bindings for a single test header, compile the bindings, and run the
@@ -124,6 +134,25 @@ Then verify the new Rust bindings compile and pass some basic tests:
124134
$ cargo test -p tests_expectations
125135
```
126136

137+
### Test Expectations and `libclang` Versions
138+
139+
If a test generates different bindings across different `libclang` versions (for
140+
example, because we take advantage of better/newer APIs when possible), then you
141+
can add multiple test expectations, one for each supported `libclang`
142+
version. Instead of having a single `tests/expectations/tests/my_test.rs` file,
143+
add each of:
144+
145+
* `tests/expectations/tests/libclang-4/my_test.rs`
146+
* `tests/expectations/tests/libclang-3.9/my_test.rs`
147+
* `tests/expectations/tests/libclang-3.8/my_test.rs`
148+
149+
If you need to update the test expectations for a test file that generates
150+
different bindings for different `libclang` versions, you *don't* need to have
151+
many version of `libclang` installed locally. Just make a work-in-progress pull
152+
request, and then when Travis CI fails, it will log a diff of the
153+
expectations. Use the diff to patch the appropriate expectation file locally and
154+
then update your pull request.
155+
127156
## Automatic code formatting
128157

129158
We use [`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) to enforce a

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,6 @@ static = []
7777
# on bindgen!
7878
testing_only_docs = []
7979
testing_only_extra_assertions = []
80-
testing_only_llvm_stable = []
80+
testing_only_libclang_4 = []
81+
testing_only_libclang_3_9 = []
82+
testing_only_libclang_3_8 = []

bindgen-integration/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ bindgen = { path = ".." }
1111
gcc = "0.3"
1212

1313
[features]
14-
testing_only_llvm_stable = ["bindgen/testing_only_llvm_stable"]
14+
testing_only_libclang_4 = ["bindgen/testing_only_libclang_4"]
15+
testing_only_libclang_3_9 = ["bindgen/testing_only_libclang_3_9"]
16+
testing_only_libclang_3_8 = ["bindgen/testing_only_libclang_3_8"]

src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ pub fn main() {
3131
let bind_args: Vec<_> = env::args().collect();
3232

3333
let version = clang_version();
34-
let expected_version = if cfg!(feature = "testing_only_llvm_stable") {
34+
let expected_version = if cfg!(feature = "testing_only_libclang_4") {
35+
(4, 0)
36+
} else if cfg!(feature = "testing_only_libclang_3_8") {
3537
(3, 8)
3638
} else {
39+
// Default to 3.9.
3740
(3, 9)
3841
};
3942

tests/expectations/tests/libclang-3.8/auto.rs

Whitespace-only changes.

tests/expectations/tests/libclang-3.8/call-conv-field.rs

Whitespace-only changes.

tests/expectations/tests/libclang-3.8/const_bool.rs

Whitespace-only changes.

tests/expectations/tests/libclang-3.8/constant-evaluate.rs

Whitespace-only changes.

tests/expectations/tests/libclang-3.8/inline-function.rs

Whitespace-only changes.

tests/expectations/tests/libclang-3.8/partial-specialization-and-inheritance.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/auto.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/call-conv-field.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/const_bool.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/constant-evaluate.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/inline-function.rs

Whitespace-only changes.

tests/expectations/tests/libclang-4/partial-specialization-and-inheritance.rs

Whitespace-only changes.

tests/stylo_sanity.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ extern crate bindgen;
1414
#[test]
1515
#[cfg(not(any(debug_assertions,
1616
feature = "testing_only_extra_assertions",
17-
feature = "testing_only_llvm_stable")))]
17+
feature = "testing_only_libclang_3_8")))]
18+
#[cfg(any(feature = "testing_only_libclang_3_9",
19+
feature = "testing_only_libclang_4"))]
1820
fn sanity_check_can_generate_stylo_bindings() {
1921
use std::time::Instant;
2022

tests/tests.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,30 @@ fn compare_generated_header(header: &PathBuf,
2626
expected.push(file_name);
2727
expected.set_extension("rs");
2828

29+
// If the expectation file doesn't exist, see if we have different test
30+
// expectations for different libclang versions.
31+
if !expected.is_file() {
32+
let file_name = expected.file_name().unwrap().to_owned();
33+
expected.pop();
34+
35+
if cfg!(feature = "testing_only_libclang_4") {
36+
expected.push("libclang-4");
37+
} else if cfg!(feature = "testing_only_libclang_3_9") {
38+
expected.push("libclang-3.9");
39+
} else if cfg!(feature = "testing_only_libclang_3_8") {
40+
expected.push("libclang-3.8");
41+
}
42+
43+
expected.push(file_name);
44+
45+
if !expected.is_file() {
46+
panic!("missing test expectation file and/or 'testing_only_libclang_$VERSION' \
47+
feature for header '{}'; looking for expectation file at '{}'",
48+
header.display(),
49+
expected.display());
50+
}
51+
}
52+
2953
// We skip the generate() error here so we get a full diff below
3054
let output = match builder.generate() {
3155
Ok(bindings) => bindings.to_string(),
@@ -87,9 +111,6 @@ fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
87111
.and_then(shlex::split)
88112
.unwrap();
89113
flags.extend(extra_flags.into_iter());
90-
} else if line.contains("bindgen-unstable") &&
91-
cfg!(feature = "testing_only_llvm_stable") {
92-
return Ok(None);
93114
} else if line.contains("bindgen-osx-only") {
94115
let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"];
95116
flags = prepend_flags.into_iter()

0 commit comments

Comments
 (0)