diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2019-07-29 09:06:35 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-29 09:06:35 -0500 | 
| commit | 5c6c3750727515fa4fc5bc3bc653293f5293f2c6 (patch) | |
| tree | a043f6de866915df978bf7c166b7261b3c5d6335 | |
| parent | 844a1a4651d6b77a5b48159348d9cccbd8f4c88f (diff) | |
| parent | 3d08775266eb1979956b03add38e6bd4824f521a (diff) | |
| download | milf-rs-5c6c3750727515fa4fc5bc3bc653293f5293f2c6.tar.gz milf-rs-5c6c3750727515fa4fc5bc3bc653293f5293f2c6.zip  | |
Merge pull request #313 from zertosh/show-col-in-errors
Show "column" in Error messages
| -rw-r--r-- | src/de.rs | 2 | ||||
| -rw-r--r-- | test-suite/tests/backcompat.rs | 19 | ||||
| -rw-r--r-- | test-suite/tests/datetime.rs | 108 | ||||
| -rw-r--r-- | test-suite/tests/invalid-misc.rs | 56 | ||||
| -rw-r--r-- | test-suite/tests/invalid.rs | 178 | ||||
| -rw-r--r-- | test-suite/tests/parser.rs | 297 | ||||
| -rw-r--r-- | test-suite/tests/serde.rs | 13 | 
7 files changed, 469 insertions, 204 deletions
@@ -1845,7 +1845,7 @@ impl fmt::Display for Error {          }          if let Some(line) = self.inner.line { -            write!(f, " at line {}", line + 1)?; +            write!(f, " at line {} column {}", line + 1, self.inner.col + 1)?;          }          Ok(()) diff --git a/test-suite/tests/backcompat.rs b/test-suite/tests/backcompat.rs index 53cda69..ef3bd36 100644 --- a/test-suite/tests/backcompat.rs +++ b/test-suite/tests/backcompat.rs @@ -3,13 +3,25 @@ extern crate toml;  use serde::de::Deserialize; +macro_rules! bad { +    ($toml:expr, $msg:expr) => { +        match $toml.parse::<toml::Value>() { +            Ok(s) => panic!("parsed to: {:#?}", s), +            Err(e) => assert_eq!(e.to_string(), $msg), +        } +    }; +} +  #[test]  fn newlines_after_tables() {      let s = "          [a] foo = 1          [[b]] foo = 1      "; -    assert!(s.parse::<toml::Value>().is_err()); +    bad!( +        s, +        "expected newline, found an identifier at line 2 column 13" +    );      let mut d = toml::de::Deserializer::new(s);      d.set_require_newline_after_table(false); @@ -30,7 +42,10 @@ fn allow_duplicate_after_longer() {          [dependencies]          bitflags = 1      "; -    assert!(s.parse::<toml::Value>().is_err()); +    bad!( +        s, +        "redefinition of table `dependencies` for key `dependencies` at line 8 column 9" +    );      let mut d = toml::de::Deserializer::new(s);      d.set_allow_duplicate_after_longer_table(true); diff --git a/test-suite/tests/datetime.rs b/test-suite/tests/datetime.rs index d6128b0..4855f54 100644 --- a/test-suite/tests/datetime.rs +++ b/test-suite/tests/datetime.rs @@ -2,13 +2,20 @@ extern crate toml;  use std::str::FromStr; -use toml::Value; +macro_rules! bad { +    ($toml:expr, $msg:expr) => { +        match $toml.parse::<toml::Value>() { +            Ok(s) => panic!("parsed to: {:#?}", s), +            Err(e) => assert_eq!(e.to_string(), $msg), +        } +    }; +}  #[test]  fn times() {      fn dogood(s: &str, serialized: &str) {          let to_parse = format!("foo = {}", s); -        let value = Value::from_str(&to_parse).unwrap(); +        let value = toml::Value::from_str(&to_parse).unwrap();          assert_eq!(value["foo"].as_datetime().unwrap().to_string(), serialized);      }      fn good(s: &str) { @@ -35,32 +42,75 @@ fn times() {  #[test]  fn bad_times() { -    fn bad(s: &str) { -        let to_parse = format!("foo = {}", s); -        assert!(Value::from_str(&to_parse).is_err()); -    } - -    bad("199-09-09"); -    bad("199709-09"); -    bad("1997-9-09"); -    bad("1997-09-9"); -    bad("1997-09-0909:09:09"); -    bad("1997-09-09T09:09:09."); -    bad("T"); -    bad("T."); -    bad("TZ"); -    bad("1997-09-09T09:09:09.09+"); -    bad("1997-09-09T09:09:09.09+09"); -    bad("1997-09-09T09:09:09.09+09:9"); -    bad("1997-09-09T09:09:09.09+0909"); -    bad("1997-09-09T09:09:09.09-"); -    bad("1997-09-09T09:09:09.09-09"); -    bad("1997-09-09T09:09:09.09-09:9"); -    bad("1997-09-09T09:09:09.09-0909"); +    bad!("foo = 199-09-09", "failed to parse datetime for key `foo`"); +    bad!("foo = 199709-09", "failed to parse datetime for key `foo`"); +    bad!("foo = 1997-9-09", "failed to parse datetime for key `foo`"); +    bad!("foo = 1997-09-9", "failed to parse datetime for key `foo`"); +    bad!( +        "foo = 1997-09-0909:09:09", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.", +        "invalid date at line 1 column 7" +    ); +    bad!("foo = T", "failed to parse datetime for key `foo`"); +    bad!( +        "foo = T.", +        "expected newline, found a period at line 1 column 8" +    ); +    bad!("foo = TZ", "failed to parse datetime for key `foo`"); +    bad!( +        "foo = 1997-09-09T09:09:09.09+", +        "invalid date at line 1 column 7" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09+09", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09+09:9", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09+0909", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09-", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09-09", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09-09:9", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T09:09:09.09-0909", +        "failed to parse datetime for key `foo`" +    ); -    bad("1997-00-09T09:09:09.09Z"); -    bad("1997-09-00T09:09:09.09Z"); -    bad("1997-09-09T30:09:09.09Z"); -    bad("1997-09-09T12:69:09.09Z"); -    bad("1997-09-09T12:09:69.09Z"); +    bad!( +        "foo = 1997-00-09T09:09:09.09Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-00T09:09:09.09Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T30:09:09.09Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T12:69:09.09Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 1997-09-09T12:09:69.09Z", +        "failed to parse datetime for key `foo`" +    );  } diff --git a/test-suite/tests/invalid-misc.rs b/test-suite/tests/invalid-misc.rs index 5c7f779..f18012a 100644 --- a/test-suite/tests/invalid-misc.rs +++ b/test-suite/tests/invalid-misc.rs @@ -1,28 +1,48 @@  extern crate toml; +macro_rules! bad { +    ($toml:expr, $msg:expr) => { +        match $toml.parse::<toml::Value>() { +            Ok(s) => panic!("parsed to: {:#?}", s), +            Err(e) => assert_eq!(e.to_string(), $msg), +        } +    }; +} +  #[test]  fn bad() { -    fn bad(s: &str) { -        assert!(s.parse::<toml::Value>().is_err()); -    } - -    bad("a = 01"); -    bad("a = 1__1"); -    bad("a = 1_"); -    bad("''"); -    bad("a = 9e99999"); +    bad!("a = 01", "invalid number at line 1 column 6"); +    bad!("a = 1__1", "invalid number at line 1 column 5"); +    bad!("a = 1_", "invalid number at line 1 column 5"); +    bad!("''", "empty table key found at line 1 column 1"); +    bad!("a = 9e99999", "invalid number at line 1 column 5"); -    bad("a = \"\u{7f}\""); -    bad("a = '\u{7f}'"); +    bad!( +        "a = \"\u{7f}\"", +        "invalid character in string: `\\u{7f}` at line 1 column 6" +    ); +    bad!( +        "a = '\u{7f}'", +        "invalid character in string: `\\u{7f}` at line 1 column 6" +    ); -    bad("a = -0x1"); -    bad("a = 0x-1"); +    bad!("a = -0x1", "invalid number at line 1 column 5"); +    bad!("a = 0x-1", "failed to parse datetime for key `a`");      // Dotted keys. -    bad("a.b.c = 1 +    bad!( +        "a.b.c = 1           a.b = 2 -        "); -    bad("a = 1 -         a.b = 2"); -    bad("a = {k1 = 1, k1.name = \"joe\"}") +        ", +        "duplicate key: `b` for key `a`" +    ); +    bad!( +        "a = 1 +         a.b = 2", +        "dotted key attempted to extend non-table type at line 1 column 5" +    ); +    bad!( +        "a = {k1 = 1, k1.name = \"joe\"}", +        "dotted key attempted to extend non-table type at line 1 column 11" +    );  } diff --git a/test-suite/tests/invalid.rs b/test-suite/tests/invalid.rs index 275e385..bfde2d4 100644 --- a/test-suite/tests/invalid.rs +++ b/test-suite/tests/invalid.rs @@ -1,167 +1,241 @@  extern crate toml; -fn run(toml: &str) { -    println!("test if invalid:\n{}", toml); -    if let Ok(e) = toml.parse::<toml::Value>() { -        panic!("parsed to: {:#?}", e); -    } +macro_rules! bad { +    ($toml:expr, $msg:expr) => { +        match $toml.parse::<toml::Value>() { +            Ok(s) => panic!("parsed to: {:#?}", s), +            Err(e) => assert_eq!(e.to_string(), $msg), +        } +    };  } -macro_rules! test( ($name:ident, $toml:expr) => ( +macro_rules! test( ($name:ident, $s:expr, $msg:expr) => (      #[test] -    fn $name() { run($toml); } +    fn $name() { bad!($s, $msg); }  ) );  test!(      array_mixed_types_arrays_and_ints, -    include_str!("invalid/array-mixed-types-arrays-and-ints.toml") +    include_str!("invalid/array-mixed-types-arrays-and-ints.toml"), +    "mixed types in an array at line 1 column 24"  );  test!(      array_mixed_types_ints_and_floats, -    include_str!("invalid/array-mixed-types-ints-and-floats.toml") +    include_str!("invalid/array-mixed-types-ints-and-floats.toml"), +    "mixed types in an array at line 1 column 23"  );  test!(      array_mixed_types_strings_and_ints, -    include_str!("invalid/array-mixed-types-strings-and-ints.toml") +    include_str!("invalid/array-mixed-types-strings-and-ints.toml"), +    "mixed types in an array at line 1 column 27"  );  test!(      datetime_malformed_no_leads, -    include_str!("invalid/datetime-malformed-no-leads.toml") +    include_str!("invalid/datetime-malformed-no-leads.toml"), +    "failed to parse datetime for key `no-leads`"  );  test!(      datetime_malformed_no_secs, -    include_str!("invalid/datetime-malformed-no-secs.toml") +    include_str!("invalid/datetime-malformed-no-secs.toml"), +    "expected a colon, found a newline at line 1 column 28"  );  test!(      datetime_malformed_no_t, -    include_str!("invalid/datetime-malformed-no-t.toml") +    include_str!("invalid/datetime-malformed-no-t.toml"), +    "failed to parse datetime for key `no-t`"  );  test!(      datetime_malformed_with_milli, -    include_str!("invalid/datetime-malformed-with-milli.toml") +    include_str!("invalid/datetime-malformed-with-milli.toml"), +    "failed to parse datetime for key `with-milli`"  );  test!(      duplicate_key_table, -    include_str!("invalid/duplicate-key-table.toml") +    include_str!("invalid/duplicate-key-table.toml"), +    "duplicate key: `type` for key `fruit`" +); +test!( +    duplicate_keys, +    include_str!("invalid/duplicate-keys.toml"), +    "duplicate key: `dupe`"  ); -test!(duplicate_keys, include_str!("invalid/duplicate-keys.toml"));  test!(      duplicate_table, -    include_str!("invalid/duplicate-table.toml") +    include_str!("invalid/duplicate-table.toml"), +    "redefinition of table `dependencies` for key `dependencies` at line 7 column 1"  );  test!(      duplicate_tables, -    include_str!("invalid/duplicate-tables.toml") +    include_str!("invalid/duplicate-tables.toml"), +    "redefinition of table `a` for key `a` at line 2 column 1"  );  test!(      empty_implicit_table, -    include_str!("invalid/empty-implicit-table.toml") +    include_str!("invalid/empty-implicit-table.toml"), +    "expected a table key, found a period at line 1 column 10" +); +test!( +    empty_table, +    include_str!("invalid/empty-table.toml"), +    "expected a table key, found a right bracket at line 1 column 2"  ); -test!(empty_table, include_str!("invalid/empty-table.toml"));  test!(      float_no_leading_zero, -    include_str!("invalid/float-no-leading-zero.toml") +    include_str!("invalid/float-no-leading-zero.toml"), +    "expected a value, found a period at line 1 column 10"  );  test!(      float_no_suffix, -    include_str!("invalid/float-no-suffix.toml") +    include_str!("invalid/float-no-suffix.toml"), +    "invalid number at line 1 column 5"  );  test!(      float_no_trailing_digits, -    include_str!("invalid/float-no-trailing-digits.toml") +    include_str!("invalid/float-no-trailing-digits.toml"), +    "invalid number at line 1 column 12"  );  test!(      key_after_array, -    include_str!("invalid/key-after-array.toml") +    include_str!("invalid/key-after-array.toml"), +    "expected newline, found an identifier at line 1 column 14"  );  test!(      key_after_table, -    include_str!("invalid/key-after-table.toml") +    include_str!("invalid/key-after-table.toml"), +    "expected newline, found an identifier at line 1 column 11" +); +test!( +    key_empty, +    include_str!("invalid/key-empty.toml"), +    "expected a table key, found an equals at line 1 column 2" +); +test!( +    key_hash, +    include_str!("invalid/key-hash.toml"), +    "expected an equals, found a comment at line 1 column 2" +); +test!( +    key_newline, +    include_str!("invalid/key-newline.toml"), +    "expected an equals, found a newline at line 1 column 2"  ); -test!(key_empty, include_str!("invalid/key-empty.toml")); -test!(key_hash, include_str!("invalid/key-hash.toml")); -test!(key_newline, include_str!("invalid/key-newline.toml"));  test!(      key_open_bracket, -    include_str!("invalid/key-open-bracket.toml") +    include_str!("invalid/key-open-bracket.toml"), +    "expected a right bracket, found an equals at line 1 column 6"  );  test!(      key_single_open_bracket, -    include_str!("invalid/key-single-open-bracket.toml") +    include_str!("invalid/key-single-open-bracket.toml"), +    "expected a table key, found eof at line 1 column 2" +); +test!( +    key_space, +    include_str!("invalid/key-space.toml"), +    "expected an equals, found an identifier at line 1 column 3"  ); -test!(key_space, include_str!("invalid/key-space.toml"));  test!(      key_start_bracket, -    include_str!("invalid/key-start-bracket.toml") +    include_str!("invalid/key-start-bracket.toml"), +    "expected a right bracket, found an equals at line 2 column 6" +); +test!( +    key_two_equals, +    include_str!("invalid/key-two-equals.toml"), +    "expected a value, found an equals at line 1 column 6"  ); -test!(key_two_equals, include_str!("invalid/key-two-equals.toml"));  test!(      string_bad_byte_escape, -    include_str!("invalid/string-bad-byte-escape.toml") +    include_str!("invalid/string-bad-byte-escape.toml"), +    "invalid escape character in string: `x` at line 1 column 13"  );  test!(      string_bad_escape, -    include_str!("invalid/string-bad-escape.toml") +    include_str!("invalid/string-bad-escape.toml"), +    "invalid escape character in string: `a` at line 1 column 42"  );  test!(      string_bad_line_ending_escape, -    include_str!("invalid/string-bad-line-ending-escape.toml") +    include_str!("invalid/string-bad-line-ending-escape.toml"), +    "invalid escape character in string: ` ` at line 2 column 79"  );  test!(      string_byte_escapes, -    include_str!("invalid/string-byte-escapes.toml") +    include_str!("invalid/string-byte-escapes.toml"), +    "invalid escape character in string: `x` at line 1 column 12"  );  test!(      string_no_close, -    include_str!("invalid/string-no-close.toml") +    include_str!("invalid/string-no-close.toml"), +    "newline in string found at line 1 column 42"  );  test!(      table_array_implicit, -    include_str!("invalid/table-array-implicit.toml") +    include_str!("invalid/table-array-implicit.toml"), +    "table redefined as array for key `albums` at line 13 column 1"  );  test!(      table_array_malformed_bracket, -    include_str!("invalid/table-array-malformed-bracket.toml") +    include_str!("invalid/table-array-malformed-bracket.toml"), +    "expected a right bracket, found a newline at line 1 column 10"  );  test!(      table_array_malformed_empty, -    include_str!("invalid/table-array-malformed-empty.toml") +    include_str!("invalid/table-array-malformed-empty.toml"), +    "expected a table key, found a right bracket at line 1 column 3" +); +test!( +    table_empty, +    include_str!("invalid/table-empty.toml"), +    "expected a table key, found a right bracket at line 1 column 2"  ); -test!(table_empty, include_str!("invalid/table-empty.toml"));  test!(      table_nested_brackets_close, -    include_str!("invalid/table-nested-brackets-close.toml") +    include_str!("invalid/table-nested-brackets-close.toml"), +    "expected newline, found an identifier at line 1 column 4"  );  test!(      table_nested_brackets_open, -    include_str!("invalid/table-nested-brackets-open.toml") +    include_str!("invalid/table-nested-brackets-open.toml"), +    "expected a right bracket, found a left bracket at line 1 column 3"  );  test!(      table_whitespace, -    include_str!("invalid/table-whitespace.toml") +    include_str!("invalid/table-whitespace.toml"), +    "expected a right bracket, found an identifier at line 1 column 10"  );  test!(      table_with_pound, -    include_str!("invalid/table-with-pound.toml") +    include_str!("invalid/table-with-pound.toml"), +    "expected a right bracket, found a comment at line 1 column 5"  );  test!(      text_after_array_entries, -    include_str!("invalid/text-after-array-entries.toml") +    include_str!("invalid/text-after-array-entries.toml"), +    "invalid number at line 2 column 46"  );  test!(      text_after_integer, -    include_str!("invalid/text-after-integer.toml") +    include_str!("invalid/text-after-integer.toml"), +    "expected newline, found an identifier at line 1 column 13"  );  test!(      text_after_string, -    include_str!("invalid/text-after-string.toml") +    include_str!("invalid/text-after-string.toml"), +    "expected newline, found an identifier at line 1 column 41"  );  test!(      text_after_table, -    include_str!("invalid/text-after-table.toml") +    include_str!("invalid/text-after-table.toml"), +    "expected newline, found an identifier at line 1 column 9"  );  test!(      text_before_array_separator, -    include_str!("invalid/text-before-array-separator.toml") +    include_str!("invalid/text-before-array-separator.toml"), +    "expected a right bracket, found an identifier at line 2 column 46" +); +test!( +    text_in_array, +    include_str!("invalid/text-in-array.toml"), +    "invalid number at line 3 column 3"  ); -test!(text_in_array, include_str!("invalid/text-in-array.toml")); diff --git a/test-suite/tests/parser.rs b/test-suite/tests/parser.rs index 56f559d..1a684c5 100644 --- a/test-suite/tests/parser.rs +++ b/test-suite/tests/parser.rs @@ -3,15 +3,12 @@ extern crate toml;  use toml::Value;  macro_rules! bad { -    ($s:expr, $msg:expr) => {{ -        match $s.parse::<Value>() { -            Ok(s) => panic!("successfully parsed as {}", s), -            Err(e) => { -                let e = e.to_string(); -                assert!(e.contains($msg), "error: {}", e); -            } +    ($toml:expr, $msg:expr) => { +        match $toml.parse::<toml::Value>() { +            Ok(s) => panic!("parsed to: {:#?}", s), +            Err(e) => assert_eq!(e.to_string(), $msg),          } -    }}; +    };  }  #[test] @@ -189,13 +186,31 @@ name = "plantain"  #[test]  fn stray_cr() { -    "\r".parse::<Value>().unwrap_err(); -    "a = [ \r ]".parse::<Value>().unwrap_err(); -    "a = \"\"\"\r\"\"\"".parse::<Value>().unwrap_err(); -    "a = \"\"\"\\  \r  \"\"\"".parse::<Value>().unwrap_err(); -    "a = '''\r'''".parse::<Value>().unwrap_err(); -    "a = '\r'".parse::<Value>().unwrap_err(); -    "a = \"\r\"".parse::<Value>().unwrap_err(); +    bad!("\r", "unexpected character found: `\\r` at line 1 column 1"); +    bad!( +        "a = [ \r ]", +        "unexpected character found: `\\r` at line 1 column 7" +    ); +    bad!( +        "a = \"\"\"\r\"\"\"", +        "invalid character in string: `\\r` at line 1 column 8" +    ); +    bad!( +        "a = \"\"\"\\  \r  \"\"\"", +        "invalid escape character in string: ` ` at line 1 column 9" +    ); +    bad!( +        "a = '''\r'''", +        "invalid character in string: `\\r` at line 1 column 8" +    ); +    bad!( +        "a = '\r'", +        "invalid character in string: `\\r` at line 1 column 6" +    ); +    bad!( +        "a = \"\r\"", +        "invalid character in string: `\\r` at line 1 column 6" +    );  }  #[test] @@ -224,32 +239,38 @@ fn literal_eats_crlf() {  #[test]  fn string_no_newline() { -    "a = \"\n\"".parse::<Value>().unwrap_err(); -    "a = '\n'".parse::<Value>().unwrap_err(); +    bad!("a = \"\n\"", "newline in string found at line 1 column 6"); +    bad!("a = '\n'", "newline in string found at line 1 column 6");  }  #[test]  fn bad_leading_zeros() { -    "a = 00".parse::<Value>().unwrap_err(); -    "a = -00".parse::<Value>().unwrap_err(); -    "a = +00".parse::<Value>().unwrap_err(); -    "a = 00.0".parse::<Value>().unwrap_err(); -    "a = -00.0".parse::<Value>().unwrap_err(); -    "a = +00.0".parse::<Value>().unwrap_err(); -    "a = 9223372036854775808".parse::<Value>().unwrap_err(); -    "a = -9223372036854775809".parse::<Value>().unwrap_err(); +    bad!("a = 00", "invalid number at line 1 column 6"); +    bad!("a = -00", "invalid number at line 1 column 7"); +    bad!("a = +00", "invalid number at line 1 column 7"); +    bad!("a = 00.0", "invalid number at line 1 column 6"); +    bad!("a = -00.0", "invalid number at line 1 column 7"); +    bad!("a = +00.0", "invalid number at line 1 column 7"); +    bad!( +        "a = 9223372036854775808", +        "invalid number at line 1 column 5" +    ); +    bad!( +        "a = -9223372036854775809", +        "invalid number at line 1 column 5" +    );  }  #[test]  fn bad_floats() { -    "a = 0.".parse::<Value>().unwrap_err(); -    "a = 0.e".parse::<Value>().unwrap_err(); -    "a = 0.E".parse::<Value>().unwrap_err(); -    "a = 0.0E".parse::<Value>().unwrap_err(); -    "a = 0.0e".parse::<Value>().unwrap_err(); -    "a = 0.0e-".parse::<Value>().unwrap_err(); -    "a = 0.0e+".parse::<Value>().unwrap_err(); -    "a = 0.0e+00".parse::<Value>().unwrap_err(); +    bad!("a = 0.", "invalid number at line 1 column 7"); +    bad!("a = 0.e", "invalid number at line 1 column 7"); +    bad!("a = 0.E", "invalid number at line 1 column 7"); +    bad!("a = 0.0E", "invalid number at line 1 column 5"); +    bad!("a = 0.0e", "invalid number at line 1 column 5"); +    bad!("a = 0.0e-", "invalid number at line 1 column 9"); +    bad!("a = 0.0e+", "invalid number at line 1 column 5"); +    bad!("a = 0.0e+00", "invalid number at line 1 column 11");  }  #[test] @@ -310,37 +331,85 @@ fn bare_key_names() {  #[test]  fn bad_keys() { -    "key\n=3".parse::<Value>().unwrap_err(); -    "key=\n3".parse::<Value>().unwrap_err(); -    "key|=3".parse::<Value>().unwrap_err(); -    "\"\"=3".parse::<Value>().unwrap_err(); -    "=3".parse::<Value>().unwrap_err(); -    "\"\"|=3".parse::<Value>().unwrap_err(); -    "\"\n\"|=3".parse::<Value>().unwrap_err(); -    "\"\r\"|=3".parse::<Value>().unwrap_err(); -    "''''''=3".parse::<Value>().unwrap_err(); -    "\"\"\"\"\"\"=3".parse::<Value>().unwrap_err(); -    "'''key'''=3".parse::<Value>().unwrap_err(); -    "\"\"\"key\"\"\"=3".parse::<Value>().unwrap_err(); +    bad!( +        "key\n=3", +        "expected an equals, found a newline at line 1 column 4" +    ); +    bad!( +        "key=\n3", +        "expected a value, found a newline at line 1 column 5" +    ); +    bad!( +        "key|=3", +        "unexpected character found: `|` at line 1 column 4" +    ); +    bad!("\"\"=3", "empty table key found at line 1 column 1"); +    bad!( +        "=3", +        "expected a table key, found an equals at line 1 column 1" +    ); +    bad!("\"\"|=3", "empty table key found at line 1 column 1"); +    bad!("\"\n\"|=3", "newline in string found at line 1 column 2"); +    bad!( +        "\"\r\"|=3", +        "invalid character in string: `\\r` at line 1 column 2" +    ); +    bad!( +        "''''''=3", +        "multiline strings are not allowed for key at line 1 column 1" +    ); +    bad!( +        "\"\"\"\"\"\"=3", +        "multiline strings are not allowed for key at line 1 column 1" +    ); +    bad!( +        "'''key'''=3", +        "multiline strings are not allowed for key at line 1 column 1" +    ); +    bad!( +        "\"\"\"key\"\"\"=3", +        "multiline strings are not allowed for key at line 1 column 1" +    );  }  #[test]  fn bad_table_names() { -    "[]".parse::<Value>().unwrap_err(); -    "[.]".parse::<Value>().unwrap_err(); -    "[\"\".\"\"]".parse::<Value>().unwrap_err(); -    "[a.]".parse::<Value>().unwrap_err(); -    "[\"\"]".parse::<Value>().unwrap_err(); -    "[!]".parse::<Value>().unwrap_err(); -    "[\"\n\"]".parse::<Value>().unwrap_err(); -    "[a.b]\n[a.\"b\"]".parse::<Value>().unwrap_err(); -    "[']".parse::<Value>().unwrap_err(); -    "[''']".parse::<Value>().unwrap_err(); -    "['''''']".parse::<Value>().unwrap_err(); -    "['''foo''']".parse::<Value>().unwrap_err(); -    "[\"\"\"bar\"\"\"]".parse::<Value>().unwrap_err(); -    "['\n']".parse::<Value>().unwrap_err(); -    "['\r\n']".parse::<Value>().unwrap_err(); +    bad!( +        "[]", +        "expected a table key, found a right bracket at line 1 column 2" +    ); +    bad!( +        "[.]", +        "expected a table key, found a period at line 1 column 2" +    ); +    bad!("[\"\".\"\"]", "empty table key found at line 1 column 2"); +    bad!( +        "[a.]", +        "expected a table key, found a right bracket at line 1 column 4" +    ); +    bad!("[\"\"]", "empty table key found at line 1 column 2"); +    bad!("[!]", "unexpected character found: `!` at line 1 column 2"); +    bad!("[\"\n\"]", "newline in string found at line 1 column 3"); +    bad!( +        "[a.b]\n[a.\"b\"]", +        "redefinition of table `a.b` for key `a.b` at line 2 column 1" +    ); +    bad!("[']", "unterminated string at line 1 column 2"); +    bad!("[''']", "unterminated string at line 1 column 2"); +    bad!( +        "['''''']", +        "multiline strings are not allowed for key at line 1 column 2" +    ); +    bad!( +        "['''foo''']", +        "multiline strings are not allowed for key at line 1 column 2" +    ); +    bad!( +        "[\"\"\"bar\"\"\"]", +        "multiline strings are not allowed for key at line 1 column 2" +    ); +    bad!("['\n']", "newline in string found at line 1 column 3"); +    bad!("['\r\n']", "newline in string found at line 1 column 3");  }  #[test] @@ -365,7 +434,7 @@ fn table_names() {  #[test]  fn invalid_bare_numeral() { -    "4".parse::<Value>().unwrap_err(); +    bad!("4", "expected an equals, found eof at line 1 column 2");  }  #[test] @@ -375,11 +444,25 @@ fn inline_tables() {      "a = {   b   =   1    }".parse::<Value>().unwrap();      "a = {a=1,b=2}".parse::<Value>().unwrap();      "a = {a=1,b=2,c={}}".parse::<Value>().unwrap(); -    "a = {a=1,}".parse::<Value>().unwrap_err(); -    "a = {,}".parse::<Value>().unwrap_err(); -    "a = {a=1,a=1}".parse::<Value>().unwrap_err(); -    "a = {\n}".parse::<Value>().unwrap_err(); -    "a = {".parse::<Value>().unwrap_err(); + +    bad!( +        "a = {a=1,}", +        "expected a table key, found a right brace at line 1 column 10" +    ); +    bad!( +        "a = {,}", +        "expected a table key, found a comma at line 1 column 6" +    ); +    bad!("a = {a=1,a=1}", "duplicate key: `a` for key `a`"); +    bad!( +        "a = {\n}", +        "expected a table key, found a newline at line 1 column 6" +    ); +    bad!( +        "a = {", +        "expected a table key, found eof at line 1 column 6" +    ); +      "a = {a=[\n]}".parse::<Value>().unwrap();      "a = {\"a\"=[\n]}".parse::<Value>().unwrap();      "a = [\n{},\n{},\n]".parse::<Value>().unwrap(); @@ -404,23 +487,32 @@ fn number_underscores() {  #[test]  fn bad_underscores() { -    bad!("foo = 0_", "invalid number"); -    bad!("foo = 0__0", "invalid number"); -    bad!("foo = __0", "invalid number"); -    bad!("foo = 1_0_", "invalid number"); +    bad!("foo = 0_", "invalid number at line 1 column 7"); +    bad!("foo = 0__0", "invalid number at line 1 column 7"); +    bad!("foo = __0", "invalid number at line 1 column 7"); +    bad!("foo = 1_0_", "invalid number at line 1 column 7");  }  #[test]  fn bad_unicode_codepoint() { -    bad!("foo = \"\\uD800\"", "invalid escape value"); +    bad!( +        "foo = \"\\uD800\"", +        "invalid escape value: `55296` at line 1 column 9" +    );  }  #[test]  fn bad_strings() { -    bad!("foo = \"\\uxx\"", "invalid hex escape"); -    bad!("foo = \"\\u\"", "invalid hex escape"); -    bad!("foo = \"\\", "unterminated"); -    bad!("foo = '", "unterminated"); +    bad!( +        "foo = \"\\uxx\"", +        "invalid hex escape character in string: `x` at line 1 column 10" +    ); +    bad!( +        "foo = \"\\u\"", +        "invalid hex escape character in string: `\\\"` at line 1 column 10" +    ); +    bad!("foo = \"\\", "unterminated string at line 1 column 7"); +    bad!("foo = '", "unterminated string at line 1 column 7");  }  #[test] @@ -441,10 +533,10 @@ fn booleans() {      let table = "foo = false".parse::<Value>().unwrap();      assert_eq!(table["foo"].as_bool(), Some(false)); -    assert!("foo = true2".parse::<Value>().is_err()); -    assert!("foo = false2".parse::<Value>().is_err()); -    assert!("foo = t1".parse::<Value>().is_err()); -    assert!("foo = f2".parse::<Value>().is_err()); +    bad!("foo = true2", "failed to parse datetime for key `foo`"); +    bad!("foo = false2", "invalid number at line 1 column 7"); +    bad!("foo = t1", "failed to parse datetime for key `foo`"); +    bad!("foo = f2", "invalid number at line 1 column 7");  }  #[test] @@ -485,7 +577,7 @@ fn bad_nesting() {          [a.b]          c = 2          ", -        "duplicate key: `b`" +        "duplicate key: `b` for key `a`"      );  } @@ -499,7 +591,7 @@ fn bad_table_redefine() {          foo=\"bar\"          [a]          ", -        "redefinition of table `a`" +        "redefinition of table `a` for key `a` at line 6 column 9"      );      bad!(          " @@ -508,7 +600,7 @@ fn bad_table_redefine() {          b = { foo = \"bar\" }          [a]          ", -        "redefinition of table `a`" +        "redefinition of table `a` for key `a` at line 5 column 9"      );      bad!(          " @@ -516,7 +608,7 @@ fn bad_table_redefine() {          b = {}          [a.b]          ", -        "duplicate key: `b`" +        "duplicate key: `b` for key `a`"      );      bad!( @@ -525,7 +617,7 @@ fn bad_table_redefine() {          b = {}          [a]          ", -        "redefinition of table `a`" +        "redefinition of table `a` for key `a` at line 4 column 9"      );  } @@ -543,21 +635,36 @@ fn datetimes() {      t!("2016-09-09T09:09:09.1Z");      t!("2016-09-09T09:09:09.2+10:00");      t!("2016-09-09T09:09:09.123456789-02:00"); -    bad!("foo = 2016-09-09T09:09:09.Z", "failed to parse date"); -    bad!("foo = 2016-9-09T09:09:09Z", "failed to parse date"); -    bad!("foo = 2016-09-09T09:09:09+2:00", "failed to parse date"); -    bad!("foo = 2016-09-09T09:09:09-2:00", "failed to parse date"); -    bad!("foo = 2016-09-09T09:09:09Z-2:00", "failed to parse date"); +    bad!( +        "foo = 2016-09-09T09:09:09.Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 2016-9-09T09:09:09Z", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 2016-09-09T09:09:09+2:00", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 2016-09-09T09:09:09-2:00", +        "failed to parse datetime for key `foo`" +    ); +    bad!( +        "foo = 2016-09-09T09:09:09Z-2:00", +        "failed to parse datetime for key `foo`" +    );  }  #[test]  fn require_newline_after_value() { -    bad!("0=0r=false", "invalid number at line 1"); +    bad!("0=0r=false", "invalid number at line 1 column 3");      bad!(          r#"  0=""o=""m=""r=""00="0"q="""0"""e="""0"""  "#, -        "expected newline" +        "expected newline, found an identifier at line 2 column 5"      );      bad!(          r#" @@ -566,24 +673,24 @@ fn require_newline_after_value() {  0="0"[[0000l0]]  0="0"l="0"  "#, -        "expected newline" +        "expected newline, found a left bracket at line 3 column 6"      );      bad!(          r#"  0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z]  "#, -        "expected newline" +        "expected newline, found an identifier at line 2 column 6"      );      bad!(          r#"  0=0r0=0r=false  "#, -        "invalid number at line 2" +        "invalid number at line 2 column 3"      );      bad!(          r#"  0=0r0=0r=falsefal=false  "#, -        "invalid number at line 2" +        "invalid number at line 2 column 3"      );  } diff --git a/test-suite/tests/serde.rs b/test-suite/tests/serde.rs index bf019d4..95b8bc4 100644 --- a/test-suite/tests/serde.rs +++ b/test-suite/tests/serde.rs @@ -44,21 +44,17 @@ macro_rules! equivalent {  }  macro_rules! error { -    ($ty:ty, $toml:expr, $error:expr) => {{ +    ($ty:ty, $toml:expr, $msg_parse:expr, $msg_decode:expr) => {{          println!("attempting parsing");          match toml::from_str::<$ty>(&$toml.to_string()) {              Ok(_) => panic!("successful"), -            Err(e) => { -                assert!(e.to_string().contains($error), "bad error: {}", e); -            } +            Err(e) => assert_eq!(e.to_string(), $msg_parse),          }          println!("attempting toml decoding");          match $toml.try_into::<$ty>() {              Ok(_) => panic!("successful"), -            Err(e) => { -                assert!(e.to_string().contains($error), "bad error: {}", e); -            } +            Err(e) => assert_eq!(e.to_string(), $msg_decode),          }      }};  } @@ -277,6 +273,7 @@ fn type_errors() {          Table(map! {              bar: Value::String("a".to_string())          }), +        "invalid type: string \"a\", expected isize for key `bar`",          "invalid type: string \"a\", expected isize for key `bar`"      } @@ -293,6 +290,7 @@ fn type_errors() {                  bar: Value::String("a".to_string())              })          }), +        "invalid type: string \"a\", expected isize for key `foo.bar`",          "invalid type: string \"a\", expected isize for key `foo.bar`"      }  } @@ -307,6 +305,7 @@ fn missing_errors() {      error! {          Foo,          Table(map! { }), +        "missing field `bar`",          "missing field `bar`"      }  }  |