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