blob: bd8a980d73b8d7b1a1e44f7da2b256d6e2324a76 [file] [log] [blame]
David Tolnay360efd22018-01-04 23:35:26 -08001extern crate syn;
2extern crate quote;
3extern crate proc_macro2;
4
5use syn::{Lit, IntSuffix, FloatSuffix};
6use quote::ToTokens;
7use proc_macro2::{TokenStream, TokenNode, Span};
8use std::str::FromStr;
9
10fn lit(s: &str) -> Lit {
11 match TokenStream::from_str(s).unwrap().into_iter().next().unwrap().kind {
12 TokenNode::Literal(lit) => Lit::new(lit, Span::default()),
13 _ => panic!(),
14 }
15}
16
17#[test]
18fn strings() {
19 fn test_string(s: &str, value: &str) {
20 match lit(s) {
21 Lit::Str(lit) => {
22 assert_eq!(lit.value(), value);
23 let again = lit.into_tokens().to_string();
24 if again != s {
25 test_string(&again, value);
26 }
27 }
28 wrong => panic!("{:?}", wrong),
29 }
30 }
31
32 test_string("\"a\"", "a");
33 test_string("\"\\n\"", "\n");
34 test_string("\"\\r\"", "\r");
35 test_string("\"\\t\"", "\t");
36 test_string("\"🐕\"", "🐕"); // NOTE: This is an emoji
37 test_string("\"\\\"\"", "\"");
38 test_string("\"'\"", "'");
39 test_string("\"\"", "");
40 test_string("\"\\u{1F415}\"", "\u{1F415}");
41 test_string("\"contains\nnewlines\\\nescaped newlines\"",
42 "contains\nnewlinesescaped newlines");
43 test_string("r\"raw\nstring\\\nhere\"", "raw\nstring\\\nhere");
44}
45
46#[test]
47fn byte_strings() {
48 fn test_byte_string(s: &str, value: &[u8]) {
49 match lit(s) {
50 Lit::ByteStr(lit) => {
51 assert_eq!(lit.value(), value);
52 let again = lit.into_tokens().to_string();
53 if again != s {
54 test_byte_string(&again, value);
55 }
56 }
57 wrong => panic!("{:?}", wrong),
58 }
59 }
60
61 test_byte_string("b\"a\"", b"a");
62 test_byte_string("b\"\\n\"", b"\n");
63 test_byte_string("b\"\\r\"", b"\r");
64 test_byte_string("b\"\\t\"", b"\t");
65 test_byte_string("b\"\\\"\"", b"\"");
66 test_byte_string("b\"'\"", b"'");
67 test_byte_string("b\"\"", b"");
68 test_byte_string("b\"contains\nnewlines\\\nescaped newlines\"",
69 b"contains\nnewlinesescaped newlines");
70 test_byte_string("br\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere");
71}
72
73#[test]
74fn bytes() {
75 fn test_byte(s: &str, value: u8) {
76 match lit(s) {
77 Lit::Byte(lit) => {
78 assert_eq!(lit.value(), value);
79 let again = lit.into_tokens().to_string();
80 assert_eq!(again, s);
81 }
82 wrong => panic!("{:?}", wrong),
83 }
84 }
85
86 test_byte("b'a'", b'a');
87 test_byte("b'\\n'", b'\n');
88 test_byte("b'\\r'", b'\r');
89 test_byte("b'\\t'", b'\t');
90 test_byte("b'\\''", b'\'');
91 test_byte("b'\"'", b'"');
92}
93
94#[test]
95fn chars() {
96 fn test_char(s: &str, value: char) {
97 match lit(s) {
98 Lit::Char(lit) => {
99 assert_eq!(lit.value(), value);
100 let again = lit.into_tokens().to_string();
101 if again != s {
102 test_char(&again, value);
103 }
104 }
105 wrong => panic!("{:?}", wrong),
106 }
107 }
108
109 test_char("'a'", 'a');
110 test_char("'\\n'", '\n');
111 test_char("'\\r'", '\r');
112 test_char("'\\t'", '\t');
113 test_char("'🐕'", '🐕'); // NOTE: This is an emoji
114 test_char("'\\''", '\'');
115 test_char("'\"'", '"');
116 test_char("'\\u{1F415}'", '\u{1F415}');
117}
118
119#[test]
120fn ints() {
121 fn test_int(s: &str, value: u64, suffix: IntSuffix) {
122 match lit(s) {
123 Lit::Int(lit) => {
124 assert_eq!(lit.value(), value);
125 assert_eq!(lit.suffix(), suffix);
126 let again = lit.into_tokens().to_string();
127 if again != s {
128 test_int(&again, value, suffix);
129 }
130 }
131 wrong => panic!("{:?}", wrong),
132 }
133 }
134
135 use syn::IntSuffix::*;
136 test_int("5", 5, None);
137 test_int("5u32", 5, U32);
138 test_int("5_0", 50, None);
139 test_int("5_____0_____", 50, None);
140 test_int("0x7f", 127, None);
141 test_int("0x7F", 127, None);
142 test_int("0b1001", 9, None);
143 test_int("0o73", 59, None);
144 test_int("0x7Fu8", 127, U8);
145 test_int("0b1001i8", 9, I8);
146 test_int("0o73u32", 59, U32);
147 test_int("0x__7___f_", 127, None);
148 test_int("0x__7___F_", 127, None);
149 test_int("0b_1_0__01", 9, None);
150 test_int("0o_7__3", 59, None);
151 test_int("0x_7F__u8", 127, U8);
152 test_int("0b__10__0_1i8", 9, I8);
153 test_int("0o__7__________________3u32", 59, U32);
154}
155
156#[test]
157fn floats() {
158 fn test_float(s: &str, value: f64, suffix: FloatSuffix) {
159 match lit(s) {
160 Lit::Float(lit) => {
161 assert_eq!(lit.value(), value);
162 assert_eq!(lit.suffix(), suffix);
163 let again = lit.into_tokens().to_string();
164 if again != s {
165 test_float(&again, value, suffix);
166 }
167 }
168 wrong => panic!("{:?}", wrong),
169 }
170 }
171
172 use syn::FloatSuffix::*;
173 test_float("5.5", 5.5, None);
174 test_float("5.5E12", 5.5e12, None);
175 test_float("5.5e12", 5.5e12, None);
176 test_float("1.0__3e-12", 1.03e-12, None);
177 test_float("1.03e+12", 1.03e12, None);
178}