blob: 7c7275d6104d295724b1e284849ffca49668fc66 [file] [log] [blame]
David Tolnaye5806852017-06-01 12:49:20 -07001extern crate proc_macro2;
2
Alex Crichton8c030332018-01-16 08:07:36 -08003use std::str;
4
David Tolnay79105e52017-12-31 11:03:04 -05005use proc_macro2::{Term, Literal, TokenStream};
6
David Tolnay1ebe3972018-01-02 20:14:20 -08007#[cfg(procmacro2_semver_exempt)]
David Tolnay79105e52017-12-31 11:03:04 -05008use proc_macro2::TokenNode;
9
David Tolnay1ebe3972018-01-02 20:14:20 -080010#[cfg(procmacro2_semver_exempt)]
David Tolnayd66ecf62018-01-02 20:05:42 -080011#[cfg(not(feature = "nightly"))]
David Tolnay79105e52017-12-31 11:03:04 -050012use proc_macro2::Span;
David Tolnaye5806852017-06-01 12:49:20 -070013
14#[test]
15fn symbols() {
Alex Crichton1a7f7622017-07-05 17:47:15 -070016 assert_eq!(Term::intern("foo").as_str(), "foo");
17 assert_eq!(Term::intern("bar").as_str(), "bar");
David Tolnaye5806852017-06-01 12:49:20 -070018}
19
20#[test]
21fn literals() {
Alex Crichton1a7f7622017-07-05 17:47:15 -070022 assert_eq!(Literal::string("foo").to_string(), "\"foo\"");
23 assert_eq!(Literal::string("\"").to_string(), "\"\\\"\"");
David Tolnay114990e2018-01-05 11:17:08 -080024 assert_eq!(Literal::float(10.0).to_string(), "10.0");
David Tolnaye5806852017-06-01 12:49:20 -070025}
26
27#[test]
28fn roundtrip() {
29 fn roundtrip(p: &str) {
30 println!("parse: {}", p);
31 let s = p.parse::<TokenStream>().unwrap().to_string();
32 println!("first: {}", s);
33 let s2 = s.to_string().parse::<TokenStream>().unwrap().to_string();
34 assert_eq!(s, s2);
35 }
36 roundtrip("a");
37 roundtrip("<<");
38 roundtrip("<<=");
39 roundtrip("
40 /// a
41 wut
42 ");
43 roundtrip("
44 1
45 1.0
46 1f32
47 2f64
48 1usize
49 4isize
50 4e10
51 1_000
52 1_0i32
53 8u8
54 9
55 0
56 0xffffffffffffffffffffffffffffffff
57 ");
58 roundtrip("'a");
59 roundtrip("'static");
David Tolnay8d109342017-12-25 18:24:45 -050060 roundtrip("'\\u{10__FFFF}'");
61 roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\"");
David Tolnaye5806852017-06-01 12:49:20 -070062}
63
64#[test]
65fn fail() {
66 fn fail(p: &str) {
67 if p.parse::<TokenStream>().is_ok() {
68 panic!("should have failed to parse: {}", p);
69 }
70 }
71 fail("1x");
72 fail("1u80");
73 fail("1f320");
74 fail("' static");
75 fail("'mut");
76}
Nika Layzellf8d5f212017-12-11 14:07:02 -050077
David Tolnay1ebe3972018-01-02 20:14:20 -080078#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -050079#[test]
80fn span_test() {
81 fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) {
Nika Layzellf8d5f212017-12-11 14:07:02 -050082 let ts = p.parse::<TokenStream>().unwrap();
83 check_spans_internal(ts, &mut lines);
84 }
85
86 fn check_spans_internal(
87 ts: TokenStream,
88 lines: &mut &[(usize, usize, usize, usize)],
89 ) {
90 for i in ts {
91 if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() {
92 *lines = rest;
93
Nika Layzellf8d5f212017-12-11 14:07:02 -050094 let start = i.span.start();
95 assert_eq!(start.line, sline, "sline did not match for {}", i);
96 assert_eq!(start.column, scol, "scol did not match for {}", i);
97
98 let end = i.span.end();
99 assert_eq!(end.line, eline, "eline did not match for {}", i);
100 assert_eq!(end.column, ecol, "ecol did not match for {}", i);
101
102 match i.kind {
103 TokenNode::Group(_, stream) =>
104 check_spans_internal(stream, lines),
105 _ => {}
106 }
107 }
108 }
109 }
110
111 check_spans("\
112/// This is a document comment
113testing 123
114{
115 testing 234
116}", &[
117 (1, 0, 1, 30),
118 (2, 0, 2, 7),
119 (2, 8, 2, 11),
120 (3, 0, 5, 1),
121 (4, 2, 4, 9),
122 (4, 10, 4, 13),
123]);
124}
125
David Tolnay1ebe3972018-01-02 20:14:20 -0800126#[cfg(procmacro2_semver_exempt)]
David Tolnayd66ecf62018-01-02 20:05:42 -0800127#[cfg(not(feature = "nightly"))]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500128#[test]
129fn default_span() {
130 let start = Span::call_site().start();
131 assert_eq!(start.line, 1);
132 assert_eq!(start.column, 0);
133 let end = Span::call_site().end();
134 assert_eq!(end.line, 1);
135 assert_eq!(end.column, 0);
136 let source_file = Span::call_site().source_file();
Nika Layzellfb783e32017-12-30 14:58:27 -0500137 assert_eq!(source_file.path().to_string(), "<unspecified>");
Nika Layzellf8d5f212017-12-11 14:07:02 -0500138 assert!(!source_file.is_real());
139}
140
David Tolnay1ebe3972018-01-02 20:14:20 -0800141#[cfg(procmacro2_semver_exempt)]
Nika Layzellddea1562017-12-11 14:25:35 -0500142#[test]
143fn span_join() {
144 let source1 =
145 "aaa\nbbb".parse::<TokenStream>().unwrap().into_iter().collect::<Vec<_>>();
146 let source2 =
147 "ccc\nddd".parse::<TokenStream>().unwrap().into_iter().collect::<Vec<_>>();
148
149 assert!(source1[0].span.source_file() != source2[0].span.source_file());
150 assert_eq!(source1[0].span.source_file(), source1[1].span.source_file());
151
152 let joined1 = source1[0].span.join(source1[1].span);
153 let joined2 = source1[0].span.join(source2[0].span);
154 assert!(joined1.is_some());
155 assert!(joined2.is_none());
156
157 let start = joined1.unwrap().start();
158 let end = joined1.unwrap().end();
159 assert_eq!(start.line, 1);
160 assert_eq!(start.column, 0);
161 assert_eq!(end.line, 2);
162 assert_eq!(end.column, 3);
163
164 assert_eq!(joined1.unwrap().source_file(), source1[0].span.source_file());
165}
Alex Crichton8c030332018-01-16 08:07:36 -0800166
167#[test]
168fn no_panic() {
169 let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap();
170 assert!(s.parse::<proc_macro2::TokenStream>().is_err());
171}
172