Skip to content
/ rust Public
forked from rust-lang/rust

Commit e9063c3

Browse files
committed
Migrate basic tests for proc_macro::quote! from quote crate
1 parent d525641 commit e9063c3

File tree

4 files changed

+368
-0
lines changed

4 files changed

+368
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
#![feature(proc_macro_quote)]
2+
#![feature(proc_macro_totokens)]
3+
4+
extern crate proc_macro;
5+
6+
use std::borrow::Cow;
7+
use std::ffi::{CStr, CString};
8+
9+
use proc_macro::*;
10+
11+
#[proc_macro]
12+
pub fn run_tests(_: TokenStream) -> TokenStream {
13+
test_quote_impl();
14+
test_substitution();
15+
test_advanced();
16+
test_integer();
17+
test_floating();
18+
test_char();
19+
test_str();
20+
test_string();
21+
test_c_str();
22+
test_c_string();
23+
test_interpolated_literal();
24+
test_ident();
25+
test_underscore();
26+
test_duplicate();
27+
test_empty_quote();
28+
test_box_str();
29+
test_cow();
30+
test_append_tokens();
31+
test_outer_line_comment();
32+
test_inner_line_comment();
33+
test_outer_block_comment();
34+
test_inner_block_comment();
35+
test_outer_attr();
36+
test_inner_attr();
37+
// test_quote_raw_id(); // FIXME: Fix it in a subsequent commit
38+
39+
TokenStream::new()
40+
}
41+
42+
// Based on https://github.com/dtolnay/quote/blob/0245506323a3616daa2ee41c6ad0b871e4d78ae4/tests/test.rs
43+
//
44+
// FIXME(quote):
45+
// The following tests are removed because they are not supported yet in `proc_macro::quote!`
46+
//
47+
// - quote_spanned:
48+
// - fn test_quote_spanned_impl
49+
// - fn test_type_inference_for_span
50+
// - format_ident:
51+
// - fn test_format_ident
52+
// - fn test_format_ident_strip_raw
53+
// - repetition:
54+
// - fn test_iter
55+
// - fn test_array
56+
// - fn test_fancy_repetition
57+
// - fn test_nested_fancy_repetition
58+
// - fn test_duplicate_name_repetition
59+
// - fn test_duplicate_name_repetition_no_copy
60+
// - fn test_btreeset_repetition
61+
// - fn test_variable_name_conflict
62+
// - fn test_nonrep_in_repetition
63+
// - fn test_closure
64+
// - fn test_star_after_repetition
65+
66+
struct X;
67+
68+
impl ToTokens for X {
69+
fn to_tokens(&self, tokens: &mut TokenStream) {
70+
Ident::new("X", Span::call_site()).to_tokens(tokens)
71+
}
72+
}
73+
74+
fn test_quote_impl() {
75+
let tokens = quote! {
76+
impl<'a, T: ToTokens> ToTokens for &'a T {
77+
fn to_tokens(&self, tokens: &mut TokenStream) {
78+
(**self).to_tokens(tokens)
79+
}
80+
}
81+
};
82+
83+
let expected = r#"impl < 'a, T : ToTokens > ToTokens for & 'a T
84+
{
85+
fn to_tokens(& self, tokens : & mut TokenStream)
86+
{ (** self).to_tokens(tokens) }
87+
}"#;
88+
89+
assert_eq!(expected, tokens.to_string());
90+
}
91+
92+
fn test_substitution() {
93+
let x = X;
94+
let tokens = quote!($x <$x> ($x) [$x] {$x});
95+
96+
let expected = "X <X > (X) [X] { X }";
97+
98+
assert_eq!(expected, tokens.to_string());
99+
}
100+
101+
fn test_advanced() {
102+
let generics = quote!( <'a, T> );
103+
104+
let where_clause = quote!( where T: Serialize );
105+
106+
let field_ty = quote!(String);
107+
108+
let item_ty = quote!(Cow<'a, str>);
109+
110+
let path = quote!(SomeTrait::serialize_with);
111+
112+
let value = quote!(self.x);
113+
114+
let tokens = quote! {
115+
struct SerializeWith $generics $where_clause {
116+
value: &'a $field_ty,
117+
phantom: ::std::marker::PhantomData<$item_ty>,
118+
}
119+
120+
impl $generics ::serde::Serialize for SerializeWith $generics $where_clause {
121+
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
122+
where S: ::serde::Serializer
123+
{
124+
$path(self.value, s)
125+
}
126+
}
127+
128+
SerializeWith {
129+
value: $value,
130+
phantom: ::std::marker::PhantomData::<$item_ty>,
131+
}
132+
};
133+
134+
let expected = r#"struct SerializeWith < 'a, T > where T : Serialize
135+
{
136+
value : & 'a String, phantom : :: std :: marker :: PhantomData <Cow < 'a,
137+
str > >,
138+
} impl < 'a, T > :: serde :: Serialize for SerializeWith < 'a, T > where T :
139+
Serialize
140+
{
141+
fn serialize < S > (& self, s : & mut S) -> Result < (), S :: Error >
142+
where S : :: serde :: Serializer
143+
{ SomeTrait :: serialize_with(self.value, s) }
144+
} SerializeWith
145+
{
146+
value : self.x, phantom : :: std :: marker :: PhantomData ::<Cow < 'a, str
147+
> >,
148+
}"#;
149+
150+
assert_eq!(expected, tokens.to_string());
151+
}
152+
153+
fn test_integer() {
154+
let ii8 = -1i8;
155+
let ii16 = -1i16;
156+
let ii32 = -1i32;
157+
let ii64 = -1i64;
158+
let ii128 = -1i128;
159+
let iisize = -1isize;
160+
let uu8 = 1u8;
161+
let uu16 = 1u16;
162+
let uu32 = 1u32;
163+
let uu64 = 1u64;
164+
let uu128 = 1u128;
165+
let uusize = 1usize;
166+
167+
let tokens = quote! {
168+
1 1i32 1u256
169+
$ii8 $ii16 $ii32 $ii64 $ii128 $iisize
170+
$uu8 $uu16 $uu32 $uu64 $uu128 $uusize
171+
};
172+
let expected = r#"1 1i32 1u256 -1i8 -1i16 -1i32 -1i64 -1i128 -1isize 1u8 1u16 1u32 1u64 1u128
173+
1usize"#;
174+
assert_eq!(expected, tokens.to_string());
175+
}
176+
177+
fn test_floating() {
178+
let e32 = 2.345f32;
179+
180+
let e64 = 2.345f64;
181+
182+
let tokens = quote! {
183+
$e32
184+
$e64
185+
};
186+
let expected = concat!("2.345f32 2.345f64");
187+
assert_eq!(expected, tokens.to_string());
188+
}
189+
190+
fn test_char() {
191+
let zero = '\u{1}';
192+
let dollar = '$';
193+
let pound = '#';
194+
let quote = '"';
195+
let apost = '\'';
196+
let newline = '\n';
197+
let heart = '\u{2764}';
198+
199+
let tokens = quote! {
200+
$zero $dollar $pound $quote $apost $newline $heart
201+
};
202+
let expected = "'\\u{1}' '$' '#' '\"' '\\'' '\\n' '\u{2764}'";
203+
assert_eq!(expected, tokens.to_string());
204+
}
205+
206+
fn test_str() {
207+
let s = "\u{1} a 'b \" c";
208+
let tokens = quote!($s);
209+
let expected = "\"\\u{1} a 'b \\\" c\"";
210+
assert_eq!(expected, tokens.to_string());
211+
}
212+
213+
fn test_string() {
214+
let s = "\u{1} a 'b \" c".to_string();
215+
let tokens = quote!($s);
216+
let expected = "\"\\u{1} a 'b \\\" c\"";
217+
assert_eq!(expected, tokens.to_string());
218+
}
219+
220+
fn test_c_str() {
221+
let s = CStr::from_bytes_with_nul(b"\x01 a 'b \" c\0").unwrap();
222+
let tokens = quote!($s);
223+
let expected = "c\"\\u{1} a 'b \\\" c\"";
224+
assert_eq!(expected, tokens.to_string());
225+
}
226+
227+
fn test_c_string() {
228+
let s = CString::new(&b"\x01 a 'b \" c"[..]).unwrap();
229+
let tokens = quote!($s);
230+
let expected = "c\"\\u{1} a 'b \\\" c\"";
231+
assert_eq!(expected, tokens.to_string());
232+
}
233+
234+
fn test_interpolated_literal() {
235+
macro_rules! m {
236+
($literal:literal) => {
237+
quote!($literal)
238+
};
239+
}
240+
241+
let tokens = m!(1);
242+
let expected = "1";
243+
assert_eq!(expected, tokens.to_string());
244+
245+
let tokens = m!(-1);
246+
let expected = "- 1";
247+
assert_eq!(expected, tokens.to_string());
248+
249+
let tokens = m!(true);
250+
let expected = "true";
251+
assert_eq!(expected, tokens.to_string());
252+
253+
let tokens = m!(-true);
254+
let expected = "- true";
255+
assert_eq!(expected, tokens.to_string());
256+
}
257+
258+
fn test_ident() {
259+
let foo = Ident::new("Foo", Span::call_site());
260+
let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
261+
let tokens = quote!(struct $foo; enum $bar {});
262+
let expected = "struct Foo; enum Bar7 {}";
263+
assert_eq!(expected, tokens.to_string());
264+
}
265+
266+
fn test_underscore() {
267+
let tokens = quote!(let _;);
268+
let expected = "let _;";
269+
assert_eq!(expected, tokens.to_string());
270+
}
271+
272+
fn test_duplicate() {
273+
let ch = 'x';
274+
275+
let tokens = quote!($ch $ch);
276+
277+
let expected = "'x' 'x'";
278+
assert_eq!(expected, tokens.to_string());
279+
}
280+
281+
fn test_empty_quote() {
282+
let tokens = quote!();
283+
assert_eq!("", tokens.to_string());
284+
}
285+
286+
fn test_box_str() {
287+
let b = "str".to_owned().into_boxed_str();
288+
let tokens = quote! { $b };
289+
assert_eq!("\"str\"", tokens.to_string());
290+
}
291+
292+
fn test_cow() {
293+
let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));
294+
295+
let ident = Ident::new("borrowed", Span::call_site());
296+
let borrowed = Cow::Borrowed(&ident);
297+
298+
let tokens = quote! { $owned $borrowed };
299+
assert_eq!("owned borrowed", tokens.to_string());
300+
}
301+
302+
fn test_append_tokens() {
303+
let mut a = quote!(a);
304+
let b = quote!(b);
305+
a.extend(b);
306+
assert_eq!("a b", a.to_string());
307+
}
308+
309+
fn test_outer_line_comment() {
310+
let tokens = quote! {
311+
/// doc
312+
};
313+
let expected = "#[doc = \" doc\"]";
314+
assert_eq!(expected, tokens.to_string());
315+
}
316+
317+
fn test_inner_line_comment() {
318+
let tokens = quote! {
319+
//! doc
320+
};
321+
let expected = "# ! [doc = \" doc\"]";
322+
assert_eq!(expected, tokens.to_string());
323+
}
324+
325+
fn test_outer_block_comment() {
326+
let tokens = quote! {
327+
/** doc */
328+
};
329+
let expected = "#[doc = \" doc \"]";
330+
assert_eq!(expected, tokens.to_string());
331+
}
332+
333+
fn test_inner_block_comment() {
334+
let tokens = quote! {
335+
/*! doc */
336+
};
337+
let expected = "# ! [doc = \" doc \"]";
338+
assert_eq!(expected, tokens.to_string());
339+
}
340+
341+
fn test_outer_attr() {
342+
let tokens = quote! {
343+
#[inline]
344+
};
345+
let expected = "#[inline]";
346+
assert_eq!(expected, tokens.to_string());
347+
}
348+
349+
fn test_inner_attr() {
350+
let tokens = quote! {
351+
#![no_std]
352+
};
353+
let expected = "#! [no_std]";
354+
assert_eq!(expected, tokens.to_string());
355+
}
356+
357+
fn test_quote_raw_id() {
358+
let id = quote!(r#raw_id);
359+
assert_eq!(id.to_string(), "r#raw_id");
360+
}

tests/ui/proc-macro/quote/basic.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ run-pass
2+
//@ proc-macro: basic.rs
3+
4+
extern crate basic;
5+
6+
fn main() {
7+
basic::run_tests!();
8+
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)