1 #[macro_use]
2 mod macros;
3 
4 use syn::parse::Parser;
5 use syn::{Attribute, Meta};
6 
7 #[test]
8 fn test_meta_item_word() {
9     let meta = test("#[foo]");
10 
11     snapshot!(meta, @r###"
12     Path(Path {
13         segments: [
14             PathSegment {
15                 ident: "foo",
16                 arguments: None,
17             },
18         ],
19     })
20     "###);
21 }
22 
23 #[test]
24 fn test_meta_item_name_value() {
25     let meta = test("#[foo = 5]");
26 
27     snapshot!(meta, @r###"
28     Meta::NameValue {
29         path: Path {
30             segments: [
31                 PathSegment {
32                     ident: "foo",
33                     arguments: None,
34                 },
35             ],
36         },
37         lit: 5,
38     }
39     "###);
40 }
41 
42 #[test]
43 fn test_meta_item_bool_value() {
44     let meta = test("#[foo = true]");
45 
46     snapshot!(meta, @r###"
47     Meta::NameValue {
48         path: Path {
49             segments: [
50                 PathSegment {
51                     ident: "foo",
52                     arguments: None,
53                 },
54             ],
55         },
56         lit: Lit::Bool {
57             value: true,
58         },
59     }
60     "###);
61 
62     let meta = test("#[foo = false]");
63 
64     snapshot!(meta, @r###"
65     Meta::NameValue {
66         path: Path {
67             segments: [
68                 PathSegment {
69                     ident: "foo",
70                     arguments: None,
71                 },
72             ],
73         },
74         lit: Lit::Bool {
75             value: false,
76         },
77     }
78     "###);
79 }
80 
81 #[test]
82 fn test_meta_item_list_lit() {
83     let meta = test("#[foo(5)]");
84 
85     snapshot!(meta, @r###"
86     Meta::List {
87         path: Path {
88             segments: [
89                 PathSegment {
90                     ident: "foo",
91                     arguments: None,
92                 },
93             ],
94         },
95         nested: [
96             Lit(5),
97         ],
98     }
99     "###);
100 }
101 
102 #[test]
103 fn test_meta_item_list_word() {
104     let meta = test("#[foo(bar)]");
105 
106     snapshot!(meta, @r###"
107     Meta::List {
108         path: Path {
109             segments: [
110                 PathSegment {
111                     ident: "foo",
112                     arguments: None,
113                 },
114             ],
115         },
116         nested: [
117             Meta(Path(Path {
118                 segments: [
119                     PathSegment {
120                         ident: "bar",
121                         arguments: None,
122                     },
123                 ],
124             })),
125         ],
126     }
127     "###);
128 }
129 
130 #[test]
131 fn test_meta_item_list_name_value() {
132     let meta = test("#[foo(bar = 5)]");
133 
134     snapshot!(meta, @r###"
135     Meta::List {
136         path: Path {
137             segments: [
138                 PathSegment {
139                     ident: "foo",
140                     arguments: None,
141                 },
142             ],
143         },
144         nested: [
145             Meta(Meta::NameValue {
146                 path: Path {
147                     segments: [
148                         PathSegment {
149                             ident: "bar",
150                             arguments: None,
151                         },
152                     ],
153                 },
154                 lit: 5,
155             }),
156         ],
157     }
158     "###);
159 }
160 
161 #[test]
162 fn test_meta_item_list_bool_value() {
163     let meta = test("#[foo(bar = true)]");
164 
165     snapshot!(meta, @r###"
166     Meta::List {
167         path: Path {
168             segments: [
169                 PathSegment {
170                     ident: "foo",
171                     arguments: None,
172                 },
173             ],
174         },
175         nested: [
176             Meta(Meta::NameValue {
177                 path: Path {
178                     segments: [
179                         PathSegment {
180                             ident: "bar",
181                             arguments: None,
182                         },
183                     ],
184                 },
185                 lit: Lit::Bool {
186                     value: true,
187                 },
188             }),
189         ],
190     }
191     "###);
192 }
193 
194 #[test]
195 fn test_meta_item_multiple() {
196     let meta = test("#[foo(word, name = 5, list(name2 = 6), word2)]");
197 
198     snapshot!(meta, @r###"
199     Meta::List {
200         path: Path {
201             segments: [
202                 PathSegment {
203                     ident: "foo",
204                     arguments: None,
205                 },
206             ],
207         },
208         nested: [
209             Meta(Path(Path {
210                 segments: [
211                     PathSegment {
212                         ident: "word",
213                         arguments: None,
214                     },
215                 ],
216             })),
217             Meta(Meta::NameValue {
218                 path: Path {
219                     segments: [
220                         PathSegment {
221                             ident: "name",
222                             arguments: None,
223                         },
224                     ],
225                 },
226                 lit: 5,
227             }),
228             Meta(Meta::List {
229                 path: Path {
230                     segments: [
231                         PathSegment {
232                             ident: "list",
233                             arguments: None,
234                         },
235                     ],
236                 },
237                 nested: [
238                     Meta(Meta::NameValue {
239                         path: Path {
240                             segments: [
241                                 PathSegment {
242                                     ident: "name2",
243                                     arguments: None,
244                                 },
245                             ],
246                         },
247                         lit: 6,
248                     }),
249                 ],
250             }),
251             Meta(Path(Path {
252                 segments: [
253                     PathSegment {
254                         ident: "word2",
255                         arguments: None,
256                     },
257                 ],
258             })),
259         ],
260     }
261     "###);
262 }
263 
264 #[test]
265 fn test_bool_lit() {
266     let meta = test("#[foo(true)]");
267 
268     snapshot!(meta, @r###"
269     Meta::List {
270         path: Path {
271             segments: [
272                 PathSegment {
273                     ident: "foo",
274                     arguments: None,
275                 },
276             ],
277         },
278         nested: [
279             Lit(Lit::Bool {
280                 value: true,
281             }),
282         ],
283     }
284     "###);
285 }
286 
287 #[test]
288 fn test_negative_lit() {
289     let meta = test("#[form(min = -1, max = 200)]");
290 
291     snapshot!(meta, @r###"
292     Meta::List {
293         path: Path {
294             segments: [
295                 PathSegment {
296                     ident: "form",
297                     arguments: None,
298                 },
299             ],
300         },
301         nested: [
302             Meta(Meta::NameValue {
303                 path: Path {
304                     segments: [
305                         PathSegment {
306                             ident: "min",
307                             arguments: None,
308                         },
309                     ],
310                 },
311                 lit: -1,
312             }),
313             Meta(Meta::NameValue {
314                 path: Path {
315                     segments: [
316                         PathSegment {
317                             ident: "max",
318                             arguments: None,
319                         },
320                     ],
321                 },
322                 lit: 200,
323             }),
324         ],
325     }
326     "###);
327 }
328 
329 fn test(input: &str) -> Meta {
330     let attrs = Attribute::parse_outer.parse_str(input).unwrap();
331 
332     assert_eq!(attrs.len(), 1);
333     let attr = attrs.into_iter().next().unwrap();
334 
335     attr.parse_meta().unwrap()
336 }
337