diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2019-08-12 15:35:35 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-12 15:35:35 -0500 | 
| commit | 72881c2a06f9c51377d8a13f7d6bd0be36171b55 (patch) | |
| tree | dfed9914f8deb222d3204cfb494d6695fe786ea9 /test-suite | |
| parent | fa9740540f7a13675b578d6cde84d65aeb03e0b5 (diff) | |
| parent | 144e1d0f90f3e83e7e3cf0764869c2bbef687397 (diff) | |
| download | milf-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.toml | 2 | ||||
| -rw-r--r-- | test-suite/tests/datetime.rs | 56 | ||||
| -rw-r--r-- | test-suite/tests/de-errors.rs | 325 | ||||
| -rw-r--r-- | test-suite/tests/invalid-misc.rs | 7 | ||||
| -rw-r--r-- | test-suite/tests/invalid.rs | 10 | ||||
| -rw-r--r-- | test-suite/tests/parser.rs | 37 | ||||
| -rw-r--r-- | test-suite/tests/serde.rs | 4 | 
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`"      }  }  |