aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-07-29 09:06:35 -0500
committerGitHub <noreply@github.com>2019-07-29 09:06:35 -0500
commit5c6c3750727515fa4fc5bc3bc653293f5293f2c6 (patch)
treea043f6de866915df978bf7c166b7261b3c5d6335
parent844a1a4651d6b77a5b48159348d9cccbd8f4c88f (diff)
parent3d08775266eb1979956b03add38e6bd4824f521a (diff)
downloadmilf-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.rs2
-rw-r--r--test-suite/tests/backcompat.rs19
-rw-r--r--test-suite/tests/datetime.rs108
-rw-r--r--test-suite/tests/invalid-misc.rs56
-rw-r--r--test-suite/tests/invalid.rs178
-rw-r--r--test-suite/tests/parser.rs297
-rw-r--r--test-suite/tests/serde.rs13
7 files changed, 469 insertions, 204 deletions
diff --git a/src/de.rs b/src/de.rs
index 077c008..f65492d 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -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`"
}
}