1#![allow(warnings)]
2
3mod bindings {
4    include!(concat!(env!("OUT_DIR"), "/test.rs"));
5}
6
7mod extern_bindings {
8    include!(concat!(env!("OUT_DIR"), "/extern.rs"));
9}
10
11use std::ffi::CStr;
12use std::mem;
13use std::os::raw::c_int;
14
15#[allow(unused)]
16use bindings::testing::Bar; // This type is generated from module_raw_line.
17
18type MacroInteger = isize;
19
20#[test]
21fn test_static_array() {
22    let mut test = unsafe { bindings::Test_COUNTDOWN.as_ptr() };
23    let expected = unsafe { bindings::Test_countdown() };
24    let also_expected = unsafe { bindings::Test_COUNTDOWN_PTR };
25    assert!(!test.is_null());
26    assert_eq!(also_expected, expected);
27    assert_eq!(test, also_expected);
28
29    let mut expected = 10;
30    unsafe {
31        loop {
32            assert_eq!(*test, expected);
33            if *test == 0 {
34                break;
35            }
36            test = test.offset(1);
37            expected -= 1;
38        }
39    }
40}
41
42#[test]
43fn test_static_method() {
44    let c_str = unsafe { bindings::Test::name() };
45    let name = unsafe { CStr::from_ptr(c_str).to_string_lossy().into_owned() };
46    assert_eq!(name, "Test", "Calling a static C++ method works!");
47}
48
49#[test]
50fn test_constructor() {
51    let test = unsafe { bindings::Test::new(5) };
52    assert_eq!(test.m_int, 5);
53    assert_eq!(test.m_double, 0.0);
54}
55
56#[test]
57fn test_overload() {
58    let test = unsafe { bindings::Test::new1(5.0) };
59    assert_eq!(test.m_int, 0);
60    assert_eq!(test.m_double, 5.0);
61}
62
63#[test]
64fn test_bitfields_first() {
65    let mut first: bindings::bitfields::First = unsafe { mem::zeroed() };
66    assert!(unsafe { first.assert(0, 0, 0) });
67    first.set_three_bits_byte_one(2);
68    first.set_six_bits_byte_two(42);
69    first.set_two_bits_byte_two(1);
70    assert!(unsafe { first.assert(2, 42, 1) });
71}
72
73#[test]
74fn test_bitfields_second() {
75    let mut second: bindings::bitfields::Second = unsafe { mem::zeroed() };
76    assert!(unsafe { second.assert(0, false) });
77    second.set_thirty_one_bits(1337);
78    second.set_one_bit(true);
79    assert!(unsafe { second.assert(1337, true) });
80}
81
82#[test]
83fn test_bitfields_third() {
84    let mut third: bindings::bitfields::Third = unsafe { mem::zeroed() };
85    assert!(unsafe {
86        third.assert(0, false, bindings::bitfields::ItemKind::ITEM_KIND_UNO)
87    });
88    third.set_flags(12345);
89    third.set_is_whatever(true);
90    third.set_kind(bindings::bitfields::ItemKind::ITEM_KIND_TRES);
91    assert!(unsafe {
92        third.assert(12345, true, bindings::bitfields::ItemKind::ITEM_KIND_TRES)
93    });
94}
95
96#[test]
97fn test_bitfields_fourth() {
98    let mut fourth: bindings::bitfields::Fourth = unsafe { mem::zeroed() };
99    assert!(unsafe { fourth.assert(bindings::bitfields::MyEnum::ONE, 0) });
100
101    fourth.set_tag(bindings::bitfields::MyEnum::THREE);
102    fourth.set_ptr(0xdeadbeef);
103    assert!(unsafe {
104        fourth.assert(bindings::bitfields::MyEnum::THREE, 0xdeadbeef)
105    });
106}
107
108#[test]
109fn test_bitfields_date2() {
110    let mut date: bindings::bitfields::Date2 = unsafe { mem::zeroed() };
111    assert!(unsafe { date.assert(0, 0, 0, 0, 0) });
112
113    date.set_nWeekDay(6); // saturdays are the best
114    date.set_nMonthDay(20);
115    date.set_nMonth(11);
116    date.set_nYear(95);
117    date.set_byte(255);
118    assert!(unsafe { date.assert(6, 20, 11, 95, 255) });
119}
120
121#[test]
122fn test_bitfields_fifth() {
123    let mut date: bindings::bitfields::Fifth = unsafe { mem::zeroed() };
124
125    assert!(unsafe { date.assert(0, 0, 0, 0, 0) });
126
127    date.byte = 255; // Set this first, to ensure we don't override it.
128
129    date.set_nWeekDay(6); // saturdays are the best
130    date.set_nMonthDay(20);
131    date.set_nMonth(11);
132    date.set_nYear(95);
133
134    assert!(unsafe { date.assert(6, 20, 11, 95, 255) });
135}
136
137#[test]
138fn test_bitfields_sixth() {
139    let mut date: bindings::bitfields::Sixth = unsafe { mem::zeroed() };
140
141    assert!(unsafe { date.assert(0, 0, 0, 0) });
142
143    date.byte = 255;
144    date.set_nWeekDay(6); // saturdays are the best
145    date.set_nMonthDay(20);
146    date.set_nMonth(11);
147
148    assert!(unsafe { date.assert(255, 6, 11, 20) });
149}
150
151#[test]
152fn test_bitfields_seventh() {
153    let mut large: bindings::bitfields::Seventh = unsafe { mem::zeroed() };
154
155    assert!(unsafe { large.assert(false, 0, 0, 0, 0, false, 0) });
156
157    large.set_first_one_bit(true);
158    large.set_second_thirty_bits(375028802);
159    large.set_third_two_bits(2);
160    large.set_fourth_thirty_bits(643472885);
161    large.set_fifth_two_bits(3);
162    large.set_sixth_one_bit(true);
163    large.set_seventh_thirty_bits(1061657575);
164
165    assert!(unsafe {
166        large.assert(true, 375028802, 2, 643472885, 3, true, 1061657575)
167    });
168
169    assert_eq!(large.first_one_bit(), true);
170    assert_eq!(large.second_thirty_bits(), 375028802);
171    assert_eq!(large.third_two_bits(), 2);
172    assert_eq!(large.fourth_thirty_bits(), 643472885);
173    assert_eq!(large.fifth_two_bits(), 3);
174    assert_eq!(large.sixth_one_bit(), true);
175    assert_eq!(large.seventh_thirty_bits(), 1061657575);
176}
177
178#[test]
179fn test_bitfield_constructors() {
180    use std::mem;
181    let mut first = bindings::bitfields::First {
182        _bitfield_align_1: [],
183        _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3),
184    };
185    assert!(unsafe { first.assert(1, 2, 3) });
186
187    let mut second = bindings::bitfields::Second {
188        _bitfield_align_1: [],
189        _bitfield_1: bindings::bitfields::Second::new_bitfield_1(1337, true),
190    };
191    assert!(unsafe { second.assert(1337, true) });
192
193    let mut third = bindings::bitfields::Third {
194        _bitfield_align_1: [],
195        _bitfield_1: bindings::bitfields::Third::new_bitfield_1(
196            42,
197            false,
198            bindings::bitfields::ItemKind::ITEM_KIND_TRES,
199        ),
200    };
201    assert!(unsafe {
202        third.assert(42, false, bindings::bitfields::ItemKind::ITEM_KIND_TRES)
203    });
204}
205
206impl Drop for bindings::AutoRestoreBool {
207    fn drop(&mut self) {
208        unsafe { bindings::AutoRestoreBool::destruct(self) }
209    }
210}
211
212#[test]
213fn test_destructors() {
214    let mut v = true;
215
216    {
217        let auto_restore = unsafe { bindings::AutoRestoreBool::new(&mut v) };
218        v = false;
219    }
220
221    assert!(v, "Should've been restored when going out of scope");
222}
223
224impl Drop for bindings::InheritsFromVirtualDestructor {
225    fn drop(&mut self) {
226        unsafe {
227            bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self)
228        }
229    }
230}
231
232#[test]
233fn test_virtual_dtor() {
234    unsafe {
235        {
236            let b = bindings::InheritsFromVirtualDestructor::new();
237            // Let it go out of scope.
238        }
239
240        assert_eq!(bindings::InheritsFromVirtualDestructor_sDestructorCount, 1);
241        assert_eq!(bindings::VirtualDestructor_sDestructorCount, 1);
242    }
243}
244
245#[test]
246fn test_item_rename() {
247    assert_eq!(bindings::CONST_VALUE, 3);
248    assert_eq!(unsafe { bindings::function_name() }, 4);
249
250    let _foo = bindings::foo {
251        member: bindings::bar { foo: 2 },
252    };
253}
254
255#[test]
256fn test_matching_with_rename() {
257    assert_eq!(bindings::enum_to_be_constified_THREE, 3);
258    assert_eq!(unsafe { bindings::TEMPLATED_CONST_VALUE.len() }, 30);
259}
260
261#[test]
262fn test_macro_customintkind_path() {
263    let v: &std::any::Any = &bindings::TESTMACRO_CUSTOMINTKIND_PATH;
264    assert!(v.is::<MacroInteger>())
265}
266
267#[test]
268fn test_homogeneous_aggregate_float_union() {
269    unsafe {
270        let coord = &bindings::coord(1., 2., 3., 4.);
271        assert_eq!([1., 2., 3., 4.], coord.v)
272    }
273}
274
275#[test]
276fn test_custom_derive() {
277    // The `add_derives` callback should have added `#[derive(PartialEq)]`
278    // to the `Test` struct. If it didn't, this will fail to compile.
279    let test1 = unsafe { bindings::Test::new(5) };
280    let test2 = unsafe { bindings::Test::new(6) };
281    assert_ne!(test1, test2);
282
283    // The `add_derives` callback should have added `#[derive(PartialOrd)]`
284    // to the `MyOrderedEnum` enum. If it didn't, this will fail to compile.
285
286    let micron = unsafe { bindings::MyOrderedEnum::MICRON };
287    let meter = unsafe { bindings::MyOrderedEnum::METER };
288    let lightyear = unsafe { bindings::MyOrderedEnum::LIGHTYEAR };
289
290    assert!(meter < lightyear);
291    assert!(meter > micron);
292}
293
294#[test]
295fn test_wrap_static_fns() {
296    // GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090
297    unsafe {
298        let f = extern_bindings::foo();
299        assert_eq!(11, f);
300
301        let b = extern_bindings::bar();
302        assert_eq!(1, b);
303
304        let t = extern_bindings::takes_ptr(&mut 1);
305        assert_eq!(2, t);
306
307        extern "C" fn function(x: i32) -> i32 {
308            x + 1
309        }
310
311        let tp = extern_bindings::takes_fn_ptr(Some(function));
312        assert_eq!(2, tp);
313
314        let tf = extern_bindings::takes_fn(Some(function));
315        assert_eq!(3, tf);
316
317        let ta = extern_bindings::takes_alias(Some(function));
318        assert_eq!(4, ta);
319
320        let tq =
321            extern_bindings::takes_qualified(&(&5 as *const _) as *const _);
322        assert_eq!(5, tq);
323    }
324}
325