1 //! Tests for `FromGenerics`, and - indirectly - `FromGenericParam`.
2 //! These tests assume `FromTypeParam` is working and only look at whether the wrappers for magic
3 //! fields are working as expected.
4 
5 #[macro_use]
6 extern crate darling;
7 extern crate syn;
8 
9 use darling::ast::{self, GenericParamExt};
10 use darling::util::{Ignored, WithOriginal};
11 use darling::{FromDeriveInput, Result};
12 
13 #[derive(FromDeriveInput)]
14 #[darling(attributes(lorem))]
15 struct MyReceiver {
16     pub ident: syn::Ident,
17     pub generics: ast::Generics<ast::GenericParam<MyTypeParam>>,
18 }
19 
20 #[derive(FromTypeParam)]
21 #[darling(attributes(lorem))]
22 struct MyTypeParam {
23     pub ident: syn::Ident,
24     #[darling(default)]
25     pub foo: bool,
26     #[darling(default)]
27     pub bar: Option<String>,
28 }
29 
fdi<T: FromDeriveInput>(src: &str) -> Result<T>30 fn fdi<T: FromDeriveInput>(src: &str) -> Result<T> {
31     FromDeriveInput::from_derive_input(&syn::parse_str(src).expect("Source parses"))
32 }
33 
34 /// Verify that `ast::Generics` is populated correctly when there is no generics declaration
35 #[test]
no_generics()36 fn no_generics() {
37     let rec: MyReceiver = fdi("struct Baz;").expect("Input is well-formed");
38     assert!(rec.generics.where_clause.is_none());
39     assert_eq!(rec.generics.params.len(), 0);
40 }
41 
42 #[test]
expand_some()43 fn expand_some() {
44     let rec: MyReceiver = fdi(r#"
45         struct Baz<
46             'a,
47             #[lorem(foo)] T,
48             #[lorem(bar = "x")] U: Eq + ?Sized
49         >(&'a T, U);
50     "#)
51         .expect("Input is well-formed");
52     assert!(rec.generics.where_clause.is_none());
53 
54     // Make sure we've preserved the lifetime def, though we don't do anything with it.
55     assert!(rec.generics.params[0].as_lifetime_def().is_some());
56 
57     let mut ty_param_iter = rec.generics.type_params();
58 
59     let first = ty_param_iter
60         .next()
61         .expect("type_params should not be empty");
62     assert!(first.bar.is_none());
63     assert!(first.foo);
64     assert_eq!(first.ident, "T");
65 
66     let second = ty_param_iter
67         .next()
68         .expect("type_params should have a second value");
69     assert_eq!(
70         second
71             .bar
72             .as_ref()
73             .expect("Second type param should set bar"),
74         "x"
75     );
76     assert_eq!(second.foo, false);
77     assert_eq!(second.ident, "U");
78 }
79 
80 /// Verify ≤0.4.1 behavior - where `generics` had to be `syn::Generics` - keeps working.
81 #[test]
passthrough()82 fn passthrough() {
83     #[derive(FromDeriveInput)]
84     struct PassthroughReceiver {
85         pub generics: syn::Generics,
86     }
87 
88     let rec: PassthroughReceiver = fdi(r#"
89         struct Baz<
90             'a,
91             #[lorem(foo)] T,
92             #[lorem(bar = "x")] U: Eq + ?Sized
93         >(&'a T, U);
94     "#)
95         .expect("Input is well-formed");
96 
97     let mut type_param_iter = rec.generics.type_params();
98     assert!(type_param_iter.next().is_some());
99 }
100 
101 /// Verify that `where_clause` is passed through when it exists.
102 /// As of 0.4.1, there is no `FromWhereClause` trait, so other types aren't supported
103 /// for that field.
104 #[test]
where_clause()105 fn where_clause() {
106     let rec: MyReceiver = fdi(r#"
107         struct Baz<
108             'a,
109             #[lorem(foo)] T,
110             #[lorem(bar = "x")] U: Eq + ?Sized
111         >(&'a T, U) where T: Into<String>;
112     "#)
113         .expect("Input is well-formed");
114 
115     assert!(rec.generics.where_clause.is_some());
116 }
117 
118 /// Test that `WithOriginal` works for generics.
119 #[test]
with_original()120 fn with_original() {
121     #[derive(FromDeriveInput)]
122     struct WorigReceiver {
123         generics: WithOriginal<ast::Generics<ast::GenericParam<MyTypeParam>>, syn::Generics>,
124     }
125 
126     let rec: WorigReceiver = fdi(r#"
127         struct Baz<
128             'a,
129             #[lorem(foo)] T,
130             #[lorem(bar = "x")] U: Eq + ?Sized
131         >(&'a T, U) where T: Into<String>;
132     "#)
133         .expect("Input is well-formed");
134 
135     // Make sure we haven't lost anything in the conversion
136     assert_eq!(rec.generics.parsed.params.len(), 3);
137     assert_eq!(
138         rec.generics
139             .original
140             .params
141             .iter()
142             .collect::<Vec<_>>()
143             .len(),
144         3
145     );
146 
147     let parsed_t: &MyTypeParam = rec.generics.parsed.params[1]
148         .as_type_param()
149         .expect("Second argument should be type param");
150 
151     // Make sure the first type param in each case is T
152     assert_eq!(parsed_t.ident, "T");
153     assert_eq!(
154         rec.generics
155             .original
156             .type_params()
157             .next()
158             .expect("First type param should exist")
159             .ident,
160         "T"
161     );
162 
163     // Make sure we actually parsed the first type param
164     assert!(parsed_t.foo);
165     assert!(parsed_t.bar.is_none());
166 }
167 
168 /// Make sure generics can be ignored
169 #[test]
ignored()170 fn ignored() {
171     #[derive(FromDeriveInput)]
172     struct IgnoredReceiver {
173         generics: Ignored,
174     }
175 
176     let rec: IgnoredReceiver = fdi(r#"
177         struct Baz<
178             'a,
179             #[lorem(foo)] T,
180             #[lorem(bar = "x")] U: Eq + ?Sized
181         >(&'a T, U) where T: Into<String>;
182     "#)
183         .expect("Input is well-formed");
184 
185     assert_eq!(Ignored, rec.generics);
186 }
187