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