]> git.proxmox.com Git - rustc.git/blob - vendor/quote/tests/test.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / vendor / quote / tests / test.rs
1 #![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
2
3 use std::borrow::Cow;
4 use std::collections::BTreeSet;
5
6 use proc_macro2::{Ident, Span, TokenStream};
7 use quote::{format_ident, quote, quote_spanned, TokenStreamExt};
8
9 struct X;
10
11 impl quote::ToTokens for X {
12 fn to_tokens(&self, tokens: &mut TokenStream) {
13 tokens.append(Ident::new("X", Span::call_site()));
14 }
15 }
16
17 #[test]
18 fn test_quote_impl() {
19 let tokens = quote! {
20 impl<'a, T: ToTokens> ToTokens for &'a T {
21 fn to_tokens(&self, tokens: &mut TokenStream) {
22 (**self).to_tokens(tokens)
23 }
24 }
25 };
26
27 let expected = concat!(
28 "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
29 "fn to_tokens ( & self , tokens : & mut TokenStream ) { ",
30 "( * * self ) . to_tokens ( tokens ) ",
31 "} ",
32 "}"
33 );
34
35 assert_eq!(expected, tokens.to_string());
36 }
37
38 #[test]
39 fn test_quote_spanned_impl() {
40 let span = Span::call_site();
41 let tokens = quote_spanned! {span=>
42 impl<'a, T: ToTokens> ToTokens for &'a T {
43 fn to_tokens(&self, tokens: &mut TokenStream) {
44 (**self).to_tokens(tokens)
45 }
46 }
47 };
48
49 let expected = concat!(
50 "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
51 "fn to_tokens ( & self , tokens : & mut TokenStream ) { ",
52 "( * * self ) . to_tokens ( tokens ) ",
53 "} ",
54 "}"
55 );
56
57 assert_eq!(expected, tokens.to_string());
58 }
59
60 #[test]
61 fn test_substitution() {
62 let x = X;
63 let tokens = quote!(#x <#x> (#x) [#x] {#x});
64
65 let expected = "X < X > ( X ) [ X ] { X }";
66
67 assert_eq!(expected, tokens.to_string());
68 }
69
70 #[test]
71 fn test_iter() {
72 let primes = &[X, X, X, X];
73
74 assert_eq!("X X X X", quote!(#(#primes)*).to_string());
75
76 assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());
77
78 assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
79 }
80
81 #[test]
82 fn test_advanced() {
83 let generics = quote!( <'a, T> );
84
85 let where_clause = quote!( where T: Serialize );
86
87 let field_ty = quote!(String);
88
89 let item_ty = quote!(Cow<'a, str>);
90
91 let path = quote!(SomeTrait::serialize_with);
92
93 let value = quote!(self.x);
94
95 let tokens = quote! {
96 struct SerializeWith #generics #where_clause {
97 value: &'a #field_ty,
98 phantom: ::std::marker::PhantomData<#item_ty>,
99 }
100
101 impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
102 fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
103 where S: ::serde::Serializer
104 {
105 #path(self.value, s)
106 }
107 }
108
109 SerializeWith {
110 value: #value,
111 phantom: ::std::marker::PhantomData::<#item_ty>,
112 }
113 };
114
115 let expected = concat!(
116 "struct SerializeWith < 'a , T > where T : Serialize { ",
117 "value : & 'a String , ",
118 "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
119 "} ",
120 "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
121 "fn serialize < S > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > ",
122 "where S : :: serde :: Serializer ",
123 "{ ",
124 "SomeTrait :: serialize_with ( self . value , s ) ",
125 "} ",
126 "} ",
127 "SerializeWith { ",
128 "value : self . x , ",
129 "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
130 "}"
131 );
132
133 assert_eq!(expected, tokens.to_string());
134 }
135
136 #[test]
137 fn test_integer() {
138 let ii8 = -1i8;
139 let ii16 = -1i16;
140 let ii32 = -1i32;
141 let ii64 = -1i64;
142 let ii128 = -1i128;
143 let iisize = -1isize;
144 let uu8 = 1u8;
145 let uu16 = 1u16;
146 let uu32 = 1u32;
147 let uu64 = 1u64;
148 let uu128 = 1u128;
149 let uusize = 1usize;
150
151 let tokens = quote! {
152 #ii8 #ii16 #ii32 #ii64 #ii128 #iisize
153 #uu8 #uu16 #uu32 #uu64 #uu128 #uusize
154 };
155 let expected = "- 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";
156 assert_eq!(expected, tokens.to_string());
157 }
158
159 #[test]
160 fn test_floating() {
161 let e32 = 2.345f32;
162
163 let e64 = 2.345f64;
164
165 let tokens = quote! {
166 #e32
167 #e64
168 };
169 let expected = concat!("2.345f32 2.345f64");
170 assert_eq!(expected, tokens.to_string());
171 }
172
173 #[test]
174 fn test_char() {
175 let zero = '\0';
176 let pound = '#';
177 let quote = '"';
178 let apost = '\'';
179 let newline = '\n';
180 let heart = '\u{2764}';
181
182 let tokens = quote! {
183 #zero #pound #quote #apost #newline #heart
184 };
185 let expected = "'\\u{0}' '#' '\"' '\\'' '\\n' '\u{2764}'";
186 assert_eq!(expected, tokens.to_string());
187 }
188
189 #[test]
190 fn test_str() {
191 let s = "\0 a 'b \" c";
192 let tokens = quote!(#s);
193 let expected = "\"\\u{0} a 'b \\\" c\"";
194 assert_eq!(expected, tokens.to_string());
195 }
196
197 #[test]
198 fn test_string() {
199 let s = "\0 a 'b \" c".to_string();
200 let tokens = quote!(#s);
201 let expected = "\"\\u{0} a 'b \\\" c\"";
202 assert_eq!(expected, tokens.to_string());
203 }
204
205 #[test]
206 fn test_ident() {
207 let foo = Ident::new("Foo", Span::call_site());
208 let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
209 let tokens = quote!(struct #foo; enum #bar {});
210 let expected = "struct Foo ; enum Bar7 { }";
211 assert_eq!(expected, tokens.to_string());
212 }
213
214 #[test]
215 fn test_duplicate() {
216 let ch = 'x';
217
218 let tokens = quote!(#ch #ch);
219
220 let expected = "'x' 'x'";
221 assert_eq!(expected, tokens.to_string());
222 }
223
224 #[test]
225 fn test_fancy_repetition() {
226 let foo = vec!["a", "b"];
227 let bar = vec![true, false];
228
229 let tokens = quote! {
230 #(#foo: #bar),*
231 };
232
233 let expected = r#""a" : true , "b" : false"#;
234 assert_eq!(expected, tokens.to_string());
235 }
236
237 #[test]
238 fn test_nested_fancy_repetition() {
239 let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];
240
241 let tokens = quote! {
242 #(
243 #(#nested)*
244 ),*
245 };
246
247 let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
248 assert_eq!(expected, tokens.to_string());
249 }
250
251 #[test]
252 fn test_duplicate_name_repetition() {
253 let foo = &["a", "b"];
254
255 let tokens = quote! {
256 #(#foo: #foo),*
257 #(#foo: #foo),*
258 };
259
260 let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
261 assert_eq!(expected, tokens.to_string());
262 }
263
264 #[test]
265 fn test_duplicate_name_repetition_no_copy() {
266 let foo = vec!["a".to_owned(), "b".to_owned()];
267
268 let tokens = quote! {
269 #(#foo: #foo),*
270 };
271
272 let expected = r#""a" : "a" , "b" : "b""#;
273 assert_eq!(expected, tokens.to_string());
274 }
275
276 #[test]
277 fn test_btreeset_repetition() {
278 let mut set = BTreeSet::new();
279 set.insert("a".to_owned());
280 set.insert("b".to_owned());
281
282 let tokens = quote! {
283 #(#set: #set),*
284 };
285
286 let expected = r#""a" : "a" , "b" : "b""#;
287 assert_eq!(expected, tokens.to_string());
288 }
289
290 #[test]
291 fn test_variable_name_conflict() {
292 // The implementation of `#(...),*` uses the variable `_i` but it should be
293 // fine, if a little confusing when debugging.
294 let _i = vec!['a', 'b'];
295 let tokens = quote! { #(#_i),* };
296 let expected = "'a' , 'b'";
297 assert_eq!(expected, tokens.to_string());
298 }
299
300 #[test]
301 fn test_nonrep_in_repetition() {
302 let rep = vec!["a", "b"];
303 let nonrep = "c";
304
305 let tokens = quote! {
306 #(#rep #rep : #nonrep #nonrep),*
307 };
308
309 let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
310 assert_eq!(expected, tokens.to_string());
311 }
312
313 #[test]
314 fn test_empty_quote() {
315 let tokens = quote!();
316 assert_eq!("", tokens.to_string());
317 }
318
319 #[test]
320 fn test_box_str() {
321 let b = "str".to_owned().into_boxed_str();
322 let tokens = quote! { #b };
323 assert_eq!("\"str\"", tokens.to_string());
324 }
325
326 #[test]
327 fn test_cow() {
328 let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));
329
330 let ident = Ident::new("borrowed", Span::call_site());
331 let borrowed = Cow::Borrowed(&ident);
332
333 let tokens = quote! { #owned #borrowed };
334 assert_eq!("owned borrowed", tokens.to_string());
335 }
336
337 #[test]
338 fn test_closure() {
339 fn field_i(i: usize) -> Ident {
340 format_ident!("__field{}", i)
341 }
342
343 let fields = (0usize..3)
344 .map(field_i as fn(_) -> _)
345 .map(|var| quote! { #var });
346
347 let tokens = quote! { #(#fields)* };
348 assert_eq!("__field0 __field1 __field2", tokens.to_string());
349 }
350
351 #[test]
352 fn test_append_tokens() {
353 let mut a = quote!(a);
354 let b = quote!(b);
355 a.append_all(b);
356 assert_eq!("a b", a.to_string());
357 }
358
359 #[test]
360 fn test_format_ident() {
361 let id0 = format_ident!("Aa");
362 let id1 = format_ident!("Hello{x}", x = id0);
363 let id2 = format_ident!("Hello{x}", x = 5usize);
364 let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
365 let id4 = format_ident!("Aa", span = Span::call_site());
366 let id5 = format_ident!("Hello{}", Cow::Borrowed("World"));
367
368 assert_eq!(id0, "Aa");
369 assert_eq!(id1, "HelloAa");
370 assert_eq!(id2, "Hello5");
371 assert_eq!(id3, "HelloAa_10");
372 assert_eq!(id4, "Aa");
373 assert_eq!(id5, "HelloWorld");
374 }
375
376 #[test]
377 fn test_format_ident_strip_raw() {
378 let id = format_ident!("r#struct");
379 let my_id = format_ident!("MyId{}", id);
380 let raw_my_id = format_ident!("r#MyId{}", id);
381
382 assert_eq!(id, "r#struct");
383 assert_eq!(my_id, "MyIdstruct");
384 assert_eq!(raw_my_id, "r#MyIdstruct");
385 }
386
387 #[test]
388 fn test_outer_line_comment() {
389 let tokens = quote! {
390 /// doc
391 };
392 let expected = "# [ doc = r\" doc\" ]";
393 assert_eq!(expected, tokens.to_string());
394 }
395
396 #[test]
397 fn test_inner_line_comment() {
398 let tokens = quote! {
399 //! doc
400 };
401 let expected = "# ! [ doc = r\" doc\" ]";
402 assert_eq!(expected, tokens.to_string());
403 }
404
405 #[test]
406 fn test_outer_block_comment() {
407 let tokens = quote! {
408 /** doc */
409 };
410 let expected = "# [ doc = r\" doc \" ]";
411 assert_eq!(expected, tokens.to_string());
412 }
413
414 #[test]
415 fn test_inner_block_comment() {
416 let tokens = quote! {
417 /*! doc */
418 };
419 let expected = "# ! [ doc = r\" doc \" ]";
420 assert_eq!(expected, tokens.to_string());
421 }
422
423 #[test]
424 fn test_outer_attr() {
425 let tokens = quote! {
426 #[inline]
427 };
428 let expected = "# [ inline ]";
429 assert_eq!(expected, tokens.to_string());
430 }
431
432 #[test]
433 fn test_inner_attr() {
434 let tokens = quote! {
435 #![no_std]
436 };
437 let expected = "# ! [ no_std ]";
438 assert_eq!(expected, tokens.to_string());
439 }
440
441 // https://github.com/dtolnay/quote/issues/130
442 #[test]
443 fn test_star_after_repetition() {
444 let c = vec!['0', '1'];
445 let tokens = quote! {
446 #(
447 f(#c);
448 )*
449 *out = None;
450 };
451 let expected = "f ( '0' ) ; f ( '1' ) ; * out = None ;";
452 assert_eq!(expected, tokens.to_string());
453 }
454
455 #[test]
456 fn test_quote_raw_id() {
457 let id = quote!(r#raw_id);
458 assert_eq!(id.to_string(), "r#raw_id");
459 }