1 //! Verifies the implementation of the style checker in [style].
2 
3 use style::StyleChecker;
4 
5 pub mod style;
6 
7 #[test]
check_style_accept_correct_module_layout()8 fn check_style_accept_correct_module_layout() {
9     let contents = r#"
10 use core::mem::size_of;
11 pub type foo_t = u32;
12 struct Foo {}
13 pub const FOO: u32 = 0x20000;
14 f! {}
15 extern "C" {}
16 mod foolib;
17 pub use self::foolib::*;
18 "#
19     .to_string();
20 
21     let mut checker = StyleChecker::new();
22     checker.check_string(contents).unwrap();
23     checker.finalize().unwrap();
24 }
25 
26 #[test]
check_style_reject_incorrect_module_layout()27 fn check_style_reject_incorrect_module_layout() {
28     let contents = r#"
29 use core::mem::size_of;
30 pub type foo_t = u32;
31 struct Foo {}
32 pub const FOO: u32 = 0x20000;
33 extern "C" {}
34 f! {}
35 mod foolib;
36 pub use self::foolib::*;
37 "#
38     .to_string();
39 
40     let mut checker = StyleChecker::new();
41     checker.check_string(contents).unwrap();
42     assert!(checker.finalize().is_err());
43 }
44 
45 #[test]
check_style_reject_incorrect_cfg_if_layout()46 fn check_style_reject_incorrect_cfg_if_layout() {
47     let contents = r#"
48 cfg_if! {
49     if #[cfg(foo)] {
50         pub type foo_t = u32;
51         use core::mem::size_of;
52     }
53 }
54 "#
55     .to_string();
56 
57     let mut checker = StyleChecker::new();
58     checker.check_string(contents).unwrap();
59     assert!(checker.finalize().is_err());
60 }
61 
62 #[test]
check_style_accept_cfg_if_branch_resets_state()63 fn check_style_accept_cfg_if_branch_resets_state() {
64     let contents = r#"
65 cfg_if! {
66     if #[cfg(foo)] {
67         use core::mem::size_of;
68         pub type foo_t = u32;
69     } else {
70         use core::mem::align_of;
71     }
72 }
73 "#
74     .to_string();
75 
76     let mut checker = StyleChecker::new();
77     checker.check_string(contents).unwrap();
78     checker.finalize().unwrap();
79 }
80 
81 #[test]
check_style_reject_multiple_f_macros()82 fn check_style_reject_multiple_f_macros() {
83     let contents = r#"
84 f! {}
85 f! {}
86 "#
87     .to_string();
88 
89     let mut checker = StyleChecker::new();
90     checker.check_string(contents).unwrap();
91     assert!(checker.finalize().is_err());
92 }
93 
94 #[test]
check_style_accept_cfg_ignore_target_endian_nested()95 fn check_style_accept_cfg_ignore_target_endian_nested() {
96     let contents = r#"
97 pub struct Foo {
98     #[cfg(target_endian = "little")]
99     pub id: __u16,
100 }
101 "#
102     .to_string();
103 
104     let mut checker = StyleChecker::new();
105     checker.check_string(contents).unwrap();
106     checker.finalize().unwrap();
107 }
108 
109 #[test]
check_style_reject_manual_copy()110 fn check_style_reject_manual_copy() {
111     let contents = r#"
112 #[derive(Copy)]
113 pub struct Foo {}
114 "#
115     .to_string();
116 
117     let mut checker = StyleChecker::new();
118     checker.check_string(contents).unwrap();
119     assert!(checker.finalize().is_err());
120 }
121 
122 #[test]
check_style_reject_manual_clone()123 fn check_style_reject_manual_clone() {
124     let contents = r#"
125 #[derive(Clone)]
126 pub struct Foo {}
127 "#
128     .to_string();
129 
130     let mut checker = StyleChecker::new();
131     checker.check_string(contents).unwrap();
132     assert!(checker.finalize().is_err());
133 }
134 
135 #[test]
check_style_accept_multiple_s_macros_with_disjoint_cfg()136 fn check_style_accept_multiple_s_macros_with_disjoint_cfg() {
137     let contents = r#"
138 // Main `s!`
139 s! {}
140 
141 // These are not supported on a single arch. It doesn't make sense to
142 // duplicate `foo` into every single file except one, so allow this here.
143 #[cfg(not(target_arch = "foo"))]
144 s! { pub struct foo { /* ... */ } }
145 
146 // Similar to the above, no problems here
147 #[cfg(not(target_os = "illumos"))]
148 s! { pub struct bar { /* ... */ } }
149 "#
150     .to_string();
151 
152     let mut checker = StyleChecker::new();
153     checker.check_string(contents).unwrap();
154     checker.finalize().unwrap();
155 }
156 
157 #[test]
check_style_reject_duplicated_s_macro()158 fn check_style_reject_duplicated_s_macro() {
159     let contents = r#"
160 s! {}
161 s! {}
162 "#
163     .to_string();
164 
165     let mut checker = StyleChecker::new();
166     checker.check_string(contents).unwrap();
167     assert!(checker.finalize().is_err());
168 }
169 
170 #[test]
check_style_reject_duplicated_s_macro_cfg()171 fn check_style_reject_duplicated_s_macro_cfg() {
172     let contents = r#"
173 #[cfg(not(target_arch = "foo"))]
174 s! {}
175 
176 #[cfg(not(target_arch = "foo"))]
177 s! {}
178 "#
179     .to_string();
180 
181     let mut checker = StyleChecker::new();
182     checker.check_string(contents).unwrap();
183     assert!(checker.finalize().is_err());
184 }
185 
186 #[test]
check_style_reject_single_positive_s_macro_cfg()187 fn check_style_reject_single_positive_s_macro_cfg() {
188     let contents = r#"
189 // A positive (no `not`) config: reject because this should go into
190 // the relevant file.
191 #[cfg(target_arch = "foo")]
192 s! { pub struct foo { /* ... */ } }
193 "#
194     .to_string();
195 
196     let mut checker = StyleChecker::new();
197     checker.check_string(contents).unwrap();
198     assert!(checker.finalize().is_err());
199 }
200 
201 #[test]
check_style_reject_single_positive_s_macro_cfg_target_os()202 fn check_style_reject_single_positive_s_macro_cfg_target_os() {
203     let contents = r#"
204 // A positive (no `not`) config: reject because this should go into
205 // the relevant file.
206 #[cfg(target_os = "foo")]
207 s! { pub struct foo { /* ... */ } }
208 "#
209     .to_string();
210 
211     let mut checker = StyleChecker::new();
212     checker.check_string(contents).unwrap();
213     assert!(checker.finalize().is_err());
214 }
215 
216 #[test]
check_style_accept_positive_s_macro_any()217 fn check_style_accept_positive_s_macro_any() {
218     let contents = r#"
219 // It's nicer to accept this so that we don't have to duplicate the same struct 3 times.
220 #[cfg(any(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
221 s! { pub struct foo { /* ... */ } }
222 "#
223     .to_string();
224 
225     let mut checker = StyleChecker::new();
226     checker.check_string(contents).unwrap();
227     checker.finalize().unwrap();
228 }
229 
230 #[test]
check_style_accept_positive_s_macro_all()231 fn check_style_accept_positive_s_macro_all() {
232     let contents = r#"
233 #[cfg(all(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
234 s! { pub struct foo { /* ... */ } }
235 "#
236     .to_string();
237 
238     let mut checker = StyleChecker::new();
239     checker.check_string(contents).unwrap();
240     checker.finalize().unwrap();
241 }
242 
243 #[test]
check_style_reject_duplicated_cfg_and_cfg_if()244 fn check_style_reject_duplicated_cfg_and_cfg_if() {
245     let contents = r#"
246 #[cfg(not(target_arch = "foo"))]
247 s! { pub struct foo { /* ... */ } }
248 
249 cfg_if! {
250     if #[cfg(not(target_arch = "foo"))] {
251         s!{ pub struct bar {} }
252     }
253 }
254 "#
255     .to_string();
256 
257     let mut checker = StyleChecker::new();
258     checker.check_string(contents).unwrap();
259     assert!(checker.finalize().is_err());
260 }
261