]> git.proxmox.com Git - rustc.git/blob - src/vendor/toml/tests/parser.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / vendor / toml / tests / parser.rs
1 extern crate toml;
2
3 use toml::Value;
4
5 macro_rules! bad {
6 ($s:expr, $msg:expr) => ({
7 match $s.parse::<Value>() {
8 Ok(s) => panic!("successfully parsed as {}", s),
9 Err(e) => {
10 let e = e.to_string();
11 assert!(e.contains($msg), "error: {}", e);
12 }
13 }
14 })
15 }
16
17 #[test]
18 fn crlf() {
19 "\
20 [project]\r\n\
21 \r\n\
22 name = \"splay\"\r\n\
23 version = \"0.1.0\"\r\n\
24 authors = [\"alex@crichton.co\"]\r\n\
25 \r\n\
26 [[lib]]\r\n\
27 \r\n\
28 path = \"lib.rs\"\r\n\
29 name = \"splay\"\r\n\
30 description = \"\"\"\
31 A Rust implementation of a TAR file reader and writer. This library does not\r\n\
32 currently handle compression, but it is abstract over all I/O readers and\r\n\
33 writers. Additionally, great lengths are taken to ensure that the entire\r\n\
34 contents are never required to be entirely resident in memory all at once.\r\n\
35 \"\"\"\
36 ".parse::<Value>().unwrap();
37 }
38
39 #[test]
40 fn fun_with_strings() {
41 let table = r#"
42 bar = "\U00000000"
43 key1 = "One\nTwo"
44 key2 = """One\nTwo"""
45 key3 = """
46 One
47 Two"""
48
49 key4 = "The quick brown fox jumps over the lazy dog."
50 key5 = """
51 The quick brown \
52
53
54 fox jumps over \
55 the lazy dog."""
56 key6 = """\
57 The quick brown \
58 fox jumps over \
59 the lazy dog.\
60 """
61 # What you see is what you get.
62 winpath = 'C:\Users\nodejs\templates'
63 winpath2 = '\\ServerX\admin$\system32\'
64 quoted = 'Tom "Dubs" Preston-Werner'
65 regex = '<\i\c*\s*>'
66
67 regex2 = '''I [dw]on't need \d{2} apples'''
68 lines = '''
69 The first newline is
70 trimmed in raw strings.
71 All other whitespace
72 is preserved.
73 '''
74 "#.parse::<Value>().unwrap();
75 assert_eq!(table["bar"].as_str(), Some("\0"));
76 assert_eq!(table["key1"].as_str(), Some("One\nTwo"));
77 assert_eq!(table["key2"].as_str(), Some("One\nTwo"));
78 assert_eq!(table["key3"].as_str(), Some("One\nTwo"));
79
80 let msg = "The quick brown fox jumps over the lazy dog.";
81 assert_eq!(table["key4"].as_str(), Some(msg));
82 assert_eq!(table["key5"].as_str(), Some(msg));
83 assert_eq!(table["key6"].as_str(), Some(msg));
84
85 assert_eq!(table["winpath"].as_str(), Some(r"C:\Users\nodejs\templates"));
86 assert_eq!(table["winpath2"].as_str(), Some(r"\\ServerX\admin$\system32\"));
87 assert_eq!(table["quoted"].as_str(), Some(r#"Tom "Dubs" Preston-Werner"#));
88 assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>"));
89 assert_eq!(table["regex2"].as_str(), Some(r"I [dw]on't need \d{2} apples"));
90 assert_eq!(table["lines"].as_str(),
91 Some("The first newline is\n\
92 trimmed in raw strings.\n\
93 All other whitespace\n\
94 is preserved.\n"));
95 }
96
97 #[test]
98 fn tables_in_arrays() {
99 let table = r#"
100 [[foo]]
101 #…
102 [foo.bar]
103 #…
104
105 [[foo]] # ...
106 #…
107 [foo.bar]
108 #...
109 "#.parse::<Value>().unwrap();
110 table["foo"][0]["bar"].as_table().unwrap();
111 table["foo"][1]["bar"].as_table().unwrap();
112 }
113
114 #[test]
115 fn empty_table() {
116 let table = r#"
117 [foo]"#.parse::<Value>().unwrap();
118 table["foo"].as_table().unwrap();
119 }
120
121 #[test]
122 fn fruit() {
123 let table = r#"
124 [[fruit]]
125 name = "apple"
126
127 [fruit.physical]
128 color = "red"
129 shape = "round"
130
131 [[fruit.variety]]
132 name = "red delicious"
133
134 [[fruit.variety]]
135 name = "granny smith"
136
137 [[fruit]]
138 name = "banana"
139
140 [[fruit.variety]]
141 name = "plantain"
142 "#.parse::<Value>().unwrap();
143 assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple"));
144 assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red"));
145 assert_eq!(table["fruit"][0]["physical"]["shape"].as_str(), Some("round"));
146 assert_eq!(table["fruit"][0]["variety"][0]["name"].as_str(), Some("red delicious"));
147 assert_eq!(table["fruit"][0]["variety"][1]["name"].as_str(), Some("granny smith"));
148 assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana"));
149 assert_eq!(table["fruit"][1]["variety"][0]["name"].as_str(), Some("plantain"));
150 }
151
152 #[test]
153 fn stray_cr() {
154 "\r".parse::<Value>().unwrap_err();
155 "a = [ \r ]".parse::<Value>().unwrap_err();
156 "a = \"\"\"\r\"\"\"".parse::<Value>().unwrap_err();
157 "a = \"\"\"\\ \r \"\"\"".parse::<Value>().unwrap_err();
158 "a = '''\r'''".parse::<Value>().unwrap_err();
159 "a = '\r'".parse::<Value>().unwrap_err();
160 "a = \"\r\"".parse::<Value>().unwrap_err();
161 }
162
163 #[test]
164 fn blank_literal_string() {
165 let table = "foo = ''".parse::<Value>().unwrap();
166 assert_eq!(table["foo"].as_str(), Some(""));
167 }
168
169 #[test]
170 fn many_blank() {
171 let table = "foo = \"\"\"\n\n\n\"\"\"".parse::<Value>().unwrap();
172 assert_eq!(table["foo"].as_str(), Some("\n\n"));
173 }
174
175 #[test]
176 fn literal_eats_crlf() {
177 let table = "
178 foo = \"\"\"\\\r\n\"\"\"
179 bar = \"\"\"\\\r\n \r\n \r\n a\"\"\"
180 ".parse::<Value>().unwrap();
181 assert_eq!(table["foo"].as_str(), Some(""));
182 assert_eq!(table["bar"].as_str(), Some("a"));
183 }
184
185 #[test]
186 fn string_no_newline() {
187 "a = \"\n\"".parse::<Value>().unwrap_err();
188 "a = '\n'".parse::<Value>().unwrap_err();
189 }
190
191 #[test]
192 fn bad_leading_zeros() {
193 "a = 00".parse::<Value>().unwrap_err();
194 "a = -00".parse::<Value>().unwrap_err();
195 "a = +00".parse::<Value>().unwrap_err();
196 "a = 00.0".parse::<Value>().unwrap_err();
197 "a = -00.0".parse::<Value>().unwrap_err();
198 "a = +00.0".parse::<Value>().unwrap_err();
199 "a = 9223372036854775808".parse::<Value>().unwrap_err();
200 "a = -9223372036854775809".parse::<Value>().unwrap_err();
201 }
202
203 #[test]
204 fn bad_floats() {
205 "a = 0.".parse::<Value>().unwrap_err();
206 "a = 0.e".parse::<Value>().unwrap_err();
207 "a = 0.E".parse::<Value>().unwrap_err();
208 "a = 0.0E".parse::<Value>().unwrap_err();
209 "a = 0.0e".parse::<Value>().unwrap_err();
210 "a = 0.0e-".parse::<Value>().unwrap_err();
211 "a = 0.0e+".parse::<Value>().unwrap_err();
212 "a = 0.0e+00".parse::<Value>().unwrap_err();
213 }
214
215 #[test]
216 fn floats() {
217 macro_rules! t {
218 ($actual:expr, $expected:expr) => ({
219 let f = format!("foo = {}", $actual);
220 println!("{}", f);
221 let a = f.parse::<Value>().unwrap();
222 assert_eq!(a["foo"].as_float().unwrap(), $expected);
223 })
224 }
225
226 t!("1.0", 1.0);
227 t!("1.0e0", 1.0);
228 t!("1.0e+0", 1.0);
229 t!("1.0e-0", 1.0);
230 t!("1.001e-0", 1.001);
231 t!("2e10", 2e10);
232 t!("2e+10", 2e10);
233 t!("2e-10", 2e-10);
234 t!("2_0.0", 20.0);
235 t!("2_0.0_0e1_0", 20.0e10);
236 t!("2_0.1_0e1_0", 20.1e10);
237 }
238
239 #[test]
240 fn bare_key_names() {
241 let a = "
242 foo = 3
243 foo_3 = 3
244 foo_-2--3--r23f--4-f2-4 = 3
245 _ = 3
246 - = 3
247 8 = 8
248 \"a\" = 3
249 \"!\" = 3
250 \"a^b\" = 3
251 \"\\\"\" = 3
252 \"character encoding\" = \"value\"
253 'ʎǝʞ' = \"value\"
254 ".parse::<Value>().unwrap();
255 &a["foo"];
256 &a["-"];
257 &a["_"];
258 &a["8"];
259 &a["foo_3"];
260 &a["foo_-2--3--r23f--4-f2-4"];
261 &a["a"];
262 &a["!"];
263 &a["\""];
264 &a["character encoding"];
265 &a["ʎǝʞ"];
266 }
267
268 #[test]
269 fn bad_keys() {
270 "key\n=3".parse::<Value>().unwrap_err();
271 "key=\n3".parse::<Value>().unwrap_err();
272 "key|=3".parse::<Value>().unwrap_err();
273 "\"\"=3".parse::<Value>().unwrap_err();
274 "=3".parse::<Value>().unwrap_err();
275 "\"\"|=3".parse::<Value>().unwrap_err();
276 "\"\n\"|=3".parse::<Value>().unwrap_err();
277 "\"\r\"|=3".parse::<Value>().unwrap_err();
278 }
279
280 #[test]
281 fn bad_table_names() {
282 "[]".parse::<Value>().unwrap_err();
283 "[.]".parse::<Value>().unwrap_err();
284 "[\"\".\"\"]".parse::<Value>().unwrap_err();
285 "[a.]".parse::<Value>().unwrap_err();
286 "[\"\"]".parse::<Value>().unwrap_err();
287 "[!]".parse::<Value>().unwrap_err();
288 "[\"\n\"]".parse::<Value>().unwrap_err();
289 "[a.b]\n[a.\"b\"]".parse::<Value>().unwrap_err();
290 "[']".parse::<Value>().unwrap_err();
291 "[''']".parse::<Value>().unwrap_err();
292 "['''''']".parse::<Value>().unwrap_err();
293 "['\n']".parse::<Value>().unwrap_err();
294 "['\r\n']".parse::<Value>().unwrap_err();
295 }
296
297 #[test]
298 fn table_names() {
299 let a = "
300 [a.\"b\"]
301 [\"f f\"]
302 [\"f.f\"]
303 [\"\\\"\"]
304 ['a.a']
305 ['\"\"']
306 ".parse::<Value>().unwrap();
307 println!("{:?}", a);
308 &a["a"]["b"];
309 &a["f f"];
310 &a["f.f"];
311 &a["\""];
312 &a["\"\""];
313 }
314
315 #[test]
316 fn invalid_bare_numeral() {
317 "4".parse::<Value>().unwrap_err();
318 }
319
320 #[test]
321 fn inline_tables() {
322 "a = {}".parse::<Value>().unwrap();
323 "a = {b=1}".parse::<Value>().unwrap();
324 "a = { b = 1 }".parse::<Value>().unwrap();
325 "a = {a=1,b=2}".parse::<Value>().unwrap();
326 "a = {a=1,b=2,c={}}".parse::<Value>().unwrap();
327 "a = {a=1,}".parse::<Value>().unwrap_err();
328 "a = {,}".parse::<Value>().unwrap_err();
329 "a = {a=1,a=1}".parse::<Value>().unwrap_err();
330 "a = {\n}".parse::<Value>().unwrap_err();
331 "a = {".parse::<Value>().unwrap_err();
332 "a = {a=[\n]}".parse::<Value>().unwrap();
333 "a = {\"a\"=[\n]}".parse::<Value>().unwrap();
334 "a = [\n{},\n{},\n]".parse::<Value>().unwrap();
335 }
336
337 #[test]
338 fn number_underscores() {
339 macro_rules! t {
340 ($actual:expr, $expected:expr) => ({
341 let f = format!("foo = {}", $actual);
342 let table = f.parse::<Value>().unwrap();
343 assert_eq!(table["foo"].as_integer().unwrap(), $expected);
344 })
345 }
346
347 t!("1_0", 10);
348 t!("1_0_0", 100);
349 t!("1_000", 1000);
350 t!("+1_000", 1000);
351 t!("-1_000", -1000);
352 }
353
354 #[test]
355 fn bad_underscores() {
356 bad!("foo = 0_", "invalid number");
357 bad!("foo = 0__0", "invalid number");
358 bad!("foo = __0", "invalid number");
359 bad!("foo = 1_0_", "invalid number");
360 }
361
362 #[test]
363 fn bad_unicode_codepoint() {
364 bad!("foo = \"\\uD800\"", "invalid escape value");
365 }
366
367 #[test]
368 fn bad_strings() {
369 bad!("foo = \"\\uxx\"", "invalid hex escape");
370 bad!("foo = \"\\u\"", "invalid hex escape");
371 bad!("foo = \"\\", "unterminated");
372 bad!("foo = '", "unterminated");
373 }
374
375 #[test]
376 fn empty_string() {
377 assert_eq!("foo = \"\"".parse::<Value>()
378 .unwrap()["foo"]
379 .as_str()
380 .unwrap(),
381 "");
382 }
383
384 #[test]
385 fn booleans() {
386 let table = "foo = true".parse::<Value>().unwrap();
387 assert_eq!(table["foo"].as_bool(), Some(true));
388
389 let table = "foo = false".parse::<Value>().unwrap();
390 assert_eq!(table["foo"].as_bool(), Some(false));
391
392 assert!("foo = true2".parse::<Value>().is_err());
393 assert!("foo = false2".parse::<Value>().is_err());
394 assert!("foo = t1".parse::<Value>().is_err());
395 assert!("foo = f2".parse::<Value>().is_err());
396 }
397
398 #[test]
399 fn bad_nesting() {
400 bad!("
401 a = [2]
402 [[a]]
403 b = 5
404 ", "duplicate key: `a`");
405 bad!("
406 a = 1
407 [a.b]
408 ", "duplicate key: `a`");
409 bad!("
410 a = []
411 [a.b]
412 ", "duplicate key: `a`");
413 bad!("
414 a = []
415 [[a.b]]
416 ", "duplicate key: `a`");
417 bad!("
418 [a]
419 b = { c = 2, d = {} }
420 [a.b]
421 c = 2
422 ", "duplicate key: `b`");
423 }
424
425 #[test]
426 fn bad_table_redefine() {
427 bad!("
428 [a]
429 foo=\"bar\"
430 [a.b]
431 foo=\"bar\"
432 [a]
433 ", "redefinition of table `a`");
434 bad!("
435 [a]
436 foo=\"bar\"
437 b = { foo = \"bar\" }
438 [a]
439 ", "redefinition of table `a`");
440 bad!("
441 [a]
442 b = {}
443 [a.b]
444 ", "duplicate key: `b`");
445
446 bad!("
447 [a]
448 b = {}
449 [a]
450 ", "redefinition of table `a`");
451 }
452
453 #[test]
454 fn datetimes() {
455 macro_rules! t {
456 ($actual:expr) => ({
457 let f = format!("foo = {}", $actual);
458 let toml = f.parse::<Value>().expect(&format!("failed: {}", f));
459 assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual);
460 })
461 }
462
463 t!("2016-09-09T09:09:09Z");
464 t!("2016-09-09T09:09:09.1Z");
465 t!("2016-09-09T09:09:09.2+10:00");
466 t!("2016-09-09T09:09:09.0123456789-02:00");
467 bad!("foo = 2016-09-09T09:09:09.Z", "failed to parse date");
468 bad!("foo = 2016-9-09T09:09:09Z", "failed to parse date");
469 bad!("foo = 2016-09-09T09:09:09+2:00", "failed to parse date");
470 bad!("foo = 2016-09-09T09:09:09-2:00", "failed to parse date");
471 bad!("foo = 2016-09-09T09:09:09Z-2:00", "failed to parse date");
472 }
473
474 #[test]
475 fn require_newline_after_value() {
476 bad!("0=0r=false", "invalid number at line 1");
477 bad!(r#"
478 0=""o=""m=""r=""00="0"q="""0"""e="""0"""
479 "#, "expected newline");
480 bad!(r#"
481 [[0000l0]]
482 0="0"[[0000l0]]
483 0="0"[[0000l0]]
484 0="0"l="0"
485 "#, "expected newline");
486 bad!(r#"
487 0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z]
488 "#, "expected newline");
489 bad!(r#"
490 0=0r0=0r=false
491 "#, "invalid number at line 2");
492 bad!(r#"
493 0=0r0=0r=falsefal=false
494 "#, "invalid number at line 2");
495 }