1 | #![allow (clippy::let_underscore_untyped, clippy::uninlined_format_args)] |
2 | |
3 | use serde_json::{json, Value}; |
4 | |
5 | macro_rules! bad { |
6 | ($toml:expr, $msg:expr) => { |
7 | match basic_toml::from_str::<Value>($toml) { |
8 | Ok(s) => panic!("parsed to: {:#?}" , s), |
9 | Err(e) => assert_eq!(e.to_string(), $msg), |
10 | } |
11 | }; |
12 | } |
13 | |
14 | #[test] |
15 | fn crlf() { |
16 | let toml = "\ |
17 | [project] \r\n\ |
18 | \r\n\ |
19 | name = \"splay \"\r\n\ |
20 | version = \"0.1.0 \"\r\n\ |
21 | authors = [ \"alex@crichton.co \"] \r\n\ |
22 | \r\n\ |
23 | [[lib]] \r\n\ |
24 | \r\n\ |
25 | path = \"lib.rs \"\r\n\ |
26 | name = \"splay \"\r\n\ |
27 | description = \"\"\"\ |
28 | A Rust implementation of a TAR file reader and writer. This library does not \r\n\ |
29 | currently handle compression, but it is abstract over all I/O readers and \r\n\ |
30 | writers. Additionally, great lengths are taken to ensure that the entire \r\n\ |
31 | contents are never required to be entirely resident in memory all at once. \r\n\ |
32 | \"\"\"\ |
33 | " ; |
34 | basic_toml::from_str::<Value>(toml).unwrap(); |
35 | } |
36 | |
37 | #[test] |
38 | fn fun_with_strings() { |
39 | let toml = r#" |
40 | bar = "\U00000000" |
41 | key1 = "One\nTwo" |
42 | key2 = """One\nTwo""" |
43 | key3 = """ |
44 | One |
45 | Two""" |
46 | |
47 | key4 = "The quick brown fox jumps over the lazy dog." |
48 | key5 = """ |
49 | The quick brown \ |
50 | |
51 | |
52 | fox jumps over \ |
53 | the lazy dog.""" |
54 | key6 = """\ |
55 | The quick brown \ |
56 | fox jumps over \ |
57 | the lazy dog.\ |
58 | """ |
59 | # What you see is what you get. |
60 | winpath = 'C:\Users\nodejs\templates' |
61 | winpath2 = '\\ServerX\admin$\system32\' |
62 | quoted = 'Tom "Dubs" Preston-Werner' |
63 | regex = '<\i\c*\s*>' |
64 | |
65 | regex2 = '''I [dw]on't need \d{2} apples''' |
66 | lines = ''' |
67 | The first newline is |
68 | trimmed in raw strings. |
69 | All other whitespace |
70 | is preserved. |
71 | ''' |
72 | "# ; |
73 | let table: Value = basic_toml::from_str(toml).unwrap(); |
74 | assert_eq!(table["bar" ], json!(" \0" )); |
75 | assert_eq!(table["key1" ], json!("One \nTwo" )); |
76 | assert_eq!(table["key2" ], json!("One \nTwo" )); |
77 | assert_eq!(table["key3" ], json!("One \nTwo" )); |
78 | |
79 | let msg = "The quick brown fox jumps over the lazy dog." ; |
80 | assert_eq!(table["key4" ], json!(msg)); |
81 | assert_eq!(table["key5" ], json!(msg)); |
82 | assert_eq!(table["key6" ], json!(msg)); |
83 | |
84 | assert_eq!(table["winpath" ], json!(r"C:\Users\nodejs\templates" )); |
85 | assert_eq!(table["winpath2" ], json!(r"\\ServerX\admin$\system32\" )); |
86 | assert_eq!(table["quoted" ], json!(r#"Tom "Dubs" Preston-Werner"# )); |
87 | assert_eq!(table["regex" ], json!(r"<\i\c*\s*>" )); |
88 | assert_eq!(table["regex2" ], json!(r"I [dw]on't need \d{2} apples" )); |
89 | assert_eq!( |
90 | table["lines" ], |
91 | json!( |
92 | "The first newline is \n\ |
93 | trimmed in raw strings. \n\ |
94 | All other whitespace \n\ |
95 | is preserved. \n" |
96 | ) |
97 | ); |
98 | } |
99 | |
100 | #[test] |
101 | fn tables_in_arrays() { |
102 | let toml = " |
103 | [[foo]] |
104 | #… |
105 | [foo.bar] |
106 | #… |
107 | |
108 | [[foo]] # ... |
109 | #… |
110 | [foo.bar] |
111 | #... |
112 | " ; |
113 | let table: Value = basic_toml::from_str(toml).unwrap(); |
114 | table["foo" ][0]["bar" ].as_object().unwrap(); |
115 | table["foo" ][1]["bar" ].as_object().unwrap(); |
116 | } |
117 | |
118 | #[test] |
119 | fn empty_table() { |
120 | let toml = " |
121 | [foo]" ; |
122 | let table: Value = basic_toml::from_str(toml).unwrap(); |
123 | table["foo" ].as_object().unwrap(); |
124 | } |
125 | |
126 | #[test] |
127 | fn fruit() { |
128 | let toml = r#" |
129 | [[fruit]] |
130 | name = "apple" |
131 | |
132 | [fruit.physical] |
133 | color = "red" |
134 | shape = "round" |
135 | |
136 | [[fruit.variety]] |
137 | name = "red delicious" |
138 | |
139 | [[fruit.variety]] |
140 | name = "granny smith" |
141 | |
142 | [[fruit]] |
143 | name = "banana" |
144 | |
145 | [[fruit.variety]] |
146 | name = "plantain" |
147 | "# ; |
148 | let table: Value = basic_toml::from_str(toml).unwrap(); |
149 | assert_eq!(table["fruit" ][0]["name" ], json!("apple" )); |
150 | assert_eq!(table["fruit" ][0]["physical" ]["color" ], json!("red" )); |
151 | assert_eq!(table["fruit" ][0]["physical" ]["shape" ], json!("round" )); |
152 | assert_eq!( |
153 | table["fruit" ][0]["variety" ][0]["name" ], |
154 | json!("red delicious" ) |
155 | ); |
156 | assert_eq!( |
157 | table["fruit" ][0]["variety" ][1]["name" ], |
158 | json!("granny smith" ) |
159 | ); |
160 | assert_eq!(table["fruit" ][1]["name" ], json!("banana" )); |
161 | assert_eq!(table["fruit" ][1]["variety" ][0]["name" ], json!("plantain" )); |
162 | } |
163 | |
164 | #[test] |
165 | fn stray_cr() { |
166 | bad!(" \r" , "unexpected character found: ` \\r` at line 1 column 1" ); |
167 | bad!( |
168 | "a = [ \r ]" , |
169 | "unexpected character found: ` \\r` at line 1 column 7" |
170 | ); |
171 | bad!( |
172 | "a = \"\"\"\r\"\"\"" , |
173 | "invalid character in string: ` \\r` at line 1 column 8" |
174 | ); |
175 | bad!( |
176 | "a = \"\"\"\\ \r \"\"\"" , |
177 | "invalid escape character in string: ` ` at line 1 column 9" |
178 | ); |
179 | bad!( |
180 | "a = ''' \r'''" , |
181 | "invalid character in string: ` \\r` at line 1 column 8" |
182 | ); |
183 | bad!( |
184 | "a = ' \r'" , |
185 | "invalid character in string: ` \\r` at line 1 column 6" |
186 | ); |
187 | bad!( |
188 | "a = \"\r\"" , |
189 | "invalid character in string: ` \\r` at line 1 column 6" |
190 | ); |
191 | } |
192 | |
193 | #[test] |
194 | fn blank_literal_string() { |
195 | let table: Value = basic_toml::from_str("foo = ''" ).unwrap(); |
196 | assert_eq!(table["foo" ], json!("" )); |
197 | } |
198 | |
199 | #[test] |
200 | fn many_blank() { |
201 | let table: Value = basic_toml::from_str("foo = \"\"\"\n\n\n\"\"\"" ).unwrap(); |
202 | assert_eq!(table["foo" ], json!(" \n\n" )); |
203 | } |
204 | |
205 | #[test] |
206 | fn literal_eats_crlf() { |
207 | let toml = " |
208 | foo = \"\"\"\\\r\n\"\"\" |
209 | bar = \"\"\"\\\r\n \r\n \r\n a \"\"\" |
210 | " ; |
211 | let table: Value = basic_toml::from_str(toml).unwrap(); |
212 | assert_eq!(table["foo" ], json!("" )); |
213 | assert_eq!(table["bar" ], json!("a" )); |
214 | } |
215 | |
216 | #[test] |
217 | fn string_no_newline() { |
218 | bad!("a = \"\n\"" , "newline in string found at line 1 column 6" ); |
219 | bad!("a = ' \n'" , "newline in string found at line 1 column 6" ); |
220 | } |
221 | |
222 | #[test] |
223 | fn bad_leading_zeros() { |
224 | bad!("a = 00" , "invalid number at line 1 column 6" ); |
225 | bad!("a = -00" , "invalid number at line 1 column 7" ); |
226 | bad!("a = +00" , "invalid number at line 1 column 7" ); |
227 | bad!("a = 00.0" , "invalid number at line 1 column 6" ); |
228 | bad!("a = -00.0" , "invalid number at line 1 column 7" ); |
229 | bad!("a = +00.0" , "invalid number at line 1 column 7" ); |
230 | bad!( |
231 | "a = 9223372036854775808" , |
232 | "invalid number at line 1 column 5" |
233 | ); |
234 | bad!( |
235 | "a = -9223372036854775809" , |
236 | "invalid number at line 1 column 5" |
237 | ); |
238 | } |
239 | |
240 | #[test] |
241 | fn bad_floats() { |
242 | bad!("a = 0." , "invalid number at line 1 column 7" ); |
243 | bad!("a = 0.e" , "invalid number at line 1 column 7" ); |
244 | bad!("a = 0.E" , "invalid number at line 1 column 7" ); |
245 | bad!("a = 0.0E" , "invalid number at line 1 column 5" ); |
246 | bad!("a = 0.0e" , "invalid number at line 1 column 5" ); |
247 | bad!("a = 0.0e-" , "invalid number at line 1 column 9" ); |
248 | bad!("a = 0.0e+" , "invalid number at line 1 column 5" ); |
249 | } |
250 | |
251 | #[test] |
252 | fn floats() { |
253 | macro_rules! t { |
254 | ($actual:expr, $expected:expr) => {{ |
255 | let f = format!("foo = {}" , $actual); |
256 | println!("{}" , f); |
257 | let a: Value = basic_toml::from_str(&f).unwrap(); |
258 | assert_eq!(a["foo" ], json!($expected)); |
259 | }}; |
260 | } |
261 | |
262 | t!("1.0" , 1.0); |
263 | t!("1.0e0" , 1.0); |
264 | t!("1.0e+0" , 1.0); |
265 | t!("1.0e-0" , 1.0); |
266 | t!("1E-0" , 1.0); |
267 | t!("1.001e-0" , 1.001); |
268 | t!("2e10" , 2e10); |
269 | t!("2e+10" , 2e10); |
270 | t!("2e-10" , 2e-10); |
271 | t!("2_0.0" , 20.0); |
272 | t!("2_0.0_0e1_0" , 20.0e10); |
273 | t!("2_0.1_0e1_0" , 20.1e10); |
274 | } |
275 | |
276 | #[test] |
277 | fn bare_key_names() { |
278 | let toml = " |
279 | foo = 3 |
280 | foo_3 = 3 |
281 | foo_-2--3--r23f--4-f2-4 = 3 |
282 | _ = 3 |
283 | - = 3 |
284 | 8 = 8 |
285 | \"a \" = 3 |
286 | \"! \" = 3 |
287 | \"a^b \" = 3 |
288 | \"\\\"\" = 3 |
289 | \"character encoding \" = \"value \" |
290 | 'ʎǝʞ' = \"value \" |
291 | " ; |
292 | let a: Value = basic_toml::from_str(toml).unwrap(); |
293 | let _ = &a["foo" ]; |
294 | let _ = &a["-" ]; |
295 | let _ = &a["_" ]; |
296 | let _ = &a["8" ]; |
297 | let _ = &a["foo_3" ]; |
298 | let _ = &a["foo_-2--3--r23f--4-f2-4" ]; |
299 | let _ = &a["a" ]; |
300 | let _ = &a["!" ]; |
301 | let _ = &a[" \"" ]; |
302 | let _ = &a["character encoding" ]; |
303 | let _ = &a["ʎǝʞ" ]; |
304 | } |
305 | |
306 | #[test] |
307 | fn bad_keys() { |
308 | bad!( |
309 | "key \n=3" , |
310 | "expected an equals, found a newline at line 1 column 4" |
311 | ); |
312 | bad!( |
313 | "key= \n3" , |
314 | "expected a value, found a newline at line 1 column 5" |
315 | ); |
316 | bad!( |
317 | "key|=3" , |
318 | "unexpected character found: `|` at line 1 column 4" |
319 | ); |
320 | bad!( |
321 | "=3" , |
322 | "expected a table key, found an equals at line 1 column 1" |
323 | ); |
324 | bad!( |
325 | " \"\"|=3" , |
326 | "unexpected character found: `|` at line 1 column 3" |
327 | ); |
328 | bad!(" \"\n\"|=3" , "newline in string found at line 1 column 2" ); |
329 | bad!( |
330 | " \"\r\"|=3" , |
331 | "invalid character in string: ` \\r` at line 1 column 2" |
332 | ); |
333 | bad!( |
334 | "''''''=3" , |
335 | "multiline strings are not allowed for key at line 1 column 1" |
336 | ); |
337 | bad!( |
338 | " \"\"\"\"\"\"=3" , |
339 | "multiline strings are not allowed for key at line 1 column 1" |
340 | ); |
341 | bad!( |
342 | "'''key'''=3" , |
343 | "multiline strings are not allowed for key at line 1 column 1" |
344 | ); |
345 | bad!( |
346 | " \"\"\"key \"\"\"=3" , |
347 | "multiline strings are not allowed for key at line 1 column 1" |
348 | ); |
349 | } |
350 | |
351 | #[test] |
352 | fn bad_table_names() { |
353 | bad!( |
354 | "[]" , |
355 | "expected a table key, found a right bracket at line 1 column 2" |
356 | ); |
357 | bad!( |
358 | "[.]" , |
359 | "expected a table key, found a period at line 1 column 2" |
360 | ); |
361 | bad!( |
362 | "[a.]" , |
363 | "expected a table key, found a right bracket at line 1 column 4" |
364 | ); |
365 | bad!("[!]" , "unexpected character found: `!` at line 1 column 2" ); |
366 | bad!("[ \"\n\"]" , "newline in string found at line 1 column 3" ); |
367 | bad!( |
368 | "[a.b] \n[a. \"b \"]" , |
369 | "redefinition of table `a.b` for key `a.b` at line 2 column 1" |
370 | ); |
371 | bad!("[']" , "unterminated string at line 1 column 2" ); |
372 | bad!("[''']" , "unterminated string at line 1 column 2" ); |
373 | bad!( |
374 | "['''''']" , |
375 | "multiline strings are not allowed for key at line 1 column 2" |
376 | ); |
377 | bad!( |
378 | "['''foo''']" , |
379 | "multiline strings are not allowed for key at line 1 column 2" |
380 | ); |
381 | bad!( |
382 | "[ \"\"\"bar \"\"\"]" , |
383 | "multiline strings are not allowed for key at line 1 column 2" |
384 | ); |
385 | bad!("[' \n']" , "newline in string found at line 1 column 3" ); |
386 | bad!("[' \r\n']" , "newline in string found at line 1 column 3" ); |
387 | } |
388 | |
389 | #[test] |
390 | fn table_names() { |
391 | let toml = " |
392 | [a. \"b \"] |
393 | [ \"f f \"] |
394 | [ \"f.f \"] |
395 | [ \"\\\"\"] |
396 | ['a.a'] |
397 | [' \"\"'] |
398 | " ; |
399 | let a: Value = basic_toml::from_str(toml).unwrap(); |
400 | println!("{:?}" , a); |
401 | let _ = &a["a" ]["b" ]; |
402 | let _ = &a["f f" ]; |
403 | let _ = &a["f.f" ]; |
404 | let _ = &a[" \"" ]; |
405 | let _ = &a[" \"\"" ]; |
406 | } |
407 | |
408 | #[test] |
409 | fn invalid_bare_numeral() { |
410 | bad!("4" , "expected an equals, found eof at line 1 column 2" ); |
411 | } |
412 | |
413 | #[test] |
414 | fn inline_tables() { |
415 | basic_toml::from_str::<Value>("a = {}" ).unwrap(); |
416 | basic_toml::from_str::<Value>("a = {b=1}" ).unwrap(); |
417 | basic_toml::from_str::<Value>("a = { b = 1 }" ).unwrap(); |
418 | basic_toml::from_str::<Value>("a = {a=1,b=2}" ).unwrap(); |
419 | basic_toml::from_str::<Value>("a = {a=1,b=2,c={}}" ).unwrap(); |
420 | |
421 | bad!( |
422 | "a = {a=1,}" , |
423 | "expected a table key, found a right brace at line 1 column 10" |
424 | ); |
425 | bad!( |
426 | "a = {,}" , |
427 | "expected a table key, found a comma at line 1 column 6" |
428 | ); |
429 | bad!( |
430 | "a = {a=1,a=1}" , |
431 | "duplicate key: `a` for key `a` at line 1 column 10" |
432 | ); |
433 | bad!( |
434 | "a = { \n}" , |
435 | "expected a table key, found a newline at line 1 column 6" |
436 | ); |
437 | bad!( |
438 | "a = {" , |
439 | "expected a table key, found eof at line 1 column 6" |
440 | ); |
441 | |
442 | basic_toml::from_str::<Value>("a = {a=[ \n]}" ).unwrap(); |
443 | basic_toml::from_str::<Value>("a = { \"a \"=[ \n]}" ).unwrap(); |
444 | basic_toml::from_str::<Value>("a = [ \n{}, \n{}, \n]" ).unwrap(); |
445 | } |
446 | |
447 | #[test] |
448 | fn number_underscores() { |
449 | macro_rules! t { |
450 | ($actual:expr, $expected:expr) => {{ |
451 | let f = format!("foo = {}" , $actual); |
452 | let table: Value = basic_toml::from_str(&f).unwrap(); |
453 | assert_eq!(table["foo" ], json!($expected)); |
454 | }}; |
455 | } |
456 | |
457 | t!("1_0" , 10); |
458 | t!("1_0_0" , 100); |
459 | t!("1_000" , 1000); |
460 | t!("+1_000" , 1000); |
461 | t!("-1_000" , -1000); |
462 | } |
463 | |
464 | #[test] |
465 | fn bad_underscores() { |
466 | bad!("foo = 0_" , "invalid number at line 1 column 7" ); |
467 | bad!("foo = 0__0" , "invalid number at line 1 column 7" ); |
468 | bad!( |
469 | "foo = __0" , |
470 | "invalid TOML value, did you mean to use a quoted string? at line 1 column 7" |
471 | ); |
472 | bad!("foo = 1_0_" , "invalid number at line 1 column 7" ); |
473 | } |
474 | |
475 | #[test] |
476 | fn bad_unicode_codepoint() { |
477 | bad!( |
478 | "foo = \"\\uD800 \"" , |
479 | "invalid escape value: `55296` at line 1 column 9" |
480 | ); |
481 | } |
482 | |
483 | #[test] |
484 | fn bad_strings() { |
485 | bad!( |
486 | "foo = \"\\uxx \"" , |
487 | "invalid hex escape character in string: `x` at line 1 column 10" |
488 | ); |
489 | bad!( |
490 | "foo = \"\\u \"" , |
491 | "invalid hex escape character in string: ` \\\"` at line 1 column 10" |
492 | ); |
493 | bad!("foo = \"\\" , "unterminated string at line 1 column 7" ); |
494 | bad!("foo = '" , "unterminated string at line 1 column 7" ); |
495 | } |
496 | |
497 | #[test] |
498 | fn empty_string() { |
499 | let table: Value = basic_toml::from_str::<Value>("foo = \"\"" ).unwrap(); |
500 | assert_eq!(table["foo" ], json!("" )); |
501 | } |
502 | |
503 | #[test] |
504 | fn booleans() { |
505 | let table: Value = basic_toml::from_str("foo = true" ).unwrap(); |
506 | assert_eq!(table["foo" ], json!(true)); |
507 | |
508 | let table: Value = basic_toml::from_str("foo = false" ).unwrap(); |
509 | assert_eq!(table["foo" ], json!(false)); |
510 | |
511 | bad!( |
512 | "foo = true2" , |
513 | "invalid TOML value, did you mean to use a quoted string? at line 1 column 7" |
514 | ); |
515 | bad!( |
516 | "foo = false2" , |
517 | "invalid TOML value, did you mean to use a quoted string? at line 1 column 7" |
518 | ); |
519 | bad!( |
520 | "foo = t1" , |
521 | "invalid TOML value, did you mean to use a quoted string? at line 1 column 7" |
522 | ); |
523 | bad!( |
524 | "foo = f2" , |
525 | "invalid TOML value, did you mean to use a quoted string? at line 1 column 7" |
526 | ); |
527 | } |
528 | |
529 | #[test] |
530 | fn bad_nesting() { |
531 | bad!( |
532 | " |
533 | a = [2] |
534 | [[a]] |
535 | b = 5 |
536 | " , |
537 | "duplicate key: `a` at line 3 column 11" |
538 | ); |
539 | bad!( |
540 | " |
541 | a = 1 |
542 | [a.b] |
543 | " , |
544 | "duplicate key: `a` at line 3 column 10" |
545 | ); |
546 | bad!( |
547 | " |
548 | a = [] |
549 | [a.b] |
550 | " , |
551 | "duplicate key: `a` at line 3 column 10" |
552 | ); |
553 | bad!( |
554 | " |
555 | a = [] |
556 | [[a.b]] |
557 | " , |
558 | "duplicate key: `a` at line 3 column 11" |
559 | ); |
560 | bad!( |
561 | " |
562 | [a] |
563 | b = { c = 2, d = {} } |
564 | [a.b] |
565 | c = 2 |
566 | " , |
567 | "duplicate key: `b` for key `a` at line 4 column 12" |
568 | ); |
569 | } |
570 | |
571 | #[test] |
572 | fn bad_table_redefine() { |
573 | bad!( |
574 | " |
575 | [a] |
576 | foo= \"bar \" |
577 | [a.b] |
578 | foo= \"bar \" |
579 | [a] |
580 | " , |
581 | "redefinition of table `a` for key `a` at line 6 column 9" |
582 | ); |
583 | bad!( |
584 | " |
585 | [a] |
586 | foo= \"bar \" |
587 | b = { foo = \"bar \" } |
588 | [a] |
589 | " , |
590 | "redefinition of table `a` for key `a` at line 5 column 9" |
591 | ); |
592 | bad!( |
593 | " |
594 | [a] |
595 | b = {} |
596 | [a.b] |
597 | " , |
598 | "duplicate key: `b` for key `a` at line 4 column 12" |
599 | ); |
600 | |
601 | bad!( |
602 | " |
603 | [a] |
604 | b = {} |
605 | [a] |
606 | " , |
607 | "redefinition of table `a` for key `a` at line 4 column 9" |
608 | ); |
609 | } |
610 | |
611 | #[test] |
612 | fn datetimes() { |
613 | bad!( |
614 | "foo = 2016-09-09T09:09:09Z" , |
615 | "invalid number at line 1 column 7" |
616 | ); |
617 | bad!( |
618 | "foo = 2016-09-09T09:09:09.1Z" , |
619 | "invalid number at line 1 column 7" |
620 | ); |
621 | bad!( |
622 | "foo = 2016-09-09T09:09:09.2+10:00" , |
623 | "invalid number at line 1 column 7" |
624 | ); |
625 | bad!( |
626 | "foo = 2016-09-09T09:09:09.123456789-02:00" , |
627 | "invalid number at line 1 column 7" |
628 | ); |
629 | bad!( |
630 | "foo = 2016-09-09T09:09:09.Z" , |
631 | "invalid number at line 1 column 7" |
632 | ); |
633 | bad!( |
634 | "foo = 2016-9-09T09:09:09Z" , |
635 | "invalid number at line 1 column 7" |
636 | ); |
637 | bad!( |
638 | "foo = 2016-09-09T09:09:09+2:00" , |
639 | "invalid number at line 1 column 7" |
640 | ); |
641 | bad!( |
642 | "foo = 2016-09-09T09:09:09-2:00" , |
643 | "invalid number at line 1 column 7" |
644 | ); |
645 | bad!( |
646 | "foo = 2016-09-09T09:09:09Z-2:00" , |
647 | "invalid number at line 1 column 7" |
648 | ); |
649 | } |
650 | |
651 | #[test] |
652 | fn require_newline_after_value() { |
653 | bad!("0=0r=false" , "invalid number at line 1 column 3" ); |
654 | bad!( |
655 | r#" |
656 | 0=""o=""m=""r=""00="0"q="""0"""e="""0""" |
657 | "# , |
658 | "expected newline, found an identifier at line 2 column 5" |
659 | ); |
660 | bad!( |
661 | r#" |
662 | [[0000l0]] |
663 | 0="0"[[0000l0]] |
664 | 0="0"[[0000l0]] |
665 | 0="0"l="0" |
666 | "# , |
667 | "expected newline, found a left bracket at line 3 column 6" |
668 | ); |
669 | bad!( |
670 | r#" |
671 | 0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z] |
672 | "# , |
673 | "expected newline, found an identifier at line 2 column 6" |
674 | ); |
675 | bad!( |
676 | " |
677 | 0=0r0=0r=false |
678 | " , |
679 | "invalid number at line 2 column 3" |
680 | ); |
681 | bad!( |
682 | " |
683 | 0=0r0=0r=falsefal=false |
684 | " , |
685 | "invalid number at line 2 column 3" |
686 | ); |
687 | } |
688 | |