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