1 use crate::{Literal, test_util::{assert_parse_ok_eq, assert_roundtrip}};
2 use super::CharLit;
3
4 // ===== Utility functions =======================================================================
5
6 macro_rules! check {
7 ($lit:literal) => { check!($lit, stringify!($lit), "") };
8 ($lit:literal, $input:expr, $suffix:literal) => {
9 let input = $input;
10 let expected = CharLit {
11 raw: input,
12 start_suffix: input.len() - $suffix.len(),
13 value: $lit,
14 };
15
16 assert_parse_ok_eq(input, CharLit::parse(input), expected.clone(), "CharLit::parse");
17 assert_parse_ok_eq(input, Literal::parse(input), Literal::Char(expected), "Literal::parse");
18 let lit = CharLit::parse(input).unwrap();
19 assert_eq!(lit.value(), $lit);
20 assert_eq!(lit.suffix(), $suffix);
21 assert_roundtrip(expected.to_owned(), input);
22 };
23 }
24
25
26 // ===== Actual tests ============================================================================
27
28 #[test]
alphanumeric()29 fn alphanumeric() {
30 check!('a');
31 check!('b');
32 check!('y');
33 check!('z');
34 check!('A');
35 check!('B');
36 check!('Y');
37 check!('Z');
38
39 check!('0');
40 check!('1');
41 check!('8');
42 check!('9');
43 }
44
45 #[test]
special_chars()46 fn special_chars() {
47 check!(' ');
48 check!('!');
49 check!('"');
50 check!('#');
51 check!('$');
52 check!('%');
53 check!('&');
54 check!('(');
55 check!(')');
56 check!('*');
57 check!('+');
58 check!(',');
59 check!('-');
60 check!('.');
61 check!('/');
62 check!(':');
63 check!(';');
64 check!('<');
65 check!('=');
66 check!('>');
67 check!('?');
68 check!('@');
69 check!('[');
70 check!(']');
71 check!('^');
72 check!('_');
73 check!('`');
74 check!('{');
75 check!('|');
76 check!('}');
77 check!('~');
78 }
79
80 #[test]
unicode()81 fn unicode() {
82 check!('న');
83 check!('犬');
84 check!('');
85 }
86
87 #[test]
quote_escapes()88 fn quote_escapes() {
89 check!('\'');
90 check!('\"');
91 }
92
93 #[test]
ascii_escapes()94 fn ascii_escapes() {
95 check!('\n');
96 check!('\r');
97 check!('\t');
98 check!('\\');
99 check!('\0');
100
101 check!('\x00');
102 check!('\x01');
103 check!('\x0c');
104 check!('\x0D');
105 check!('\x13');
106 check!('\x30');
107 check!('\x30');
108 check!('\x4B');
109 check!('\x6b');
110 check!('\x7F');
111 check!('\x7f');
112 }
113
114 #[test]
unicode_escapes()115 fn unicode_escapes() {
116 check!('\u{0}');
117 check!('\u{00}');
118 check!('\u{b}');
119 check!('\u{B}');
120 check!('\u{7e}');
121 check!('\u{E4}');
122 check!('\u{e4}');
123 check!('\u{fc}');
124 check!('\u{Fc}');
125 check!('\u{fC}');
126 check!('\u{FC}');
127 check!('\u{b10}');
128 check!('\u{B10}');
129 check!('\u{0b10}');
130 check!('\u{2764}');
131 check!('\u{1f602}');
132 check!('\u{1F602}');
133
134 check!('\u{0}');
135 check!('\u{0__}');
136 check!('\u{3_b}');
137 check!('\u{1_F_6_0_2}');
138 check!('\u{1_F6_02_____}');
139 }
140
141 #[test]
suffixes()142 fn suffixes() {
143 check!('a', r##"'a'peter"##, "peter");
144 check!('#', r##"'#'peter"##, "peter");
145 check!('\n', r##"'\n'peter"##, "peter");
146 check!('\'', r##"'\''peter"##, "peter");
147 check!('\"', r##"'\"'peter"##, "peter");
148 }
149
150 #[test]
invald_ascii_escapes()151 fn invald_ascii_escapes() {
152 assert_err!(CharLit, r"'\x80'", NonAsciiXEscape, 1..5);
153 assert_err!(CharLit, r"'\x81'", NonAsciiXEscape, 1..5);
154 assert_err!(CharLit, r"'\x8a'", NonAsciiXEscape, 1..5);
155 assert_err!(CharLit, r"'\x8F'", NonAsciiXEscape, 1..5);
156 assert_err!(CharLit, r"'\xa0'", NonAsciiXEscape, 1..5);
157 assert_err!(CharLit, r"'\xB0'", NonAsciiXEscape, 1..5);
158 assert_err!(CharLit, r"'\xc3'", NonAsciiXEscape, 1..5);
159 assert_err!(CharLit, r"'\xDf'", NonAsciiXEscape, 1..5);
160 assert_err!(CharLit, r"'\xff'", NonAsciiXEscape, 1..5);
161 assert_err!(CharLit, r"'\xfF'", NonAsciiXEscape, 1..5);
162 assert_err!(CharLit, r"'\xFf'", NonAsciiXEscape, 1..5);
163 assert_err!(CharLit, r"'\xFF'", NonAsciiXEscape, 1..5);
164 }
165
166 #[test]
invalid_escapes()167 fn invalid_escapes() {
168 assert_err!(CharLit, r"'\a'", UnknownEscape, 1..3);
169 assert_err!(CharLit, r"'\y'", UnknownEscape, 1..3);
170 assert_err!(CharLit, r"'\", UnterminatedEscape, 1);
171 assert_err!(CharLit, r"'\x'", UnterminatedEscape, 1..4);
172 assert_err!(CharLit, r"'\x1'", InvalidXEscape, 1..5);
173 assert_err!(CharLit, r"'\xaj'", InvalidXEscape, 1..5);
174 assert_err!(CharLit, r"'\xjb'", InvalidXEscape, 1..5);
175 }
176
177 #[test]
invalid_unicode_escapes()178 fn invalid_unicode_escapes() {
179 assert_err!(CharLit, r"'\u'", UnicodeEscapeWithoutBrace, 1..3);
180 assert_err!(CharLit, r"'\u '", UnicodeEscapeWithoutBrace, 1..3);
181 assert_err!(CharLit, r"'\u3'", UnicodeEscapeWithoutBrace, 1..3);
182
183 assert_err!(CharLit, r"'\u{'", UnterminatedUnicodeEscape, 1..5);
184 assert_err!(CharLit, r"'\u{12'", UnterminatedUnicodeEscape, 1..7);
185 assert_err!(CharLit, r"'\u{a0b'", UnterminatedUnicodeEscape, 1..8);
186 assert_err!(CharLit, r"'\u{a0_b '", UnterminatedUnicodeEscape, 1..11);
187
188 assert_err!(CharLit, r"'\u{_}'", InvalidStartOfUnicodeEscape, 4);
189 assert_err!(CharLit, r"'\u{_5f}'", InvalidStartOfUnicodeEscape, 4);
190
191 assert_err!(CharLit, r"'\u{x}'", NonHexDigitInUnicodeEscape, 4);
192 assert_err!(CharLit, r"'\u{0x}'", NonHexDigitInUnicodeEscape, 5);
193 assert_err!(CharLit, r"'\u{3bx}'", NonHexDigitInUnicodeEscape, 6);
194 assert_err!(CharLit, r"'\u{3b_x}'", NonHexDigitInUnicodeEscape, 7);
195 assert_err!(CharLit, r"'\u{4x_}'", NonHexDigitInUnicodeEscape, 5);
196
197 assert_err!(CharLit, r"'\u{1234567}'", TooManyDigitInUnicodeEscape, 10);
198 assert_err!(CharLit, r"'\u{1234567}'", TooManyDigitInUnicodeEscape, 10);
199 assert_err!(CharLit, r"'\u{1_23_4_56_7}'", TooManyDigitInUnicodeEscape, 14);
200 assert_err!(CharLit, r"'\u{abcdef123}'", TooManyDigitInUnicodeEscape, 10);
201
202 assert_err!(CharLit, r"'\u{110000}'", InvalidUnicodeEscapeChar, 1..10);
203 }
204
205 #[test]
parse_err()206 fn parse_err() {
207 assert_err!(CharLit, r"''", EmptyCharLiteral, None);
208 assert_err!(CharLit, r"' ''", UnexpectedChar, 3);
209
210 assert_err!(CharLit, r"'", UnterminatedCharLiteral, None);
211 assert_err!(CharLit, r"'a", UnterminatedCharLiteral, None);
212 assert_err!(CharLit, r"'\n", UnterminatedCharLiteral, None);
213 assert_err!(CharLit, r"'\x35", UnterminatedCharLiteral, None);
214
215 assert_err!(CharLit, r"'ab'", OverlongCharLiteral, None);
216 assert_err!(CharLit, r"'a _'", OverlongCharLiteral, None);
217 assert_err!(CharLit, r"'\n3'", OverlongCharLiteral, None);
218
219 assert_err!(CharLit, r"", Empty, None);
220
221 assert_err!(CharLit, r"'''", UnescapedSingleQuote, 1);
222 assert_err!(CharLit, r"''''", UnescapedSingleQuote, 1);
223
224 assert_err!(CharLit, "'\n'", UnescapedSpecialWhitespace, 1);
225 assert_err!(CharLit, "'\t'", UnescapedSpecialWhitespace, 1);
226 assert_err!(CharLit, "'\r'", UnescapedSpecialWhitespace, 1);
227 }
228