aboutsummaryrefslogtreecommitdiff
path: root/test-suite
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-08-12 15:35:35 -0500
committerGitHub <noreply@github.com>2019-08-12 15:35:35 -0500
commit72881c2a06f9c51377d8a13f7d6bd0be36171b55 (patch)
treedfed9914f8deb222d3204cfb494d6695fe786ea9 /test-suite
parentfa9740540f7a13675b578d6cde84d65aeb03e0b5 (diff)
parent144e1d0f90f3e83e7e3cf0764869c2bbef687397 (diff)
downloadmilf-rs-72881c2a06f9c51377d8a13f7d6bd0be36171b55.tar.gz
milf-rs-72881c2a06f9c51377d8a13f7d6bd0be36171b55.zip
Merge pull request #314 from zertosh/add-line-and-col-to-errors
Add line and column to all Errors
Diffstat (limited to 'test-suite')
-rw-r--r--test-suite/Cargo.toml2
-rw-r--r--test-suite/tests/datetime.rs56
-rw-r--r--test-suite/tests/de-errors.rs325
-rw-r--r--test-suite/tests/invalid-misc.rs7
-rw-r--r--test-suite/tests/invalid.rs10
-rw-r--r--test-suite/tests/parser.rs37
-rw-r--r--test-suite/tests/serde.rs4
7 files changed, 398 insertions, 43 deletions
diff --git a/test-suite/Cargo.toml b/test-suite/Cargo.toml
index 4f4db16..9f500b3 100644
--- a/test-suite/Cargo.toml
+++ b/test-suite/Cargo.toml
@@ -7,6 +7,6 @@ edition = "2018"
[dev-dependencies]
toml = { path = ".." }
-serde = "1.0"
+serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0"
diff --git a/test-suite/tests/datetime.rs b/test-suite/tests/datetime.rs
index 4855f54..74b5939 100644
--- a/test-suite/tests/datetime.rs
+++ b/test-suite/tests/datetime.rs
@@ -42,75 +42,93 @@ fn times() {
#[test]
fn bad_times() {
- 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 = 199-09-09",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
+ bad!(
+ "foo = 199709-09",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
+ bad!(
+ "foo = 1997-9-09",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
+ bad!(
+ "foo = 1997-09-9",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
bad!(
"foo = 1997-09-0909:09:09",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
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",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
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 = TZ",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
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`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09+09:9",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09+0909",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09-",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09-09",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09-09:9",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T09:09:09.09-0909",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-00-09T09:09:09.09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-00T09:09:09.09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T30:09:09.09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T12:69:09.09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 1997-09-09T12:09:69.09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
}
diff --git a/test-suite/tests/de-errors.rs b/test-suite/tests/de-errors.rs
new file mode 100644
index 0000000..7cceb7b
--- /dev/null
+++ b/test-suite/tests/de-errors.rs
@@ -0,0 +1,325 @@
+extern crate serde;
+extern crate toml;
+
+use serde::{de, Deserialize};
+use std::fmt;
+
+macro_rules! bad {
+ ($toml:expr, $ty:ty, $msg:expr) => {
+ match toml::from_str::<$ty>($toml) {
+ Ok(s) => panic!("parsed to: {:#?}", s),
+ Err(e) => assert_eq!(e.to_string(), $msg),
+ }
+ };
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct Parent<T> {
+ p_a: T,
+ p_b: Vec<Child<T>>,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(deny_unknown_fields)]
+struct Child<T> {
+ c_a: T,
+ c_b: T,
+}
+
+#[derive(Debug, PartialEq)]
+enum CasedString {
+ Lowercase(String),
+ Uppercase(String),
+}
+
+impl<'de> de::Deserialize<'de> for CasedString {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct CasedStringVisitor;
+
+ impl<'de> de::Visitor<'de> for CasedStringVisitor {
+ type Value = CasedString;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ if s.is_empty() {
+ Err(de::Error::invalid_length(0, &"a non-empty string"))
+ } else if s.chars().all(|x| x.is_ascii_lowercase()) {
+ Ok(CasedString::Lowercase(s.to_string()))
+ } else if s.chars().all(|x| x.is_ascii_uppercase()) {
+ Ok(CasedString::Uppercase(s.to_string()))
+ } else {
+ Err(de::Error::invalid_value(
+ de::Unexpected::Str(s),
+ &"all lowercase or all uppercase",
+ ))
+ }
+ }
+ }
+
+ deserializer.deserialize_any(CasedStringVisitor)
+ }
+}
+
+#[test]
+fn custom_errors() {
+ toml::from_str::<Parent<CasedString>>(
+ "
+ p_a = 'a'
+ p_b = [{c_a = 'a', c_b = 'c'}]
+ ",
+ )
+ .unwrap();
+
+ // Custom error at p_b value.
+ bad!(
+ "
+ p_a = ''
+ # ^
+ ",
+ Parent<CasedString>,
+ "invalid length 0, expected a non-empty string for key `p_a` at line 2 column 19"
+ );
+
+ // Missing field in table.
+ bad!(
+ "
+ p_a = 'a'
+ # ^
+ ",
+ Parent<CasedString>,
+ "missing field `p_b` at line 1 column 1"
+ );
+
+ // Invalid type in p_b.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = 1
+ # ^
+ ",
+ Parent<CasedString>,
+ "invalid type: integer `1`, expected a sequence for key `p_b` at line 3 column 19"
+ );
+
+ // Sub-table in Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "missing field `c_b` for key `p_b` at line 4 column 17"
+ );
+
+ // Sub-table in Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = '*'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "invalid value: string \"*\", expected all lowercase or all uppercase for key `p_b` at line 4 column 35"
+ );
+
+ // Sub-table in Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "missing field `c_b` for key `p_b` at line 5 column 17"
+ );
+
+ // Sub-table in the middle of a Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa'},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "missing field `c_b` for key `p_b` at line 5 column 17"
+ );
+
+ // Sub-table in the middle of a Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa', c_b = 1},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "invalid type: integer `1`, expected a string for key `p_b` at line 5 column 36"
+ );
+
+ // Sub-table in the middle of a Vec has an extra field.
+ // FIXME: This location could be better.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa', c_b = 'bb', c_d = 'd'},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ {c_a = 'aaaa', c_b = 'bbbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "unknown field `c_d`, expected `c_a` or `c_b` for key `p_b` at line 5 column 17"
+ );
+
+ // Sub-table in the middle of a Vec is missing a field.
+ // FIXME: This location is pretty off.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ # c_b = 'bb' # <- missing field
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ [[p_b]]
+ # ^
+ c_a = 'aaaa'
+ c_b = 'bbbb'
+ ",
+ Parent<CasedString>,
+ "missing field `c_b` for key `p_b` at line 12 column 13"
+ );
+
+ // Sub-table in the middle of a Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ c_b = '*'
+ # ^
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ ",
+ Parent<CasedString>,
+ "invalid value: string \"*\", expected all lowercase or all uppercase for key `p_b.c_b` at line 8 column 19"
+ );
+
+ // Sub-table in the middle of a Vec has an extra field.
+ // FIXME: This location is pretty off.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ c_d = 'dd' # unknown field
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ [[p_b]]
+ # ^
+ c_a = 'aaaa'
+ c_b = 'bbbb'
+ ",
+ Parent<CasedString>,
+ "unknown field `c_d`, expected `c_a` or `c_b` for key `p_b` at line 12 column 13"
+ );
+}
+
+#[test]
+fn serde_derive_deserialize_errors() {
+ bad!(
+ "
+ p_a = ''
+ # ^
+ ",
+ Parent<String>,
+ "missing field `p_b` at line 1 column 1"
+ );
+
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = ''}
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "missing field `c_b` for key `p_b` at line 4 column 17"
+ );
+
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = '', c_b = 1}
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "invalid type: integer `1`, expected a string for key `p_b` at line 4 column 34"
+ );
+
+ // FIXME: This location could be better.
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = '', c_b = '', c_d = ''},
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "unknown field `c_d`, expected `c_a` or `c_b` for key `p_b` at line 4 column 17"
+ );
+
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = '', c_b = 1, c_d = ''},
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "invalid type: integer `1`, expected a string for key `p_b` at line 4 column 34"
+ );
+}
diff --git a/test-suite/tests/invalid-misc.rs b/test-suite/tests/invalid-misc.rs
index f18012a..cea0801 100644
--- a/test-suite/tests/invalid-misc.rs
+++ b/test-suite/tests/invalid-misc.rs
@@ -27,14 +27,17 @@ fn bad() {
);
bad!("a = -0x1", "invalid number at line 1 column 5");
- bad!("a = 0x-1", "failed to parse datetime for key `a`");
+ bad!(
+ "a = 0x-1",
+ "failed to parse datetime for key `a` at line 1 column 5"
+ );
// Dotted keys.
bad!(
"a.b.c = 1
a.b = 2
",
- "duplicate key: `b` for key `a`"
+ "duplicate key: `b` for key `a` at line 1 column 9"
);
bad!(
"a = 1
diff --git a/test-suite/tests/invalid.rs b/test-suite/tests/invalid.rs
index bfde2d4..3312629 100644
--- a/test-suite/tests/invalid.rs
+++ b/test-suite/tests/invalid.rs
@@ -32,7 +32,7 @@ test!(
test!(
datetime_malformed_no_leads,
include_str!("invalid/datetime-malformed-no-leads.toml"),
- "failed to parse datetime for key `no-leads`"
+ "failed to parse datetime for key `no-leads` at line 1 column 12"
);
test!(
datetime_malformed_no_secs,
@@ -42,22 +42,22 @@ test!(
test!(
datetime_malformed_no_t,
include_str!("invalid/datetime-malformed-no-t.toml"),
- "failed to parse datetime for key `no-t`"
+ "failed to parse datetime for key `no-t` at line 1 column 8"
);
test!(
datetime_malformed_with_milli,
include_str!("invalid/datetime-malformed-with-milli.toml"),
- "failed to parse datetime for key `with-milli`"
+ "failed to parse datetime for key `with-milli` at line 1 column 14"
);
test!(
duplicate_key_table,
include_str!("invalid/duplicate-key-table.toml"),
- "duplicate key: `type` for key `fruit`"
+ "duplicate key: `type` for key `fruit` at line 4 column 1"
);
test!(
duplicate_keys,
include_str!("invalid/duplicate-keys.toml"),
- "duplicate key: `dupe`"
+ "duplicate key: `dupe` at line 1 column 1"
);
test!(
duplicate_table,
diff --git a/test-suite/tests/parser.rs b/test-suite/tests/parser.rs
index 1a684c5..012bd65 100644
--- a/test-suite/tests/parser.rs
+++ b/test-suite/tests/parser.rs
@@ -453,7 +453,10 @@ fn inline_tables() {
"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 = {a=1,a=1}",
+ "duplicate key: `a` for key `a` at line 1 column 5"
+ );
bad!(
"a = {\n}",
"expected a table key, found a newline at line 1 column 6"
@@ -533,9 +536,15 @@ fn booleans() {
let table = "foo = false".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_bool(), Some(false));
- bad!("foo = true2", "failed to parse datetime for key `foo`");
+ bad!(
+ "foo = true2",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
bad!("foo = false2", "invalid number at line 1 column 7");
- bad!("foo = t1", "failed to parse datetime for key `foo`");
+ bad!(
+ "foo = t1",
+ "failed to parse datetime for key `foo` at line 1 column 7"
+ );
bad!("foo = f2", "invalid number at line 1 column 7");
}
@@ -547,28 +556,28 @@ fn bad_nesting() {
[[a]]
b = 5
",
- "duplicate key: `a`"
+ "duplicate key: `a` at line 3 column 9"
);
bad!(
"
a = 1
[a.b]
",
- "duplicate key: `a`"
+ "duplicate key: `a` at line 3 column 9"
);
bad!(
"
a = []
[a.b]
",
- "duplicate key: `a`"
+ "duplicate key: `a` at line 3 column 9"
);
bad!(
"
a = []
[[a.b]]
",
- "duplicate key: `a`"
+ "duplicate key: `a` at line 3 column 9"
);
bad!(
"
@@ -577,7 +586,7 @@ fn bad_nesting() {
[a.b]
c = 2
",
- "duplicate key: `b` for key `a`"
+ "duplicate key: `b` for key `a` at line 4 column 9"
);
}
@@ -608,7 +617,7 @@ fn bad_table_redefine() {
b = {}
[a.b]
",
- "duplicate key: `b` for key `a`"
+ "duplicate key: `b` for key `a` at line 4 column 9"
);
bad!(
@@ -637,23 +646,23 @@ fn datetimes() {
t!("2016-09-09T09:09:09.123456789-02:00");
bad!(
"foo = 2016-09-09T09:09:09.Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 2016-9-09T09:09:09Z",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 2016-09-09T09:09:09+2:00",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 2016-09-09T09:09:09-2:00",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
bad!(
"foo = 2016-09-09T09:09:09Z-2:00",
- "failed to parse datetime for key `foo`"
+ "failed to parse datetime for key `foo` at line 1 column 7"
);
}
diff --git a/test-suite/tests/serde.rs b/test-suite/tests/serde.rs
index 95b8bc4..56172bd 100644
--- a/test-suite/tests/serde.rs
+++ b/test-suite/tests/serde.rs
@@ -273,7 +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` at line 1 column 7",
"invalid type: string \"a\", expected isize for key `bar`"
}
@@ -290,7 +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` at line 2 column 7",
"invalid type: string \"a\", expected isize for key `foo.bar`"
}
}