diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | tests/support.rs | 35 | ||||
-rw-r--r-- | tests/test_decl.rs | 15 | ||||
-rw-r--r-- | tests/test_func.rs | 81 | ||||
-rw-r--r-- | tests/test_struct.rs | 179 | ||||
-rw-r--r-- | tests/test_union.rs | 43 | ||||
-rw-r--r-- | tests/tests.rs | 8 |
8 files changed, 195 insertions, 171 deletions
diff --git a/.travis.yml b/.travis.yml index c70783a6..d5b4a601 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: rust +rust: + - nightly env: - LLVM_VERSION=3.4 - LLVM_VERSION=3.5 @@ -12,6 +12,9 @@ log = "*" libc = "*" syntex_syntax = "*" +[dev-dependencies.rust-bindgen-plugin] +path = "./plugin" + [features] static = [] diff --git a/tests/support.rs b/tests/support.rs index acef5dbe..dda9ebae 100644 --- a/tests/support.rs +++ b/tests/support.rs @@ -31,25 +31,34 @@ pub fn generate_bindings(filename: &str) -> Result<Vec<P<ast::Item>>, ()> { Ok(try!(bindgen::Bindings::generate(&options, Some(&logger as &Logger), None)).into_ast()) } -pub fn test_bind_eq<F>(filename: &str, f:F) - where F: FnOnce(DummyExtCtxt) -> Vec<Option<P<ast::Item>>> +pub fn assert_bind_eq(filename: &str, reference_items_str: &str) { let ext_cx = mk_dummy_ext_ctxt(); - let items = generate_bindings(filename).unwrap(); - let quoted =f(ext_cx).into_iter().map(|x| x.unwrap()).collect(); + let generated_items = generate_bindings(&format!("tests/{}", filename)[..]).unwrap(); + + let mut parser = parse::new_parser_from_source_str(ext_cx.parse_sess(), ext_cx.cfg(), "".to_string(), reference_items_str.to_string()); + let mut reference_items = Vec::new(); + while let Some(item) = parser.parse_item() { + reference_items.push(item); + } // The ast::Items themselves have insignificant (for our purposes) // differences that make them difficult to compare directly. So, compare // rendered versions, which is not beautiful, but should work. - assert_eq!(render_items("ed), render_items(&items)); -} - -macro_rules! assert_bind_eq { - ($filename:expr, $ext_cx:ident, $($quote:expr),*) => { - ::support::test_bind_eq(concat!("tests/", $filename), |ext_cx| { - let $ext_cx = &ext_cx; - vec!($($quote),*) - }); + let reference_rendered = render_items(&reference_items); + let generated_rendered = render_items(&generated_items); + + if reference_rendered != generated_rendered { + println!("Generated bindings for {} do not match the reference bindings.", filename); + println!(""); + println!("Generated:"); + println!(""); + println!("{}", generated_rendered); + println!(""); + println!("Reference:"); + println!(""); + println!("{}", reference_rendered); + panic!(); } } diff --git a/tests/test_decl.rs b/tests/test_decl.rs index 38ff24e0..feac3720 100644 --- a/tests/test_decl.rs +++ b/tests/test_decl.rs @@ -1,11 +1,10 @@ +use support::assert_bind_eq; + #[test] fn ptr_to_array() { - assert_bind_eq!("headers/decl_ptr_to_array.h", cx, - quote_item!(cx, - extern "C" { - pub static mut foo: [::libc::c_int; 1usize]; - } - ) - ); - + assert_bind_eq("headers/decl_ptr_to_array.h", " + extern \"C\" { + pub static mut foo: [::libc::c_int; 1usize]; + } + "); } diff --git a/tests/test_func.rs b/tests/test_func.rs index 93e165c5..6f809a38 100644 --- a/tests/test_func.rs +++ b/tests/test_func.rs @@ -1,61 +1,58 @@ +use support::assert_bind_eq; + #[test] fn func_ptr() { - assert_bind_eq!("headers/func_ptr.h", cx, - quote_item!(cx, - extern "C" { - pub static mut foo: ::std::option::Option< - extern "C" fn(x: ::libc::c_int, - y: ::libc::c_int) -> ::libc::c_int>; - } - ) - ); + assert_bind_eq("headers/func_ptr.h", " + extern \"C\" { + pub static mut foo: ::std::option::Option< + extern \"C\" fn(x: ::libc::c_int, + y: ::libc::c_int) -> ::libc::c_int>; + } + "); } #[test] fn func_ptr_in_struct() { - assert_bind_eq!("headers/func_ptr_in_struct.h", cx, - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_Foo { - pub bar: ::std::option::Option< - extern "C" fn(x: ::libc::c_int, - y: ::libc::c_int) -> Enum_baz>, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_Foo { - fn default() -> Struct_Foo { unsafe { ::std::mem::zeroed() } } - } - ) - ); + assert_bind_eq("headers/func_ptr_in_struct.h", " + #[repr(C)] + #[derive(Copy)] + pub struct Struct_Foo { + pub bar: ::std::option::Option< + extern \"C\" fn(x: ::libc::c_int, + y: ::libc::c_int) -> Enum_baz>, + } + + impl ::std::clone::Clone for Struct_Foo { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_Foo { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); } #[test] fn func_proto() { - assert_bind_eq!("headers/func_proto.h", cx, - quote_item!(cx, - pub type foo = extern "C" fn(bar: ::libc::c_int) -> ::libc::c_int; - )); + assert_bind_eq("headers/func_proto.h", " + pub type foo = extern \"C\" fn(bar: ::libc::c_int) -> ::libc::c_int; + "); } #[test] fn with_func_ptr_arg() { - assert_bind_eq!("headers/func_with_func_ptr_arg.h", cx, - quote_item!(cx, - extern "C" { - pub fn foo(bar: ::std::option::Option<extern "C" fn() -> () >) -> (); - } - )); + assert_bind_eq("headers/func_with_func_ptr_arg.h", " + extern \"C\" { + pub fn foo(bar: ::std::option::Option<extern \"C\" fn() -> () >) -> (); + } + "); } #[test] fn with_array_arg() { - assert_bind_eq!("headers/func_with_array_arg.h", cx, - quote_item!(cx, - extern "C" { - pub fn f(x: *mut ::libc::c_int) -> (); - } - ) - ); + assert_bind_eq("headers/func_with_array_arg.h", " + extern \"C\" { + pub fn f(x: *mut ::libc::c_int) -> (); + } + "); } diff --git a/tests/test_struct.rs b/tests/test_struct.rs index feee0058..f271421c 100644 --- a/tests/test_struct.rs +++ b/tests/test_struct.rs @@ -1,5 +1,7 @@ use std::default::Default; +use support::assert_bind_eq; + #[test] fn with_anon_struct() { mod ffi { bindgen!("headers/struct_with_anon_struct.h"); } @@ -14,47 +16,52 @@ fn with_anon_struct() { #[test] fn with_anon_struct_array() { - assert_bind_eq!("headers/struct_with_anon_struct_array.h", cx, - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_foo { - pub bar: [Struct_Unnamed1; 2usize], - pub baz: [[[Struct_Unnamed2; 4usize]; 3usize]; 2usize], - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_foo { - fn default() -> Struct_foo { unsafe { ::std::mem::zeroed() } } - } - ), - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_Unnamed1 { - pub a: ::libc::c_int, - pub b: ::libc::c_int, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_Unnamed1 { - fn default() -> Struct_Unnamed1 { unsafe { ::std::mem::zeroed() } } - } - ), - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_Unnamed2 { - pub a: ::libc::c_int, - pub b: ::libc::c_int, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_Unnamed2 { - fn default() -> Struct_Unnamed2 { unsafe { ::std::mem::zeroed() } } - } - ) - ); + assert_bind_eq("headers/struct_with_anon_struct_array.h", " + #[repr(C)] + #[derive(Copy)] + pub struct Struct_foo { + pub bar: [Struct_Unnamed1; 2usize], + pub baz: [[[Struct_Unnamed2; 4usize]; 3usize]; 2usize], + } + + impl ::std::clone::Clone for Struct_foo { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_foo { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + + #[repr(C)] + #[derive(Copy)] + pub struct Struct_Unnamed1 { + pub a: ::libc::c_int, + pub b: ::libc::c_int, + } + + impl ::std::clone::Clone for Struct_Unnamed1 { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_Unnamed1 { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + + #[repr(C)] + #[derive(Copy)] + pub struct Struct_Unnamed2 { + pub a: ::libc::c_int, + pub b: ::libc::c_int, + } + + impl ::std::clone::Clone for Struct_Unnamed2 { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_Unnamed2 { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); } #[test] @@ -135,53 +142,57 @@ fn with_nesting() { #[test] fn containing_fwd_decl_struct() { - assert_bind_eq!("headers/struct_containing_forward_declared_struct.h", cx, - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_a { - pub val_a: *mut Struct_b, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_a { - fn default() -> Struct_a { unsafe { ::std::mem::zeroed() } } - } - ), - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_b { - pub val_b: ::libc::c_int, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_b { - fn default() -> Struct_b { unsafe { ::std::mem::zeroed() } } - } - ) - ); + assert_bind_eq("headers/struct_containing_forward_declared_struct.h", " + #[repr(C)] + #[derive(Copy)] + pub struct Struct_a { + pub val_a: *mut Struct_b, + } + + impl ::std::clone::Clone for Struct_a { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_a { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + + #[repr(C)] + #[derive(Copy)] + pub struct Struct_b { + pub val_b: ::libc::c_int, + } + + impl ::std::clone::Clone for Struct_b { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_b { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); } #[test] fn with_bitfields() { - assert_bind_eq!("headers/struct_with_bitfields.h", cx, - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Struct_bitfield { - pub _bindgen_bitfield_1_: ::libc::c_ushort, - pub e: ::libc::c_int, - pub _bindgen_bitfield_2_: ::libc::c_uint, - pub _bindgen_bitfield_3_: ::libc::c_uint, - } - ), - quote_item!(cx, - impl ::std::default::Default for Struct_bitfield { - fn default() -> Struct_bitfield { unsafe { ::std::mem::zeroed() } } - } - ) - ); + assert_bind_eq("headers/struct_with_bitfields.h", " + #[repr(C)] + #[derive(Copy)] + pub struct Struct_bitfield { + pub _bindgen_bitfield_1_: ::libc::c_ushort, + pub e: ::libc::c_int, + pub _bindgen_bitfield_2_: ::libc::c_uint, + pub _bindgen_bitfield_3_: ::libc::c_uint, + } + + impl ::std::clone::Clone for Struct_bitfield { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Struct_bitfield { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); } #[test] diff --git a/tests/test_union.rs b/tests/test_union.rs index 540d9305..c899d826 100644 --- a/tests/test_union.rs +++ b/tests/test_union.rs @@ -1,5 +1,7 @@ use std::default::Default; +use support::assert_bind_eq; + #[test] fn with_anon_struct() { mod ffi { bindgen!("headers/union_with_anon_struct.h"); } @@ -16,27 +18,28 @@ fn with_anon_struct() { #[test] fn with_anon_struct_bitfield() { - assert_bind_eq!("headers/union_with_anon_struct_bitfield.h", cx, - quote_item!(cx, - #[repr(C)] - #[derive(Copy)] - pub struct Union_foo { - pub _bindgen_data_: [u32; 1usize], - } - ), - quote_item!(cx, - impl Union_foo { - pub unsafe fn a(&mut self) -> *mut ::libc::c_int { - ::std::mem::transmute(&self._bindgen_data_) - } - } - ), - quote_item!(cx, - impl ::std::default::Default for Union_foo { - fn default() -> Union_foo { unsafe { ::std::mem::zeroed() } } + assert_bind_eq("headers/union_with_anon_struct_bitfield.h", " + #[repr(C)] + #[derive(Copy)] + pub struct Union_foo { + pub _bindgen_data_: [u32; 1usize], + } + + impl Union_foo { + pub unsafe fn a(&mut self) -> *mut ::libc::c_int { + let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_); + ::std::mem::transmute(raw.offset(0)) } - ) - ); + } + + impl ::std::clone::Clone for Union_foo { + fn clone(&self) -> Self { *self } + } + + impl ::std::default::Default for Union_foo { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); } #[test] diff --git a/tests/tests.rs b/tests/tests.rs index 6c54c665..669f5623 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,11 +1,11 @@ -#![feature(quote, plugin, libc, rustc_private)] -#![plugin(bindgen)] +#![feature(plugin)] +#![plugin(bindgen_plugin)] +#![allow(dead_code)] extern crate bindgen; extern crate libc; -extern crate syntax; +extern crate syntex_syntax as syntax; -#[macro_use] mod support; mod test_cmath; |