summaryrefslogtreecommitdiffstats
path: root/third_party/rust/litrs/src/char/tests.rs
blob: 19219db73b6941483c5d88dcfb806965bed49470 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
use crate::{Literal, test_util::{assert_parse_ok_eq, assert_roundtrip}};
use super::CharLit;

// ===== Utility functions =======================================================================

macro_rules! check {
    ($lit:literal) => { check!($lit, stringify!($lit), "") };
    ($lit:literal, $input:expr, $suffix:literal) => {
        let input = $input;
        let expected = CharLit {
            raw: input,
            start_suffix: input.len() - $suffix.len(),
            value: $lit,
        };

        assert_parse_ok_eq(input, CharLit::parse(input), expected.clone(), "CharLit::parse");
        assert_parse_ok_eq(input, Literal::parse(input), Literal::Char(expected), "Literal::parse");
        let lit = CharLit::parse(input).unwrap();
        assert_eq!(lit.value(), $lit);
        assert_eq!(lit.suffix(), $suffix);
        assert_roundtrip(expected.to_owned(), input);
    };
}


// ===== Actual tests ============================================================================

#[test]
fn alphanumeric() {
    check!('a');
    check!('b');
    check!('y');
    check!('z');
    check!('A');
    check!('B');
    check!('Y');
    check!('Z');

    check!('0');
    check!('1');
    check!('8');
    check!('9');
}

#[test]
fn special_chars() {
    check!(' ');
    check!('!');
    check!('"');
    check!('#');
    check!('$');
    check!('%');
    check!('&');
    check!('(');
    check!(')');
    check!('*');
    check!('+');
    check!(',');
    check!('-');
    check!('.');
    check!('/');
    check!(':');
    check!(';');
    check!('<');
    check!('=');
    check!('>');
    check!('?');
    check!('@');
    check!('[');
    check!(']');
    check!('^');
    check!('_');
    check!('`');
    check!('{');
    check!('|');
    check!('}');
    check!('~');
}

#[test]
fn unicode() {
    check!('న');
    check!('犬');
    check!('🦊');
}

#[test]
fn quote_escapes() {
    check!('\'');
    check!('\"');
}

#[test]
fn ascii_escapes() {
    check!('\n');
    check!('\r');
    check!('\t');
    check!('\\');
    check!('\0');

    check!('\x00');
    check!('\x01');
    check!('\x0c');
    check!('\x0D');
    check!('\x13');
    check!('\x30');
    check!('\x30');
    check!('\x4B');
    check!('\x6b');
    check!('\x7F');
    check!('\x7f');
}

#[test]
fn unicode_escapes() {
    check!('\u{0}');
    check!('\u{00}');
    check!('\u{b}');
    check!('\u{B}');
    check!('\u{7e}');
    check!('\u{E4}');
    check!('\u{e4}');
    check!('\u{fc}');
    check!('\u{Fc}');
    check!('\u{fC}');
    check!('\u{FC}');
    check!('\u{b10}');
    check!('\u{B10}');
    check!('\u{0b10}');
    check!('\u{2764}');
    check!('\u{1f602}');
    check!('\u{1F602}');

    check!('\u{0}');
    check!('\u{0__}');
    check!('\u{3_b}');
    check!('\u{1_F_6_0_2}');
    check!('\u{1_F6_02_____}');
}

#[test]
fn suffixes() {
    check!('a', r##"'a'peter"##, "peter");
    check!('#', r##"'#'peter"##, "peter");
    check!('\n', r##"'\n'peter"##, "peter");
    check!('\'', r##"'\''peter"##, "peter");
    check!('\"', r##"'\"'peter"##, "peter");
}

#[test]
fn invald_ascii_escapes() {
    assert_err!(CharLit, r"'\x80'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\x81'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\x8a'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\x8F'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xa0'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xB0'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xc3'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xDf'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xff'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xfF'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xFf'", NonAsciiXEscape, 1..5);
    assert_err!(CharLit, r"'\xFF'", NonAsciiXEscape, 1..5);
}

#[test]
fn invalid_escapes() {
    assert_err!(CharLit, r"'\a'", UnknownEscape, 1..3);
    assert_err!(CharLit, r"'\y'", UnknownEscape, 1..3);
    assert_err!(CharLit, r"'\", UnterminatedEscape, 1);
    assert_err!(CharLit, r"'\x'", UnterminatedEscape, 1..4);
    assert_err!(CharLit, r"'\x1'", InvalidXEscape, 1..5);
    assert_err!(CharLit, r"'\xaj'", InvalidXEscape, 1..5);
    assert_err!(CharLit, r"'\xjb'", InvalidXEscape, 1..5);
}

#[test]
fn invalid_unicode_escapes() {
    assert_err!(CharLit, r"'\u'", UnicodeEscapeWithoutBrace, 1..3);
    assert_err!(CharLit, r"'\u '", UnicodeEscapeWithoutBrace, 1..3);
    assert_err!(CharLit, r"'\u3'", UnicodeEscapeWithoutBrace, 1..3);

    assert_err!(CharLit, r"'\u{'", UnterminatedUnicodeEscape, 1..5);
    assert_err!(CharLit, r"'\u{12'", UnterminatedUnicodeEscape, 1..7);
    assert_err!(CharLit, r"'\u{a0b'", UnterminatedUnicodeEscape, 1..8);
    assert_err!(CharLit, r"'\u{a0_b  '", UnterminatedUnicodeEscape, 1..11);

    assert_err!(CharLit, r"'\u{_}'", InvalidStartOfUnicodeEscape, 4);
    assert_err!(CharLit, r"'\u{_5f}'", InvalidStartOfUnicodeEscape, 4);

    assert_err!(CharLit, r"'\u{x}'", NonHexDigitInUnicodeEscape, 4);
    assert_err!(CharLit, r"'\u{0x}'", NonHexDigitInUnicodeEscape, 5);
    assert_err!(CharLit, r"'\u{3bx}'", NonHexDigitInUnicodeEscape, 6);
    assert_err!(CharLit, r"'\u{3b_x}'", NonHexDigitInUnicodeEscape, 7);
    assert_err!(CharLit, r"'\u{4x_}'", NonHexDigitInUnicodeEscape, 5);

    assert_err!(CharLit, r"'\u{1234567}'", TooManyDigitInUnicodeEscape, 10);
    assert_err!(CharLit, r"'\u{1234567}'", TooManyDigitInUnicodeEscape, 10);
    assert_err!(CharLit, r"'\u{1_23_4_56_7}'", TooManyDigitInUnicodeEscape, 14);
    assert_err!(CharLit, r"'\u{abcdef123}'", TooManyDigitInUnicodeEscape, 10);

    assert_err!(CharLit, r"'\u{110000}'", InvalidUnicodeEscapeChar, 1..10);
}

#[test]
fn parse_err() {
    assert_err!(CharLit, r"''", EmptyCharLiteral, None);
    assert_err!(CharLit, r"' ''", UnexpectedChar, 3);

    assert_err!(CharLit, r"'", UnterminatedCharLiteral, None);
    assert_err!(CharLit, r"'a", UnterminatedCharLiteral, None);
    assert_err!(CharLit, r"'\n", UnterminatedCharLiteral, None);
    assert_err!(CharLit, r"'\x35", UnterminatedCharLiteral, None);

    assert_err!(CharLit, r"'ab'", OverlongCharLiteral, None);
    assert_err!(CharLit, r"'a _'", OverlongCharLiteral, None);
    assert_err!(CharLit, r"'\n3'", OverlongCharLiteral, None);

    assert_err!(CharLit, r"", Empty, None);

    assert_err!(CharLit, r"'''", UnescapedSingleQuote, 1);
    assert_err!(CharLit, r"''''", UnescapedSingleQuote, 1);

    assert_err!(CharLit, "'\n'", UnescapedSpecialWhitespace, 1);
    assert_err!(CharLit, "'\t'", UnescapedSpecialWhitespace, 1);
    assert_err!(CharLit, "'\r'", UnescapedSpecialWhitespace, 1);
}