]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/clean/cfg/tests.rs
Rollup merge of #106499 - lyming2007:issue-105946-fix, r=estebank
[rust.git] / src / librustdoc / clean / cfg / tests.rs
1 use super::*;
2
3 use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle};
4 use rustc_span::create_default_session_globals_then;
5 use rustc_span::symbol::{kw, Ident, Symbol};
6 use rustc_span::DUMMY_SP;
7
8 fn word_cfg(s: &str) -> Cfg {
9     Cfg::Cfg(Symbol::intern(s), None)
10 }
11
12 fn name_value_cfg(name: &str, value: &str) -> Cfg {
13     Cfg::Cfg(Symbol::intern(name), Some(Symbol::intern(value)))
14 }
15
16 fn dummy_meta_item_word(name: &str) -> MetaItem {
17     MetaItem {
18         path: Path::from_ident(Ident::from_str(name)),
19         kind: MetaItemKind::Word,
20         span: DUMMY_SP,
21     }
22 }
23
24 fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem {
25     let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP };
26     MetaItem {
27         path: Path::from_ident(Ident::from_str(name)),
28         kind: MetaItemKind::NameValue(lit),
29         span: DUMMY_SP,
30     }
31 }
32
33 macro_rules! dummy_meta_item_list {
34     ($name:ident, [$($list:ident),* $(,)?]) => {
35         MetaItem {
36             path: Path::from_ident(Ident::from_str(stringify!($name))),
37             kind: MetaItemKind::List(vec![
38                 $(
39                     NestedMetaItem::MetaItem(
40                         dummy_meta_item_word(stringify!($list)),
41                     ),
42                 )*
43             ]),
44             span: DUMMY_SP,
45         }
46     };
47
48     ($name:ident, [$($list:expr),* $(,)?]) => {
49         MetaItem {
50             path: Path::from_ident(Ident::from_str(stringify!($name))),
51             kind: MetaItemKind::List(vec![
52                 $(
53                     NestedMetaItem::MetaItem($list),
54                 )*
55             ]),
56             span: DUMMY_SP,
57         }
58     };
59 }
60
61 #[test]
62 fn test_cfg_not() {
63     create_default_session_globals_then(|| {
64         assert_eq!(!Cfg::False, Cfg::True);
65         assert_eq!(!Cfg::True, Cfg::False);
66         assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test"))));
67         assert_eq!(
68             !Cfg::All(vec![word_cfg("a"), word_cfg("b")]),
69             Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")])))
70         );
71         assert_eq!(
72             !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]),
73             Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")])))
74         );
75         assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test"));
76     })
77 }
78
79 #[test]
80 fn test_cfg_and() {
81     create_default_session_globals_then(|| {
82         let mut x = Cfg::False;
83         x &= Cfg::True;
84         assert_eq!(x, Cfg::False);
85
86         x = word_cfg("test");
87         x &= Cfg::False;
88         assert_eq!(x, Cfg::False);
89
90         x = word_cfg("test2");
91         x &= Cfg::True;
92         assert_eq!(x, word_cfg("test2"));
93
94         x = Cfg::True;
95         x &= word_cfg("test3");
96         assert_eq!(x, word_cfg("test3"));
97
98         x &= word_cfg("test3");
99         assert_eq!(x, word_cfg("test3"));
100
101         x &= word_cfg("test4");
102         assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")]));
103
104         x &= word_cfg("test4");
105         assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")]));
106
107         x &= word_cfg("test5");
108         assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")]));
109
110         x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]);
111         assert_eq!(
112             x,
113             Cfg::All(vec![
114                 word_cfg("test3"),
115                 word_cfg("test4"),
116                 word_cfg("test5"),
117                 word_cfg("test6"),
118                 word_cfg("test7"),
119             ])
120         );
121
122         x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]);
123         assert_eq!(
124             x,
125             Cfg::All(vec![
126                 word_cfg("test3"),
127                 word_cfg("test4"),
128                 word_cfg("test5"),
129                 word_cfg("test6"),
130                 word_cfg("test7"),
131             ])
132         );
133
134         let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]);
135         y &= x;
136         assert_eq!(
137             y,
138             Cfg::All(vec![
139                 word_cfg("test3"),
140                 word_cfg("test4"),
141                 word_cfg("test5"),
142                 word_cfg("test6"),
143                 word_cfg("test7"),
144                 Cfg::Any(vec![word_cfg("a"), word_cfg("b")]),
145             ])
146         );
147
148         let mut z = word_cfg("test8");
149         z &= Cfg::All(vec![word_cfg("test9"), word_cfg("test10")]);
150         assert_eq!(z, Cfg::All(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")]));
151
152         let mut z = word_cfg("test11");
153         z &= Cfg::All(vec![word_cfg("test11"), word_cfg("test12")]);
154         assert_eq!(z, Cfg::All(vec![word_cfg("test11"), word_cfg("test12")]));
155
156         assert_eq!(
157             word_cfg("a") & word_cfg("b") & word_cfg("c"),
158             Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")])
159         );
160     })
161 }
162
163 #[test]
164 fn test_cfg_or() {
165     create_default_session_globals_then(|| {
166         let mut x = Cfg::True;
167         x |= Cfg::False;
168         assert_eq!(x, Cfg::True);
169
170         x = word_cfg("test");
171         x |= Cfg::True;
172         assert_eq!(x, word_cfg("test"));
173
174         x = word_cfg("test2");
175         x |= Cfg::False;
176         assert_eq!(x, word_cfg("test2"));
177
178         x = Cfg::False;
179         x |= word_cfg("test3");
180         assert_eq!(x, word_cfg("test3"));
181
182         x |= word_cfg("test3");
183         assert_eq!(x, word_cfg("test3"));
184
185         x |= word_cfg("test4");
186         assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")]));
187
188         x |= word_cfg("test4");
189         assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")]));
190
191         x |= word_cfg("test5");
192         assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")]));
193
194         x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]);
195         assert_eq!(
196             x,
197             Cfg::Any(vec![
198                 word_cfg("test3"),
199                 word_cfg("test4"),
200                 word_cfg("test5"),
201                 word_cfg("test6"),
202                 word_cfg("test7"),
203             ])
204         );
205
206         x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]);
207         assert_eq!(
208             x,
209             Cfg::Any(vec![
210                 word_cfg("test3"),
211                 word_cfg("test4"),
212                 word_cfg("test5"),
213                 word_cfg("test6"),
214                 word_cfg("test7"),
215             ])
216         );
217
218         let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]);
219         y |= x;
220         assert_eq!(
221             y,
222             Cfg::Any(vec![
223                 word_cfg("test3"),
224                 word_cfg("test4"),
225                 word_cfg("test5"),
226                 word_cfg("test6"),
227                 word_cfg("test7"),
228                 Cfg::All(vec![word_cfg("a"), word_cfg("b")]),
229             ])
230         );
231
232         let mut z = word_cfg("test8");
233         z |= Cfg::Any(vec![word_cfg("test9"), word_cfg("test10")]);
234         assert_eq!(z, Cfg::Any(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")]));
235
236         let mut z = word_cfg("test11");
237         z |= Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")]);
238         assert_eq!(z, Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")]));
239
240         assert_eq!(
241             word_cfg("a") | word_cfg("b") | word_cfg("c"),
242             Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")])
243         );
244     })
245 }
246
247 #[test]
248 fn test_parse_ok() {
249     create_default_session_globals_then(|| {
250         let mi = dummy_meta_item_word("all");
251         assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
252
253         let done = Symbol::intern("done");
254         let mi = dummy_meta_item_name_value("all", done, LitKind::Str(done, StrStyle::Cooked));
255         assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done")));
256
257         let mi = dummy_meta_item_list!(all, [a, b]);
258         assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b")));
259
260         let mi = dummy_meta_item_list!(any, [a, b]);
261         assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b")));
262
263         let mi = dummy_meta_item_list!(not, [a]);
264         assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a")));
265
266         let mi = dummy_meta_item_list!(
267             not,
268             [dummy_meta_item_list!(
269                 any,
270                 [dummy_meta_item_word("a"), dummy_meta_item_list!(all, [b, c]),]
271             ),]
272         );
273         assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c")))));
274
275         let mi = dummy_meta_item_list!(all, [a, b, c]);
276         assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c")));
277     })
278 }
279
280 #[test]
281 fn test_parse_err() {
282     create_default_session_globals_then(|| {
283         let mi = dummy_meta_item_name_value("foo", kw::False, LitKind::Bool(false));
284         assert!(Cfg::parse(&mi).is_err());
285
286         let mi = dummy_meta_item_list!(not, [a, b]);
287         assert!(Cfg::parse(&mi).is_err());
288
289         let mi = dummy_meta_item_list!(not, []);
290         assert!(Cfg::parse(&mi).is_err());
291
292         let mi = dummy_meta_item_list!(foo, []);
293         assert!(Cfg::parse(&mi).is_err());
294
295         let mi = dummy_meta_item_list!(
296             all,
297             [dummy_meta_item_list!(foo, []), dummy_meta_item_word("b"),]
298         );
299         assert!(Cfg::parse(&mi).is_err());
300
301         let mi = dummy_meta_item_list!(
302             any,
303             [dummy_meta_item_word("a"), dummy_meta_item_list!(foo, []),]
304         );
305         assert!(Cfg::parse(&mi).is_err());
306
307         let mi = dummy_meta_item_list!(not, [dummy_meta_item_list!(foo, []),]);
308         assert!(Cfg::parse(&mi).is_err());
309     })
310 }
311
312 #[test]
313 fn test_render_short_html() {
314     create_default_session_globals_then(|| {
315         assert_eq!(word_cfg("unix").render_short_html(), "Unix");
316         assert_eq!(name_value_cfg("target_os", "macos").render_short_html(), "macOS");
317         assert_eq!(name_value_cfg("target_pointer_width", "16").render_short_html(), "16-bit");
318         assert_eq!(name_value_cfg("target_endian", "little").render_short_html(), "Little-endian");
319         assert_eq!((!word_cfg("windows")).render_short_html(), "Non-Windows");
320         assert_eq!(
321             (word_cfg("unix") & word_cfg("windows")).render_short_html(),
322             "Unix and Windows"
323         );
324         assert_eq!((word_cfg("unix") | word_cfg("windows")).render_short_html(), "Unix or Windows");
325         assert_eq!(
326             (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions"))
327                 .render_short_html(),
328             "Unix and Windows and debug-assertions enabled"
329         );
330         assert_eq!(
331             (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))
332                 .render_short_html(),
333             "Unix or Windows or debug-assertions enabled"
334         );
335         assert_eq!(
336             (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")))
337                 .render_short_html(),
338             "Neither Unix nor Windows nor debug-assertions enabled"
339         );
340         assert_eq!(
341             ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64"))
342                 | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")))
343             .render_short_html(),
344             "Unix and x86-64, or Windows and 64-bit"
345         );
346         assert_eq!(
347             (!(word_cfg("unix") & word_cfg("windows"))).render_short_html(),
348             "Not (Unix and Windows)"
349         );
350         assert_eq!(
351             ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix"))
352                 .render_short_html(),
353             "(Debug-assertions enabled or Windows) and Unix"
354         );
355         assert_eq!(
356             name_value_cfg("target_feature", "sse2").render_short_html(),
357             "<code>sse2</code>"
358         );
359         assert_eq!(
360             (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2"))
361                 .render_short_html(),
362             "x86-64 and <code>sse2</code>"
363         );
364     })
365 }
366
367 #[test]
368 fn test_render_long_html() {
369     create_default_session_globals_then(|| {
370         assert_eq!(word_cfg("unix").render_long_html(), "Available on <strong>Unix</strong> only.");
371         assert_eq!(
372             name_value_cfg("target_os", "macos").render_long_html(),
373             "Available on <strong>macOS</strong> only."
374         );
375         assert_eq!(
376             name_value_cfg("target_os", "wasi").render_long_html(),
377             "Available on <strong>WASI</strong> only."
378         );
379         assert_eq!(
380             name_value_cfg("target_pointer_width", "16").render_long_html(),
381             "Available on <strong>16-bit</strong> only."
382         );
383         assert_eq!(
384             name_value_cfg("target_endian", "little").render_long_html(),
385             "Available on <strong>little-endian</strong> only."
386         );
387         assert_eq!(
388             (!word_cfg("windows")).render_long_html(),
389             "Available on <strong>non-Windows</strong> only."
390         );
391         assert_eq!(
392             (word_cfg("unix") & word_cfg("windows")).render_long_html(),
393             "Available on <strong>Unix and Windows</strong> only."
394         );
395         assert_eq!(
396             (word_cfg("unix") | word_cfg("windows")).render_long_html(),
397             "Available on <strong>Unix or Windows</strong> only."
398         );
399         assert_eq!(
400             (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions"))
401                 .render_long_html(),
402             "Available on <strong>Unix and Windows and debug-assertions enabled</strong> only."
403         );
404         assert_eq!(
405             (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))
406                 .render_long_html(),
407             "Available on <strong>Unix or Windows or debug-assertions enabled</strong> only."
408         );
409         assert_eq!(
410             (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")))
411                 .render_long_html(),
412             "Available on <strong>neither Unix nor Windows nor debug-assertions enabled</strong>."
413         );
414         assert_eq!(
415             ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64"))
416                 | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")))
417             .render_long_html(),
418             "Available on <strong>Unix and x86-64, or Windows and 64-bit</strong> only."
419         );
420         assert_eq!(
421             (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(),
422             "Available on <strong>not (Unix and Windows)</strong>."
423         );
424         assert_eq!(
425             ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix"))
426                 .render_long_html(),
427             "Available on <strong>(debug-assertions enabled or Windows) and Unix</strong> only."
428         );
429         assert_eq!(
430             name_value_cfg("target_feature", "sse2").render_long_html(),
431             "Available with <strong>target feature <code>sse2</code></strong> only."
432         );
433         assert_eq!(
434             (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2"))
435                 .render_long_html(),
436             "Available on <strong>x86-64 and target feature <code>sse2</code></strong> only."
437         );
438     })
439 }
440
441 #[test]
442 fn test_simplify_with() {
443     // This is a tiny subset of things that could be simplified, but it likely covers 90% of
444     // real world usecases well.
445     create_default_session_globals_then(|| {
446         let foo = word_cfg("foo");
447         let bar = word_cfg("bar");
448         let baz = word_cfg("baz");
449         let quux = word_cfg("quux");
450
451         let foobar = Cfg::All(vec![foo.clone(), bar.clone()]);
452         let barbaz = Cfg::All(vec![bar.clone(), baz.clone()]);
453         let foobarbaz = Cfg::All(vec![foo.clone(), bar.clone(), baz.clone()]);
454         let bazquux = Cfg::All(vec![baz.clone(), quux.clone()]);
455
456         // Unrelated cfgs don't affect each other
457         assert_eq!(foo.simplify_with(&bar).as_ref(), Some(&foo));
458         assert_eq!(foobar.simplify_with(&bazquux).as_ref(), Some(&foobar));
459
460         // Identical cfgs are eliminated
461         assert_eq!(foo.simplify_with(&foo), None);
462         assert_eq!(foobar.simplify_with(&foobar), None);
463
464         // Multiple cfgs eliminate a single assumed cfg
465         assert_eq!(foobar.simplify_with(&foo).as_ref(), Some(&bar));
466         assert_eq!(foobar.simplify_with(&bar).as_ref(), Some(&foo));
467
468         // A single cfg is eliminated by multiple assumed cfg containing it
469         assert_eq!(foo.simplify_with(&foobar), None);
470
471         // Multiple cfgs eliminate the matching subset of multiple assumed cfg
472         assert_eq!(foobar.simplify_with(&barbaz).as_ref(), Some(&foo));
473         assert_eq!(foobar.simplify_with(&foobarbaz), None);
474     });
475 }