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