summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChristopher Chambers <chris.chambers@peanutcode.com>2014-12-31 16:25:15 -0600
committerChristopher Chambers <chris.chambers@peanutcode.com>2014-12-31 16:43:04 -0600
commitfc0a9ab26a32344308d92407ec28ef43d155dc85 (patch)
tree192d0f36ccfa39ec0ba6c90bd624181bc66331d7 /tests
parent7fd76345505adde2eee8d63a92190f38d2a7c792 (diff)
Adds Default impls for generated composites.
gen.rs - Structs and unions now emit an implementation of the Default trait using std::mem::zeroed to create a zeroed instance. tests/support.rs - AST comparisons are now done on the pretty-printed version of the ASTs. Differences in AttrIds and some identifiers (generated with gensym to ensure uniqueness) made it unreliable to compare the ASTs directly. This way should work, even if it doesn't score many points for style. tests/* - Updated to use Default::default() where appropriate. - Eliminated a few warnings.
Diffstat (limited to 'tests')
-rw-r--r--tests/support.rs171
-rw-r--r--tests/test_builtins.rs8
-rw-r--r--tests/test_func.rs5
-rw-r--r--tests/test_struct.rs66
-rw-r--r--tests/test_union.rs27
5 files changed, 101 insertions, 176 deletions
diff --git a/tests/support.rs b/tests/support.rs
index a9b6dc4d..d837786a 100644
--- a/tests/support.rs
+++ b/tests/support.rs
@@ -1,15 +1,15 @@
use bindgen;
use bindgen::{Logger, BindgenOptions};
+
use std::default::Default;
-use std::fmt;
-use syntax::ast;
-use syntax::print::pprust;
-use syntax::ptr::P;
+use syntax::ast;
use syntax::codemap;
use syntax::codemap::{Span, DUMMY_SP};
use syntax::parse;
use syntax::parse::token;
+use syntax::print::pprust;
+use syntax::ptr::P;
struct TestLogger;
@@ -33,10 +33,13 @@ pub fn generate_bindings(filename: &str) -> Result<Vec<P<ast::Item>>, ()> {
pub fn test_bind_eq(filename: &str, f:|ext_cx: DummyExtCtxt| -> Vec<Option<P<ast::Item>>>) {
let ext_cx = mk_dummy_ext_ctxt();
- let items = normalize_attr_ids(generate_bindings(filename).unwrap());
- let quoted = normalize_attr_ids(f(ext_cx).into_iter().map(|x| x.unwrap()).collect());
- assert_eq!(PrettyItems { items: items },
- PrettyItems { items: quoted });
+ let items = generate_bindings(filename).unwrap();
+ let quoted =f(ext_cx).into_iter().map(|x| x.unwrap()).collect();
+
+ // 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(&quoted), render_items(&items));
}
macro_rules! assert_bind_eq {
@@ -48,6 +51,17 @@ macro_rules! assert_bind_eq {
}
}
+fn render_items(items: &Vec<P<ast::Item>>) -> String {
+ pprust::to_string(|s| {
+ let module = ast::Mod {
+ inner: DUMMY_SP,
+ view_items: Vec::new(),
+ items: items.clone(),
+ };
+ s.print_mod(&module, &[])
+ })
+}
+
pub struct DummyExtCtxt {
sess: parse::ParseSess,
}
@@ -77,144 +91,3 @@ impl DummyExtCtxt {
fn mk_dummy_ext_ctxt<'a>() -> DummyExtCtxt {
DummyExtCtxt { sess: parse::new_parse_sess() }
}
-
-#[deriving(PartialEq)]
-struct PrettyItems {
- pub items: Vec<P<ast::Item>>,
-}
-
-impl fmt::Show for PrettyItems {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let output = pprust::to_string(|s| {
- let module = ast::Mod {
- inner: DUMMY_SP,
- view_items: Vec::new(),
- items: self.items.clone(),
- };
- s.print_mod(&module, &[])
- });
- write!(f, "\n{}\n", output)
- }
-}
-
-// libsyntax uses a thread-local variable to create unique AttrId values during
-// parsing and quoting. normalize_attr_ids makes sure that all AttrId values
-// for the passed `items` start at zero and proceed upward. This is necessary
-// to correctly compare otherwise-identical ASTs.
-fn normalize_attr_ids(items: Vec<P<ast::Item>>) -> Vec<P<ast::Item>> {
- use std::mem;
- use syntax::visit::*;
-
- struct Vis<'a> {
- attr_id: uint,
- items: Vec<P<ast::Item>>,
- }
-
- impl<'a> Vis<'a> {
- // TODO: visit_crate? ast::visit::Visitor does not deal with them directly,
- // but concievably, it could eventually come up.
-
- fn rewrite_attrs(&mut self, attrs: Vec<ast::Attribute>) -> Vec<ast::Attribute> {
- attrs.into_iter().map(|mut attr| {
- attr.node.id = ast::AttrId(self.attr_id);
- self.attr_id += 1;
- attr
- }).collect()
- }
- }
-
- unsafe fn force_mutable<T>(x: &T) -> &mut T {
- mem::transmute(x)
- }
-
- macro_rules! rewrite_attrs {
- ($self_:ident, $item:expr) => {
- unsafe {
- let unsafe_item = force_mutable($item);
- let new_attrs = mem::replace(&mut unsafe_item.attrs, vec!());
- let new_attrs = $self_.rewrite_attrs(new_attrs);
- mem::replace(&mut unsafe_item.attrs, new_attrs);
- }
- }
- }
-
- impl<'a, 'v> Visitor<'v> for Vis<'a> {
- fn visit_item(&mut self, i: &ast::Item) {
- rewrite_attrs!(self, i);
-
- match i.node {
- ast::ItemImpl(_, _, _, _, ref impl_items) => {
- for impl_item in impl_items.iter() {
- match *impl_item {
- ast::ImplItem::MethodImplItem(_) => { }
- ast::ImplItem::TypeImplItem(ref typedef) => {
- rewrite_attrs!(self, typedef.deref());
- }
- }
- }
- }
- _ => { }
- }
-
- walk_item(self, i);
- }
-
- fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
- rewrite_attrs!(self, i);
- walk_foreign_item(self, i);
- }
-
- fn visit_fn(&mut self, fk: FnKind, fd: &ast::FnDecl, b: &ast::Block, s: Span, _: ast::NodeId) {
- match fk {
- FkItemFn(_, _, _, _) | FkFnBlock => { }
- FkMethod(_, _, method) => {
- rewrite_attrs!(self, method);
- }
- }
- walk_fn(self, fk, fd, b, s);
- }
-
- fn visit_arm(&mut self, a: &ast::Arm) {
- rewrite_attrs!(self, a);
- walk_arm(self, a);
- }
-
- fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
- rewrite_attrs!(self, t);
- walk_ty_method(self, t);
- }
-
- fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
- rewrite_attrs!(self, &v.node);
- walk_variant(self, v, g);
- }
-
- fn visit_view_item(&mut self, i: &ast::ViewItem) {
- rewrite_attrs!(self, i);
- walk_view_item(self, i);
- }
-
- fn visit_struct_field(&mut self, s: &ast::StructField) {
- rewrite_attrs!(self, &s.node);
- walk_struct_field(self, s);
- }
-
- fn visit_trait_item(&mut self, t: &ast::TraitItem) {
- match *t {
- ast::TraitItem::RequiredMethod(_) |
- ast::TraitItem::ProvidedMethod(_) => { }
- ast::TraitItem::TypeTraitItem(ref assoc_ty) => {
- rewrite_attrs!(self, assoc_ty.deref());
- }
- }
- walk_trait_item(self, t);
- }
- }
-
- let mut visitor = Vis { attr_id: 0, items: vec!() };
- for item in items.into_iter() {
- visitor.visit_item(item.deref());
- visitor.items.push(item);
- }
- visitor.items
-}
diff --git a/tests/test_builtins.rs b/tests/test_builtins.rs
index 35cd573c..1df562c8 100644
--- a/tests/test_builtins.rs
+++ b/tests/test_builtins.rs
@@ -1,12 +1,6 @@
-#![feature(phase)]
-
-#[phase(plugin)]
-extern crate bindgen;
-
-extern crate libc;
-
#[test]
fn test_builtin_va_list() {
+ #[allow(dead_code, non_camel_case_types, raw_pointer_deriving)]
mod ffi { bindgen!("headers/builtin_va_list.h", emit_builtins = true); }
// Should test for more than compilation.
}
diff --git a/tests/test_func.rs b/tests/test_func.rs
index 83bc2696..8a0f2584 100644
--- a/tests/test_func.rs
+++ b/tests/test_func.rs
@@ -22,6 +22,11 @@ fn func_ptr_in_struct() {
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() } }
+ }
)
);
}
diff --git a/tests/test_struct.rs b/tests/test_struct.rs
index 2d30174c..c6f6836f 100644
--- a/tests/test_struct.rs
+++ b/tests/test_struct.rs
@@ -1,7 +1,9 @@
+use std::default::Default;
+
#[test]
fn with_anon_struct() {
mod ffi { bindgen!("headers/struct_with_anon_struct.h"); }
- let mut x = ffi::Struct_foo { bar: ffi::Struct_Unnamed1 { a: 0, b: 0 } };
+ let mut x: ffi::Struct_foo = Default::default();
x.bar.a = 1;
x.bar.b = 2;
@@ -13,10 +15,7 @@ fn with_anon_struct() {
#[test]
fn with_anon_struct_array() {
mod ffi { bindgen!("headers/struct_with_anon_struct_array.h"); }
- let mut x = ffi::Struct_foo { bar: [
- ffi::Struct_Unnamed1 { a: 0, b: 0 },
- ffi::Struct_Unnamed1 { a: 1, b: 1 } ]
- };
+ let mut x: ffi::Struct_foo = Default::default();
x.bar[1].a = 1;
x.bar[1].b = 2;
@@ -27,11 +26,13 @@ fn with_anon_struct_array() {
#[test]
fn with_anon_struct_pointer() {
+ #[allow(raw_pointer_deriving)]
mod ffi { bindgen!("headers/struct_with_anon_struct_pointer.h"); }
- let mut unnamed = box ffi::Struct_Unnamed1 { a: 0, b: 0 };
+ let mut x: ffi::Struct_foo = Default::default();
+ let mut unnamed: ffi::Struct_Unnamed1 = Default::default();
unsafe {
- let mut x = ffi::Struct_foo { bar: ::std::mem::transmute(unnamed) };
+ x.bar = &mut unnamed;
(*x.bar).a = 1;
(*x.bar).b = 2;
@@ -46,7 +47,7 @@ fn with_anon_struct_pointer() {
#[test]
fn with_anon_union() {
mod ffi { bindgen!("headers/struct_with_anon_union.h"); }
- let mut x = ffi::Struct_foo { bar: ffi::Union_Unnamed1 { _bindgen_data_: [0] } };
+ let mut x: ffi::Struct_foo = Default::default();
unsafe {
*x.bar.a() = 0x12345678;
@@ -58,7 +59,7 @@ fn with_anon_union() {
#[test]
fn with_anon_unnamed_struct() {
mod ffi { bindgen!("headers/struct_with_anon_unnamed_struct.h"); }
- let mut x = ffi::Struct_foo { _bindgen_data_1_: [0, 0] };
+ let mut x: ffi::Struct_foo = Default::default();
unsafe {
*x.a() = 0x12345678;
@@ -71,7 +72,7 @@ fn with_anon_unnamed_struct() {
#[test]
fn with_anon_unnamed_union() {
mod ffi { bindgen!("headers/struct_with_anon_unnamed_union.h"); }
- let mut x = ffi::Struct_foo { _bindgen_data_1_: [0] };
+ let mut x: ffi::Struct_foo = Default::default();
unsafe {
*x.a() = 0x12345678;
@@ -83,7 +84,7 @@ fn with_anon_unnamed_union() {
#[test]
fn with_nesting() {
mod ffi { bindgen!("headers/struct_with_nesting.h"); }
- let mut x = ffi::Struct_foo { a: 0, _bindgen_data_1_: [0] };
+ let mut x: ffi::Struct_foo = Default::default();
unsafe {
x.a = 0x12345678;
@@ -111,12 +112,23 @@ fn containing_fwd_decl_struct() {
}
),
quote_item!(cx,
+ impl ::std::default::Default for Struct_a {
+ fn default() -> Struct_a { unsafe { ::std::mem::zeroed() } }
+ }
+ ),
+ quote_item!(cx,
#[repr(C)]
#[deriving(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() } }
+ }
+ )
+ );
}
#[test]
@@ -133,7 +145,13 @@ fn with_unnamed_bitfields() {
pub unnamed_field2: ::libc::c_ushort,
pub d: ::libc::c_ushort,
}
- ));
+ ),
+ quote_item!(cx,
+ impl ::std::default::Default for Struct_bitfield {
+ fn default() -> Struct_bitfield { unsafe { ::std::mem::zeroed() } }
+ }
+ )
+ );
}
#[test]
@@ -143,6 +161,24 @@ fn with_fwd_decl_struct() {
let a = ffi::Struct_a { b: 1 };
let c = ffi::Struct_c { d: 1 };
- a.b;
- c.d;
+ assert_eq!(a.b, 1);
+ assert_eq!(c.d, 1);
+}
+
+#[test]
+fn default_impl() {
+ mod ffi { bindgen!("headers/struct_with_nesting.h"); }
+
+ let mut x: ffi::Struct_foo = Default::default();
+
+ unsafe {
+ assert_eq!(x.a, 0);
+ assert_eq!(*x.b(), 0);
+ assert_eq!(*x.c1(), 0);
+ assert_eq!(*x.c2(), 0);
+ assert_eq!(*x.d1(), 0);
+ assert_eq!(*x.d2(), 0);
+ assert_eq!(*x.d3(), 0);
+ assert_eq!(*x.d4(), 0);
+ }
}
diff --git a/tests/test_union.rs b/tests/test_union.rs
index 33a3713d..15759e7f 100644
--- a/tests/test_union.rs
+++ b/tests/test_union.rs
@@ -1,9 +1,11 @@
+use std::default::Default;
+
#[test]
fn with_anon_struct() {
// XXX: Rustc thinks that the anonymous struct, bar, is unused.
#[allow(dead_code)]
mod ffi { bindgen!("headers/union_with_anon_struct.h"); }
- let mut x = ffi::Union_foo { _bindgen_data_: [0, 0] };
+ let mut x: ffi::Union_foo = Default::default();
unsafe {
(*x.bar()).a = 0x12345678;
@@ -17,7 +19,7 @@ fn with_anon_struct() {
#[test]
fn with_anon_union() {
mod ffi { bindgen!("headers/union_with_anon_union.h"); }
- let mut x = ffi::Union_foo { _bindgen_data_: [0] };
+ let mut x: ffi::Union_foo = Default::default();
unsafe {
*(*x.bar()).a() = 0x12345678;
@@ -30,7 +32,7 @@ fn with_anon_union() {
#[test]
fn with_anon_unnamed_struct() {
mod ffi { bindgen!("headers/union_with_anon_unnamed_struct.h"); }
- let mut x = ffi::Union_pixel { _bindgen_data_: [0] };
+ let mut x: ffi::Union_pixel = Default::default();
unsafe {
*x.r() = 0xca;
@@ -49,7 +51,7 @@ fn with_anon_unnamed_struct() {
#[test]
fn with_anon_unnamed_union() {
mod ffi { bindgen!("headers/union_with_anon_unnamed_union.h"); }
- let mut x = ffi::Union_foo { _bindgen_data_: [0] };
+ let mut x: ffi::Union_foo = Default::default();
unsafe {
*x.a() = 0x12345678;
@@ -63,7 +65,7 @@ fn with_anon_unnamed_union() {
#[test]
fn with_nesting() {
mod ffi { bindgen!("headers/union_with_nesting.h"); }
- let mut x = ffi::Union_foo { _bindgen_data_: [0] };
+ let mut x: ffi::Union_foo = Default::default();
unsafe {
*x.a() = 0x12345678;
@@ -75,3 +77,18 @@ fn with_nesting() {
assert_eq!(*x.c2(), 0x1234);
}
}
+
+#[test]
+fn default_impl() {
+ mod ffi { bindgen!("headers/Union_with_nesting.h"); }
+
+ let mut x: ffi::Union_foo = Default::default();
+
+ unsafe {
+ assert_eq!(*x.a(), 0);
+ assert_eq!(*x.b1(), 0);
+ assert_eq!(*x.b2(), 0);
+ assert_eq!(*x.c1(), 0);
+ assert_eq!(*x.c2(), 0);
+ }
+}