]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_lexer/src/unescape/tests.rs
Rollup merge of #107015 - cuviper:ra-riscv64, r=Mark-Simulacrum
[rust.git] / compiler / rustc_lexer / src / unescape / tests.rs
1 use super::*;
2
3 #[test]
4 fn test_unescape_char_bad() {
5     fn check(literal_text: &str, expected_error: EscapeError) {
6         assert_eq!(unescape_char(literal_text), Err(expected_error));
7     }
8
9     check("", EscapeError::ZeroChars);
10     check(r"\", EscapeError::LoneSlash);
11
12     check("\n", EscapeError::EscapeOnlyChar);
13     check("\t", EscapeError::EscapeOnlyChar);
14     check("'", EscapeError::EscapeOnlyChar);
15     check("\r", EscapeError::BareCarriageReturn);
16
17     check("spam", EscapeError::MoreThanOneChar);
18     check(r"\x0ff", EscapeError::MoreThanOneChar);
19     check(r#"\"a"#, EscapeError::MoreThanOneChar);
20     check(r"\na", EscapeError::MoreThanOneChar);
21     check(r"\ra", EscapeError::MoreThanOneChar);
22     check(r"\ta", EscapeError::MoreThanOneChar);
23     check(r"\\a", EscapeError::MoreThanOneChar);
24     check(r"\'a", EscapeError::MoreThanOneChar);
25     check(r"\0a", EscapeError::MoreThanOneChar);
26     check(r"\u{0}x", EscapeError::MoreThanOneChar);
27     check(r"\u{1F63b}}", EscapeError::MoreThanOneChar);
28
29     check(r"\v", EscapeError::InvalidEscape);
30     check(r"\💩", EscapeError::InvalidEscape);
31     check(r"\●", EscapeError::InvalidEscape);
32     check("\\\r", EscapeError::InvalidEscape);
33
34     check(r"\x", EscapeError::TooShortHexEscape);
35     check(r"\x0", EscapeError::TooShortHexEscape);
36     check(r"\xf", EscapeError::TooShortHexEscape);
37     check(r"\xa", EscapeError::TooShortHexEscape);
38     check(r"\xx", EscapeError::InvalidCharInHexEscape);
39     check(r"\xы", EscapeError::InvalidCharInHexEscape);
40     check(r"\x🦀", EscapeError::InvalidCharInHexEscape);
41     check(r"\xtt", EscapeError::InvalidCharInHexEscape);
42     check(r"\xff", EscapeError::OutOfRangeHexEscape);
43     check(r"\xFF", EscapeError::OutOfRangeHexEscape);
44     check(r"\x80", EscapeError::OutOfRangeHexEscape);
45
46     check(r"\u", EscapeError::NoBraceInUnicodeEscape);
47     check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape);
48     check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape);
49     check(r"\u{", EscapeError::UnclosedUnicodeEscape);
50     check(r"\u{0000", EscapeError::UnclosedUnicodeEscape);
51     check(r"\u{}", EscapeError::EmptyUnicodeEscape);
52     check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape);
53     check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape);
54     check(r"\u{FFFFFF}", EscapeError::OutOfRangeUnicodeEscape);
55     check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape);
56     check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape);
57
58     check(r"\u{DC00}", EscapeError::LoneSurrogateUnicodeEscape);
59     check(r"\u{DDDD}", EscapeError::LoneSurrogateUnicodeEscape);
60     check(r"\u{DFFF}", EscapeError::LoneSurrogateUnicodeEscape);
61
62     check(r"\u{D800}", EscapeError::LoneSurrogateUnicodeEscape);
63     check(r"\u{DAAA}", EscapeError::LoneSurrogateUnicodeEscape);
64     check(r"\u{DBFF}", EscapeError::LoneSurrogateUnicodeEscape);
65 }
66
67 #[test]
68 fn test_unescape_char_good() {
69     fn check(literal_text: &str, expected_char: char) {
70         assert_eq!(unescape_char(literal_text), Ok(expected_char));
71     }
72
73     check("a", 'a');
74     check("ы", 'ы');
75     check("🦀", '🦀');
76
77     check(r#"\""#, '"');
78     check(r"\n", '\n');
79     check(r"\r", '\r');
80     check(r"\t", '\t');
81     check(r"\\", '\\');
82     check(r"\'", '\'');
83     check(r"\0", '\0');
84
85     check(r"\x00", '\0');
86     check(r"\x5a", 'Z');
87     check(r"\x5A", 'Z');
88     check(r"\x7f", 127 as char);
89
90     check(r"\u{0}", '\0');
91     check(r"\u{000000}", '\0');
92     check(r"\u{41}", 'A');
93     check(r"\u{0041}", 'A');
94     check(r"\u{00_41}", 'A');
95     check(r"\u{4__1__}", 'A');
96     check(r"\u{1F63b}", '😻');
97 }
98
99 #[test]
100 fn test_unescape_str_warn() {
101     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
102         let mut unescaped = Vec::with_capacity(literal.len());
103         unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
104         assert_eq!(unescaped, expected);
105     }
106
107     // Check we can handle escaped newlines at the end of a file.
108     check("\\\n", &[]);
109     check("\\\n ", &[]);
110
111     check(
112         "\\\n \u{a0} x",
113         &[
114             (0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
115             (3..5, Ok('\u{a0}')),
116             (5..6, Ok(' ')),
117             (6..7, Ok('x')),
118         ],
119     );
120     check("\\\n  \n  x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
121 }
122
123 #[test]
124 fn test_unescape_str_good() {
125     fn check(literal_text: &str, expected: &str) {
126         let mut buf = Ok(String::with_capacity(literal_text.len()));
127         unescape_literal(literal_text, Mode::Str, &mut |range, c| {
128             if let Ok(b) = &mut buf {
129                 match c {
130                     Ok(c) => b.push(c),
131                     Err(e) => buf = Err((range, e)),
132                 }
133             }
134         });
135         assert_eq!(buf.as_deref(), Ok(expected))
136     }
137
138     check("foo", "foo");
139     check("", "");
140     check(" \t\n", " \t\n");
141
142     check("hello \\\n     world", "hello world");
143     check("thread's", "thread's")
144 }
145
146 #[test]
147 fn test_unescape_byte_bad() {
148     fn check(literal_text: &str, expected_error: EscapeError) {
149         assert_eq!(unescape_byte(literal_text), Err(expected_error));
150     }
151
152     check("", EscapeError::ZeroChars);
153     check(r"\", EscapeError::LoneSlash);
154
155     check("\n", EscapeError::EscapeOnlyChar);
156     check("\t", EscapeError::EscapeOnlyChar);
157     check("'", EscapeError::EscapeOnlyChar);
158     check("\r", EscapeError::BareCarriageReturn);
159
160     check("spam", EscapeError::MoreThanOneChar);
161     check(r"\x0ff", EscapeError::MoreThanOneChar);
162     check(r#"\"a"#, EscapeError::MoreThanOneChar);
163     check(r"\na", EscapeError::MoreThanOneChar);
164     check(r"\ra", EscapeError::MoreThanOneChar);
165     check(r"\ta", EscapeError::MoreThanOneChar);
166     check(r"\\a", EscapeError::MoreThanOneChar);
167     check(r"\'a", EscapeError::MoreThanOneChar);
168     check(r"\0a", EscapeError::MoreThanOneChar);
169
170     check(r"\v", EscapeError::InvalidEscape);
171     check(r"\💩", EscapeError::InvalidEscape);
172     check(r"\●", EscapeError::InvalidEscape);
173
174     check(r"\x", EscapeError::TooShortHexEscape);
175     check(r"\x0", EscapeError::TooShortHexEscape);
176     check(r"\xa", EscapeError::TooShortHexEscape);
177     check(r"\xf", EscapeError::TooShortHexEscape);
178     check(r"\xx", EscapeError::InvalidCharInHexEscape);
179     check(r"\xы", EscapeError::InvalidCharInHexEscape);
180     check(r"\x🦀", EscapeError::InvalidCharInHexEscape);
181     check(r"\xtt", EscapeError::InvalidCharInHexEscape);
182
183     check(r"\u", EscapeError::NoBraceInUnicodeEscape);
184     check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape);
185     check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape);
186     check(r"\u{", EscapeError::UnclosedUnicodeEscape);
187     check(r"\u{0000", EscapeError::UnclosedUnicodeEscape);
188     check(r"\u{}", EscapeError::EmptyUnicodeEscape);
189     check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape);
190     check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape);
191
192     check("ы", EscapeError::NonAsciiCharInByte);
193     check("🦀", EscapeError::NonAsciiCharInByte);
194
195     check(r"\u{0}", EscapeError::UnicodeEscapeInByte);
196     check(r"\u{000000}", EscapeError::UnicodeEscapeInByte);
197     check(r"\u{41}", EscapeError::UnicodeEscapeInByte);
198     check(r"\u{0041}", EscapeError::UnicodeEscapeInByte);
199     check(r"\u{00_41}", EscapeError::UnicodeEscapeInByte);
200     check(r"\u{4__1__}", EscapeError::UnicodeEscapeInByte);
201     check(r"\u{1F63b}", EscapeError::UnicodeEscapeInByte);
202     check(r"\u{0}x", EscapeError::UnicodeEscapeInByte);
203     check(r"\u{1F63b}}", EscapeError::UnicodeEscapeInByte);
204     check(r"\u{FFFFFF}", EscapeError::UnicodeEscapeInByte);
205     check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte);
206     check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte);
207     check(r"\u{DC00}", EscapeError::UnicodeEscapeInByte);
208     check(r"\u{DDDD}", EscapeError::UnicodeEscapeInByte);
209     check(r"\u{DFFF}", EscapeError::UnicodeEscapeInByte);
210     check(r"\u{D800}", EscapeError::UnicodeEscapeInByte);
211     check(r"\u{DAAA}", EscapeError::UnicodeEscapeInByte);
212     check(r"\u{DBFF}", EscapeError::UnicodeEscapeInByte);
213 }
214
215 #[test]
216 fn test_unescape_byte_good() {
217     fn check(literal_text: &str, expected_byte: u8) {
218         assert_eq!(unescape_byte(literal_text), Ok(expected_byte));
219     }
220
221     check("a", b'a');
222
223     check(r#"\""#, b'"');
224     check(r"\n", b'\n');
225     check(r"\r", b'\r');
226     check(r"\t", b'\t');
227     check(r"\\", b'\\');
228     check(r"\'", b'\'');
229     check(r"\0", b'\0');
230
231     check(r"\x00", b'\0');
232     check(r"\x5a", b'Z');
233     check(r"\x5A", b'Z');
234     check(r"\x7f", 127);
235     check(r"\x80", 128);
236     check(r"\xff", 255);
237     check(r"\xFF", 255);
238 }
239
240 #[test]
241 fn test_unescape_byte_str_good() {
242     fn check(literal_text: &str, expected: &[u8]) {
243         let mut buf = Ok(Vec::with_capacity(literal_text.len()));
244         unescape_literal(literal_text, Mode::ByteStr, &mut |range, c| {
245             if let Ok(b) = &mut buf {
246                 match c {
247                     Ok(c) => b.push(byte_from_char(c)),
248                     Err(e) => buf = Err((range, e)),
249                 }
250             }
251         });
252         assert_eq!(buf.as_deref(), Ok(expected))
253     }
254
255     check("foo", b"foo");
256     check("", b"");
257     check(" \t\n", b" \t\n");
258
259     check("hello \\\n     world", b"hello world");
260     check("thread's", b"thread's")
261 }
262
263 #[test]
264 fn test_unescape_raw_str() {
265     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
266         let mut unescaped = Vec::with_capacity(literal.len());
267         unescape_literal(literal, Mode::RawStr, &mut |range, res| unescaped.push((range, res)));
268         assert_eq!(unescaped, expected);
269     }
270
271     check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
272     check("\rx", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString)), (1..2, Ok('x'))]);
273 }
274
275 #[test]
276 fn test_unescape_raw_byte_str() {
277     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
278         let mut unescaped = Vec::with_capacity(literal.len());
279         unescape_literal(literal, Mode::RawByteStr, &mut |range, res| unescaped.push((range, res)));
280         assert_eq!(unescaped, expected);
281     }
282
283     check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
284     check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByte))]);
285     check("🦀a", &[(0..4, Err(EscapeError::NonAsciiCharInByte)), (4..5, Ok('a'))]);
286 }