blob: 19f7b27d8b90c22f125374f729554e5f17ac39f0 [file] [log] [blame]
David Tolnaye5806852017-06-01 12:49:20 -07001extern crate proc_macro2;
2
David Tolnay79105e52017-12-31 11:03:04 -05003use proc_macro2::{Term, Literal, TokenStream};
4
David Tolnay1ebe3972018-01-02 20:14:20 -08005#[cfg(procmacro2_semver_exempt)]
David Tolnay79105e52017-12-31 11:03:04 -05006use proc_macro2::TokenNode;
7
David Tolnay1ebe3972018-01-02 20:14:20 -08008#[cfg(procmacro2_semver_exempt)]
David Tolnayd66ecf62018-01-02 20:05:42 -08009#[cfg(not(feature = "nightly"))]
David Tolnay79105e52017-12-31 11:03:04 -050010use proc_macro2::Span;
David Tolnaye5806852017-06-01 12:49:20 -070011
12#[test]
13fn symbols() {
Alex Crichton1a7f7622017-07-05 17:47:15 -070014 assert_eq!(Term::intern("foo").as_str(), "foo");
15 assert_eq!(Term::intern("bar").as_str(), "bar");
David Tolnaye5806852017-06-01 12:49:20 -070016}
17
18#[test]
19fn literals() {
Alex Crichton1a7f7622017-07-05 17:47:15 -070020 assert_eq!(Literal::string("foo").to_string(), "\"foo\"");
21 assert_eq!(Literal::string("\"").to_string(), "\"\\\"\"");
David Tolnay114990e2018-01-05 11:17:08 -080022 assert_eq!(Literal::float(10.0).to_string(), "10.0");
David Tolnaye5806852017-06-01 12:49:20 -070023}
24
25#[test]
26fn roundtrip() {
27 fn roundtrip(p: &str) {
28 println!("parse: {}", p);
29 let s = p.parse::<TokenStream>().unwrap().to_string();
30 println!("first: {}", s);
31 let s2 = s.to_string().parse::<TokenStream>().unwrap().to_string();
32 assert_eq!(s, s2);
33 }
34 roundtrip("a");
35 roundtrip("<<");
36 roundtrip("<<=");
37 roundtrip("
38 /// a
39 wut
40 ");
41 roundtrip("
42 1
43 1.0
44 1f32
45 2f64
46 1usize
47 4isize
48 4e10
49 1_000
50 1_0i32
51 8u8
52 9
53 0
54 0xffffffffffffffffffffffffffffffff
55 ");
56 roundtrip("'a");
57 roundtrip("'static");
David Tolnay8d109342017-12-25 18:24:45 -050058 roundtrip("'\\u{10__FFFF}'");
59 roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\"");
David Tolnaye5806852017-06-01 12:49:20 -070060}
61
62#[test]
63fn fail() {
64 fn fail(p: &str) {
65 if p.parse::<TokenStream>().is_ok() {
66 panic!("should have failed to parse: {}", p);
67 }
68 }
69 fail("1x");
70 fail("1u80");
71 fail("1f320");
72 fail("' static");
73 fail("'mut");
74}
Nika Layzellf8d5f212017-12-11 14:07:02 -050075
David Tolnay1ebe3972018-01-02 20:14:20 -080076#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -050077#[test]
78fn span_test() {
79 fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) {
Nika Layzellf8d5f212017-12-11 14:07:02 -050080 let ts = p.parse::<TokenStream>().unwrap();
81 check_spans_internal(ts, &mut lines);
82 }
83
84 fn check_spans_internal(
85 ts: TokenStream,
86 lines: &mut &[(usize, usize, usize, usize)],
87 ) {
88 for i in ts {
89 if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() {
90 *lines = rest;
91
Nika Layzellf8d5f212017-12-11 14:07:02 -050092 let start = i.span.start();
93 assert_eq!(start.line, sline, "sline did not match for {}", i);
94 assert_eq!(start.column, scol, "scol did not match for {}", i);
95
96 let end = i.span.end();
97 assert_eq!(end.line, eline, "eline did not match for {}", i);
98 assert_eq!(end.column, ecol, "ecol did not match for {}", i);
99
100 match i.kind {
101 TokenNode::Group(_, stream) =>
102 check_spans_internal(stream, lines),
103 _ => {}
104 }
105 }
106 }
107 }
108
109 check_spans("\
110/// This is a document comment
111testing 123
112{
113 testing 234
114}", &[
115 (1, 0, 1, 30),
116 (2, 0, 2, 7),
117 (2, 8, 2, 11),
118 (3, 0, 5, 1),
119 (4, 2, 4, 9),
120 (4, 10, 4, 13),
121]);
122}
123
David Tolnay1ebe3972018-01-02 20:14:20 -0800124#[cfg(procmacro2_semver_exempt)]
David Tolnayd66ecf62018-01-02 20:05:42 -0800125#[cfg(not(feature = "nightly"))]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500126#[test]
127fn default_span() {
128 let start = Span::call_site().start();
129 assert_eq!(start.line, 1);
130 assert_eq!(start.column, 0);
131 let end = Span::call_site().end();
132 assert_eq!(end.line, 1);
133 assert_eq!(end.column, 0);
134 let source_file = Span::call_site().source_file();
Nika Layzellfb783e32017-12-30 14:58:27 -0500135 assert_eq!(source_file.path().to_string(), "<unspecified>");
Nika Layzellf8d5f212017-12-11 14:07:02 -0500136 assert!(!source_file.is_real());
137}
138
David Tolnay1ebe3972018-01-02 20:14:20 -0800139#[cfg(procmacro2_semver_exempt)]
Nika Layzellddea1562017-12-11 14:25:35 -0500140#[test]
141fn span_join() {
142 let source1 =
143 "aaa\nbbb".parse::<TokenStream>().unwrap().into_iter().collect::<Vec<_>>();
144 let source2 =
145 "ccc\nddd".parse::<TokenStream>().unwrap().into_iter().collect::<Vec<_>>();
146
147 assert!(source1[0].span.source_file() != source2[0].span.source_file());
148 assert_eq!(source1[0].span.source_file(), source1[1].span.source_file());
149
150 let joined1 = source1[0].span.join(source1[1].span);
151 let joined2 = source1[0].span.join(source2[0].span);
152 assert!(joined1.is_some());
153 assert!(joined2.is_none());
154
155 let start = joined1.unwrap().start();
156 let end = joined1.unwrap().end();
157 assert_eq!(start.line, 1);
158 assert_eq!(start.column, 0);
159 assert_eq!(end.line, 2);
160 assert_eq!(end.column, 3);
161
162 assert_eq!(joined1.unwrap().source_file(), source1[0].span.source_file());
163}