• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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