1 // This file was generated by gir (https://github.com/gtk-rs/gir @ 894f9e5)
2 // from gir-files (https://github.com/gtk-rs/gir-files @ 22748fa)
3 // DO NOT EDIT
4 
5 extern crate libhandy_sys;
6 extern crate shell_words;
7 extern crate tempfile;
8 use std::env;
9 use std::error::Error;
10 use std::path::Path;
11 use std::mem::{align_of, size_of};
12 use std::process::Command;
13 use std::str;
14 use tempfile::Builder;
15 use libhandy_sys::*;
16 
17 static PACKAGES: &[&str] = &["libhandy-0.0"];
18 
19 #[derive(Clone, Debug)]
20 struct Compiler {
21     pub args: Vec<String>,
22 }
23 
24 impl Compiler {
new() -> Result<Compiler, Box<dyn Error>>25     pub fn new() -> Result<Compiler, Box<dyn Error>> {
26         let mut args = get_var("CC", "cc")?;
27         args.push("-Wno-deprecated-declarations".to_owned());
28         // For %z support in printf when using MinGW.
29         args.push("-D__USE_MINGW_ANSI_STDIO".to_owned());
30         args.extend(get_var("CFLAGS", "")?);
31         args.extend(get_var("CPPFLAGS", "")?);
32         args.extend(pkg_config_cflags(PACKAGES)?);
33         Ok(Compiler { args })
34     }
35 
define<'a, V: Into<Option<&'a str>>>(&mut self, var: &str, val: V)36     pub fn define<'a, V: Into<Option<&'a str>>>(&mut self, var: &str, val: V) {
37         let arg = match val.into() {
38             None => format!("-D{}", var),
39             Some(val) => format!("-D{}={}", var, val),
40         };
41         self.args.push(arg);
42     }
43 
compile(&self, src: &Path, out: &Path) -> Result<(), Box<dyn Error>>44     pub fn compile(&self, src: &Path, out: &Path) -> Result<(), Box<dyn Error>> {
45         let mut cmd = self.to_command();
46         cmd.arg(src);
47         cmd.arg("-o");
48         cmd.arg(out);
49         let status = cmd.spawn()?.wait()?;
50         if !status.success() {
51             return Err(format!("compilation command {:?} failed, {}",
52                                &cmd, status).into());
53         }
54         Ok(())
55     }
56 
to_command(&self) -> Command57     fn to_command(&self) -> Command {
58         let mut cmd = Command::new(&self.args[0]);
59         cmd.args(&self.args[1..]);
60         cmd
61     }
62 }
63 
get_var(name: &str, default: &str) -> Result<Vec<String>, Box<dyn Error>>64 fn get_var(name: &str, default: &str) -> Result<Vec<String>, Box<dyn Error>> {
65     match env::var(name) {
66         Ok(value) => Ok(shell_words::split(&value)?),
67         Err(env::VarError::NotPresent) => Ok(shell_words::split(default)?),
68         Err(err) => Err(format!("{} {}", name, err).into()),
69     }
70 }
71 
pkg_config_cflags(packages: &[&str]) -> Result<Vec<String>, Box<dyn Error>>72 fn pkg_config_cflags(packages: &[&str]) -> Result<Vec<String>, Box<dyn Error>> {
73     if packages.is_empty() {
74         return Ok(Vec::new());
75     }
76     let mut cmd = Command::new("pkg-config");
77     cmd.arg("--cflags");
78     cmd.args(packages);
79     let out = cmd.output()?;
80     if !out.status.success() {
81         return Err(format!("command {:?} returned {}",
82                            &cmd, out.status).into());
83     }
84     let stdout = str::from_utf8(&out.stdout)?;
85     Ok(shell_words::split(stdout.trim())?)
86 }
87 
88 
89 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
90 struct Layout {
91     size: usize,
92     alignment: usize,
93 }
94 
95 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
96 struct Results {
97     /// Number of successfully completed tests.
98     passed: usize,
99     /// Total number of failed tests (including those that failed to compile).
100     failed: usize,
101     /// Number of tests that failed to compile.
102     failed_to_compile: usize,
103 }
104 
105 impl Results {
record_passed(&mut self)106     fn record_passed(&mut self) {
107         self.passed += 1;
108     }
record_failed(&mut self)109     fn record_failed(&mut self) {
110         self.failed += 1;
111     }
record_failed_to_compile(&mut self)112     fn record_failed_to_compile(&mut self) {
113         self.failed += 1;
114         self.failed_to_compile += 1;
115     }
summary(&self) -> String116     fn summary(&self) -> String {
117         format!(
118             "{} passed; {} failed (compilation errors: {})",
119             self.passed,
120             self.failed,
121             self.failed_to_compile)
122     }
expect_total_success(&self)123     fn expect_total_success(&self) {
124         if self.failed == 0 {
125             println!("OK: {}", self.summary());
126         } else {
127             panic!("FAILED: {}", self.summary());
128         };
129     }
130 }
131 
132 #[test]
cross_validate_constants_with_c()133 fn cross_validate_constants_with_c() {
134     let tmpdir = Builder::new().prefix("abi").tempdir().expect("temporary directory");
135     let cc = Compiler::new().expect("configured compiler");
136 
137     assert_eq!("1",
138                get_c_value(tmpdir.path(), &cc, "1").expect("C constant"),
139                "failed to obtain correct constant value for 1");
140 
141     let mut results : Results = Default::default();
142     for (i, &(name, rust_value)) in RUST_CONSTANTS.iter().enumerate() {
143         match get_c_value(tmpdir.path(), &cc, name) {
144             Err(e) => {
145                 results.record_failed_to_compile();
146                 eprintln!("{}", e);
147             },
148             Ok(ref c_value) => {
149                 if rust_value == c_value {
150                     results.record_passed();
151                 } else {
152                     results.record_failed();
153                     eprintln!("Constant value mismatch for {}\nRust: {:?}\nC:    {:?}",
154                               name, rust_value, c_value);
155                 }
156             }
157         };
158         if (i + 1) % 25 == 0 {
159             println!("constants ... {}", results.summary());
160         }
161     }
162     results.expect_total_success();
163 }
164 
165 #[test]
cross_validate_layout_with_c()166 fn cross_validate_layout_with_c() {
167     let tmpdir = Builder::new().prefix("abi").tempdir().expect("temporary directory");
168     let cc = Compiler::new().expect("configured compiler");
169 
170     assert_eq!(Layout {size: 1, alignment: 1},
171                get_c_layout(tmpdir.path(), &cc, "char").expect("C layout"),
172                "failed to obtain correct layout for char type");
173 
174     let mut results : Results = Default::default();
175     for (i, &(name, rust_layout)) in RUST_LAYOUTS.iter().enumerate() {
176         match get_c_layout(tmpdir.path(), &cc, name) {
177             Err(e) => {
178                 results.record_failed_to_compile();
179                 eprintln!("{}", e);
180             },
181             Ok(c_layout) => {
182                 if rust_layout == c_layout {
183                     results.record_passed();
184                 } else {
185                     results.record_failed();
186                     eprintln!("Layout mismatch for {}\nRust: {:?}\nC:    {:?}",
187                               name, rust_layout, &c_layout);
188                 }
189             }
190         };
191         if (i + 1) % 25 == 0 {
192             println!("layout    ... {}", results.summary());
193         }
194     }
195     results.expect_total_success();
196 }
197 
get_c_layout(dir: &Path, cc: &Compiler, name: &str) -> Result<Layout, Box<dyn Error>>198 fn get_c_layout(dir: &Path, cc: &Compiler, name: &str) -> Result<Layout, Box<dyn Error>> {
199     let exe = dir.join("layout");
200     let mut cc = cc.clone();
201     cc.define("ABI_TYPE_NAME", name);
202     cc.compile(Path::new("tests/layout.c"), &exe)?;
203 
204     let mut abi_cmd = Command::new(exe);
205     let output = abi_cmd.output()?;
206     if !output.status.success() {
207         return Err(format!("command {:?} failed, {:?}",
208                            &abi_cmd, &output).into());
209     }
210 
211     let stdout = str::from_utf8(&output.stdout)?;
212     let mut words = stdout.trim().split_whitespace();
213     let size = words.next().unwrap().parse().unwrap();
214     let alignment = words.next().unwrap().parse().unwrap();
215     Ok(Layout {size, alignment})
216 }
217 
get_c_value(dir: &Path, cc: &Compiler, name: &str) -> Result<String, Box<dyn Error>>218 fn get_c_value(dir: &Path, cc: &Compiler, name: &str) -> Result<String, Box<dyn Error>> {
219     let exe = dir.join("constant");
220     let mut cc = cc.clone();
221     cc.define("ABI_CONSTANT_NAME", name);
222     cc.compile(Path::new("tests/constant.c"), &exe)?;
223 
224     let mut abi_cmd = Command::new(exe);
225     let output = abi_cmd.output()?;
226     if !output.status.success() {
227         return Err(format!("command {:?} failed, {:?}",
228                            &abi_cmd, &output).into());
229     }
230 
231     let output = str::from_utf8(&output.stdout)?.trim();
232     if !output.starts_with("###gir test###") ||
233        !output.ends_with("###gir test###") {
234         return Err(format!("command {:?} return invalid output, {:?}",
235                            &abi_cmd, &output).into());
236     }
237 
238     Ok(String::from(&output[14..(output.len() - 14)]))
239 }
240 
241 const RUST_LAYOUTS: &[(&str, Layout)] = &[
242     ("HdyActionRow", Layout {size: size_of::<HdyActionRow>(), alignment: align_of::<HdyActionRow>()}),
243     ("HdyActionRowClass", Layout {size: size_of::<HdyActionRowClass>(), alignment: align_of::<HdyActionRowClass>()}),
244     ("HdyArrows", Layout {size: size_of::<HdyArrows>(), alignment: align_of::<HdyArrows>()}),
245     ("HdyArrowsClass", Layout {size: size_of::<HdyArrowsClass>(), alignment: align_of::<HdyArrowsClass>()}),
246     ("HdyArrowsDirection", Layout {size: size_of::<HdyArrowsDirection>(), alignment: align_of::<HdyArrowsDirection>()}),
247     ("HdyCenteringPolicy", Layout {size: size_of::<HdyCenteringPolicy>(), alignment: align_of::<HdyCenteringPolicy>()}),
248     ("HdyColumnClass", Layout {size: size_of::<HdyColumnClass>(), alignment: align_of::<HdyColumnClass>()}),
249     ("HdyComboRow", Layout {size: size_of::<HdyComboRow>(), alignment: align_of::<HdyComboRow>()}),
250     ("HdyComboRowClass", Layout {size: size_of::<HdyComboRowClass>(), alignment: align_of::<HdyComboRowClass>()}),
251     ("HdyDialer", Layout {size: size_of::<HdyDialer>(), alignment: align_of::<HdyDialer>()}),
252     ("HdyDialerButton", Layout {size: size_of::<HdyDialerButton>(), alignment: align_of::<HdyDialerButton>()}),
253     ("HdyDialerButtonClass", Layout {size: size_of::<HdyDialerButtonClass>(), alignment: align_of::<HdyDialerButtonClass>()}),
254     ("HdyDialerClass", Layout {size: size_of::<HdyDialerClass>(), alignment: align_of::<HdyDialerClass>()}),
255     ("HdyDialerCycleButton", Layout {size: size_of::<HdyDialerCycleButton>(), alignment: align_of::<HdyDialerCycleButton>()}),
256     ("HdyDialerCycleButtonClass", Layout {size: size_of::<HdyDialerCycleButtonClass>(), alignment: align_of::<HdyDialerCycleButtonClass>()}),
257     ("HdyDialog", Layout {size: size_of::<HdyDialog>(), alignment: align_of::<HdyDialog>()}),
258     ("HdyDialogClass", Layout {size: size_of::<HdyDialogClass>(), alignment: align_of::<HdyDialogClass>()}),
259     ("HdyEnumValueObjectClass", Layout {size: size_of::<HdyEnumValueObjectClass>(), alignment: align_of::<HdyEnumValueObjectClass>()}),
260     ("HdyExpanderRow", Layout {size: size_of::<HdyExpanderRow>(), alignment: align_of::<HdyExpanderRow>()}),
261     ("HdyExpanderRowClass", Layout {size: size_of::<HdyExpanderRowClass>(), alignment: align_of::<HdyExpanderRowClass>()}),
262     ("HdyFold", Layout {size: size_of::<HdyFold>(), alignment: align_of::<HdyFold>()}),
263     ("HdyHeaderBar", Layout {size: size_of::<HdyHeaderBar>(), alignment: align_of::<HdyHeaderBar>()}),
264     ("HdyHeaderBarClass", Layout {size: size_of::<HdyHeaderBarClass>(), alignment: align_of::<HdyHeaderBarClass>()}),
265     ("HdyHeaderGroup", Layout {size: size_of::<HdyHeaderGroup>(), alignment: align_of::<HdyHeaderGroup>()}),
266     ("HdyHeaderGroupClass", Layout {size: size_of::<HdyHeaderGroupClass>(), alignment: align_of::<HdyHeaderGroupClass>()}),
267     ("HdyKeypad", Layout {size: size_of::<HdyKeypad>(), alignment: align_of::<HdyKeypad>()}),
268     ("HdyKeypadClass", Layout {size: size_of::<HdyKeypadClass>(), alignment: align_of::<HdyKeypadClass>()}),
269     ("HdyLeaflet", Layout {size: size_of::<HdyLeaflet>(), alignment: align_of::<HdyLeaflet>()}),
270     ("HdyLeafletChildTransitionType", Layout {size: size_of::<HdyLeafletChildTransitionType>(), alignment: align_of::<HdyLeafletChildTransitionType>()}),
271     ("HdyLeafletClass", Layout {size: size_of::<HdyLeafletClass>(), alignment: align_of::<HdyLeafletClass>()}),
272     ("HdyLeafletModeTransitionType", Layout {size: size_of::<HdyLeafletModeTransitionType>(), alignment: align_of::<HdyLeafletModeTransitionType>()}),
273     ("HdyLeafletTransitionType", Layout {size: size_of::<HdyLeafletTransitionType>(), alignment: align_of::<HdyLeafletTransitionType>()}),
274     ("HdyPaginatorClass", Layout {size: size_of::<HdyPaginatorClass>(), alignment: align_of::<HdyPaginatorClass>()}),
275     ("HdyPaginatorIndicatorStyle", Layout {size: size_of::<HdyPaginatorIndicatorStyle>(), alignment: align_of::<HdyPaginatorIndicatorStyle>()}),
276     ("HdyPreferencesGroup", Layout {size: size_of::<HdyPreferencesGroup>(), alignment: align_of::<HdyPreferencesGroup>()}),
277     ("HdyPreferencesGroupClass", Layout {size: size_of::<HdyPreferencesGroupClass>(), alignment: align_of::<HdyPreferencesGroupClass>()}),
278     ("HdyPreferencesPage", Layout {size: size_of::<HdyPreferencesPage>(), alignment: align_of::<HdyPreferencesPage>()}),
279     ("HdyPreferencesPageClass", Layout {size: size_of::<HdyPreferencesPageClass>(), alignment: align_of::<HdyPreferencesPageClass>()}),
280     ("HdyPreferencesRow", Layout {size: size_of::<HdyPreferencesRow>(), alignment: align_of::<HdyPreferencesRow>()}),
281     ("HdyPreferencesRowClass", Layout {size: size_of::<HdyPreferencesRowClass>(), alignment: align_of::<HdyPreferencesRowClass>()}),
282     ("HdyPreferencesWindow", Layout {size: size_of::<HdyPreferencesWindow>(), alignment: align_of::<HdyPreferencesWindow>()}),
283     ("HdyPreferencesWindowClass", Layout {size: size_of::<HdyPreferencesWindowClass>(), alignment: align_of::<HdyPreferencesWindowClass>()}),
284     ("HdySearchBar", Layout {size: size_of::<HdySearchBar>(), alignment: align_of::<HdySearchBar>()}),
285     ("HdySearchBarClass", Layout {size: size_of::<HdySearchBarClass>(), alignment: align_of::<HdySearchBarClass>()}),
286     ("HdySqueezer", Layout {size: size_of::<HdySqueezer>(), alignment: align_of::<HdySqueezer>()}),
287     ("HdySqueezerClass", Layout {size: size_of::<HdySqueezerClass>(), alignment: align_of::<HdySqueezerClass>()}),
288     ("HdySqueezerTransitionType", Layout {size: size_of::<HdySqueezerTransitionType>(), alignment: align_of::<HdySqueezerTransitionType>()}),
289     ("HdySwipeGroupClass", Layout {size: size_of::<HdySwipeGroupClass>(), alignment: align_of::<HdySwipeGroupClass>()}),
290     ("HdySwipeableInterface", Layout {size: size_of::<HdySwipeableInterface>(), alignment: align_of::<HdySwipeableInterface>()}),
291     ("HdyTitleBarClass", Layout {size: size_of::<HdyTitleBarClass>(), alignment: align_of::<HdyTitleBarClass>()}),
292     ("HdyValueObjectClass", Layout {size: size_of::<HdyValueObjectClass>(), alignment: align_of::<HdyValueObjectClass>()}),
293     ("HdyViewSwitcher", Layout {size: size_of::<HdyViewSwitcher>(), alignment: align_of::<HdyViewSwitcher>()}),
294     ("HdyViewSwitcherBar", Layout {size: size_of::<HdyViewSwitcherBar>(), alignment: align_of::<HdyViewSwitcherBar>()}),
295     ("HdyViewSwitcherBarClass", Layout {size: size_of::<HdyViewSwitcherBarClass>(), alignment: align_of::<HdyViewSwitcherBarClass>()}),
296     ("HdyViewSwitcherClass", Layout {size: size_of::<HdyViewSwitcherClass>(), alignment: align_of::<HdyViewSwitcherClass>()}),
297     ("HdyViewSwitcherPolicy", Layout {size: size_of::<HdyViewSwitcherPolicy>(), alignment: align_of::<HdyViewSwitcherPolicy>()}),
298 ];
299 
300 const RUST_CONSTANTS: &[(&str, &str)] = &[
301     ("(gint) HDY_ARROWS_DIRECTION_DOWN", "1"),
302     ("(gint) HDY_ARROWS_DIRECTION_LEFT", "2"),
303     ("(gint) HDY_ARROWS_DIRECTION_RIGHT", "3"),
304     ("(gint) HDY_ARROWS_DIRECTION_UP", "0"),
305     ("(gint) HDY_CENTERING_POLICY_LOOSE", "0"),
306     ("(gint) HDY_CENTERING_POLICY_STRICT", "1"),
307     ("(gint) HDY_FOLD_FOLDED", "1"),
308     ("(gint) HDY_FOLD_UNFOLDED", "0"),
309     ("(gint) HDY_LEAFLET_CHILD_TRANSITION_TYPE_CROSSFADE", "1"),
310     ("(gint) HDY_LEAFLET_CHILD_TRANSITION_TYPE_NONE", "0"),
311     ("(gint) HDY_LEAFLET_CHILD_TRANSITION_TYPE_OVER", "3"),
312     ("(gint) HDY_LEAFLET_CHILD_TRANSITION_TYPE_SLIDE", "2"),
313     ("(gint) HDY_LEAFLET_CHILD_TRANSITION_TYPE_UNDER", "4"),
314     ("(gint) HDY_LEAFLET_MODE_TRANSITION_TYPE_NONE", "0"),
315     ("(gint) HDY_LEAFLET_MODE_TRANSITION_TYPE_SLIDE", "1"),
316     ("(gint) HDY_LEAFLET_TRANSITION_TYPE_NONE", "0"),
317     ("(gint) HDY_LEAFLET_TRANSITION_TYPE_OVER", "2"),
318     ("(gint) HDY_LEAFLET_TRANSITION_TYPE_SLIDE", "1"),
319     ("(gint) HDY_LEAFLET_TRANSITION_TYPE_UNDER", "3"),
320     ("(gint) HDY_PAGINATOR_INDICATOR_STYLE_DOTS", "1"),
321     ("(gint) HDY_PAGINATOR_INDICATOR_STYLE_LINES", "2"),
322     ("(gint) HDY_PAGINATOR_INDICATOR_STYLE_NONE", "0"),
323     ("(gint) HDY_SQUEEZER_TRANSITION_TYPE_CROSSFADE", "1"),
324     ("(gint) HDY_SQUEEZER_TRANSITION_TYPE_NONE", "0"),
325     ("(gint) HDY_VIEW_SWITCHER_POLICY_AUTO", "0"),
326     ("(gint) HDY_VIEW_SWITCHER_POLICY_NARROW", "1"),
327     ("(gint) HDY_VIEW_SWITCHER_POLICY_WIDE", "2"),
328 ];
329 
330 
331