Merge pull request #1091 from serde-rs/fields-len

Catch wrong field names length in serde_test
This commit is contained in:
David Tolnay 2017-11-12 10:28:26 -08:00 committed by GitHub
commit 80cd9c7617
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 23 deletions

View File

@ -215,7 +215,7 @@ where
/// ///
/// assert_de_tokens_error::<S>( /// assert_de_tokens_error::<S>(
/// &[ /// &[
/// Token::Struct { name: "S", len: 1 }, /// Token::Struct { name: "S", len: 2 },
/// Token::Str("x"), /// Token::Str("x"),
/// ], /// ],
/// "unknown field `x`, expected `a` or `b`", /// "unknown field `x`, expected `a` or `b`",

View File

@ -352,8 +352,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
V: Visitor<'de>, V: Visitor<'de>,
{ {
match self.peek_token() { match self.peek_token() {
Token::Struct { len: n, .. } => { Token::Struct { .. } => {
assert_next_token!(self, Token::Struct { name: name, len: n }); assert_next_token!(self, Token::Struct { name: name, len: fields.len() });
self.visit_map(Some(fields.len()), Token::StructEnd, visitor) self.visit_map(Some(fields.len()), Token::StructEnd, visitor)
} }
Token::Map { .. } => { Token::Map { .. } => {

View File

@ -425,6 +425,10 @@ pub enum Token {
/// The header of a struct. /// The header of a struct.
/// ///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct expects to deserialize. This may be different
/// from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct, followed by `StructEnd`. /// After this header are the fields of the struct, followed by `StructEnd`.
/// ///
/// ```rust /// ```rust
@ -461,6 +465,10 @@ pub enum Token {
/// The header of a struct variant of an enum. /// The header of a struct variant of an enum.
/// ///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct variant expects to deserialize. This may be
/// different from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct variant, followed by /// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`. /// `StructVariantEnd`.
/// ///

View File

@ -135,7 +135,7 @@ fn test_default_struct() {
a5: 123, a5: 123,
}, },
&[ &[
Token::Struct { name: "DefaultStruct", len: 1 }, Token::Struct { name: "DefaultStruct", len: 3 },
Token::Str("a1"), Token::Str("a1"),
Token::I32(1), Token::I32(1),
@ -309,7 +309,7 @@ fn test_elt_not_deserialize() {
c: NotDeserializeStruct(123), c: NotDeserializeStruct(123),
e: NotDeserializeEnum::Trouble, e: NotDeserializeEnum::Trouble,
}, },
&[Token::Struct { name: "ContainsNotDeserialize", len: 3 }, Token::StructEnd], &[Token::Struct { name: "ContainsNotDeserialize", len: 1 }, Token::StructEnd],
); );
} }
@ -331,7 +331,7 @@ fn test_ignore_unknown() {
a5: 123, a5: 123,
}, },
&[ &[
Token::Struct { name: "DefaultStruct", len: 5 }, Token::Struct { name: "DefaultStruct", len: 3 },
Token::Str("whoops1"), Token::Str("whoops1"),
Token::I32(2), Token::I32(2),
@ -359,7 +359,7 @@ fn test_ignore_unknown() {
assert_de_tokens_error::<DenyUnknown>( assert_de_tokens_error::<DenyUnknown>(
&[ &[
Token::Struct { name: "DenyUnknown", len: 2 }, Token::Struct { name: "DenyUnknown", len: 1 },
Token::Str("a1"), Token::Str("a1"),
Token::I32(1), Token::I32(1),

View File

@ -538,7 +538,7 @@ declare_tests! {
Token::MapEnd, Token::MapEnd,
], ],
Struct { a: 1, b: 2, c: 0 } => &[ Struct { a: 1, b: 2, c: 0 } => &[
Token::Struct { name: "Struct", len: 3 }, Token::Struct { name: "Struct", len: 2 },
Token::Str("a"), Token::Str("a"),
Token::I32(1), Token::I32(1),
@ -570,7 +570,7 @@ declare_tests! {
Token::MapEnd, Token::MapEnd,
], ],
Struct { a: 1, b: 2, c: 0 } => &[ Struct { a: 1, b: 2, c: 0 } => &[
Token::Struct { name: "Struct", len: 3 }, Token::Struct { name: "Struct", len: 2 },
Token::Str("a"), Token::Str("a"),
Token::I32(1), Token::I32(1),
@ -591,7 +591,7 @@ declare_tests! {
Token::StructEnd, Token::StructEnd,
], ],
StructSkipAll { a: 0 } => &[ StructSkipAll { a: 0 } => &[
Token::Struct { name: "StructSkipAll", len: 1 }, Token::Struct { name: "StructSkipAll", len: 0 },
Token::Str("a"), Token::Str("a"),
Token::I32(1), Token::I32(1),
@ -608,7 +608,7 @@ declare_tests! {
} }
test_struct_default { test_struct_default {
StructDefault { a: 50, b: "overwritten".to_string() } => &[ StructDefault { a: 50, b: "overwritten".to_string() } => &[
Token::Struct { name: "StructDefault", len: 1 }, Token::Struct { name: "StructDefault", len: 2 },
Token::Str("a"), Token::Str("a"),
Token::I32(50), Token::I32(50),
@ -617,7 +617,7 @@ declare_tests! {
Token::StructEnd, Token::StructEnd,
], ],
StructDefault { a: 100, b: "default".to_string() } => &[ StructDefault { a: 100, b: "default".to_string() } => &[
Token::Struct { name: "StructDefault", len: 0 }, Token::Struct { name: "StructDefault", len: 2 },
Token::StructEnd, Token::StructEnd,
], ],
} }
@ -954,7 +954,7 @@ fn test_cstr_internal_null_end() {
declare_error_tests! { declare_error_tests! {
test_unknown_field<StructDenyUnknown> { test_unknown_field<StructDenyUnknown> {
&[ &[
Token::Struct { name: "StructDenyUnknown", len: 2 }, Token::Struct { name: "StructDenyUnknown", len: 1 },
Token::Str("a"), Token::Str("a"),
Token::I32(0), Token::I32(0),
@ -964,14 +964,14 @@ declare_error_tests! {
} }
test_skipped_field_is_unknown<StructDenyUnknown> { test_skipped_field_is_unknown<StructDenyUnknown> {
&[ &[
Token::Struct { name: "StructDenyUnknown", len: 2 }, Token::Struct { name: "StructDenyUnknown", len: 1 },
Token::Str("b"), Token::Str("b"),
], ],
"unknown field `b`, expected `a`", "unknown field `b`, expected `a`",
} }
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> { test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
&[ &[
Token::Struct { name: "StructSkipAllDenyUnknown", len: 1 }, Token::Struct { name: "StructSkipAllDenyUnknown", len: 0 },
Token::Str("a"), Token::Str("a"),
], ],
"unknown field `a`, there are no fields", "unknown field `a`, there are no fields",

View File

@ -786,7 +786,7 @@ fn test_adjacently_tagged_enum() {
} }
// unit with no content // unit with no content
assert_tokens( assert_ser_tokens(
&AdjacentlyTagged::Unit::<u8>, &AdjacentlyTagged::Unit::<u8>,
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 1 }, Token::Struct { name: "AdjacentlyTagged", len: 1 },
@ -798,11 +798,24 @@ fn test_adjacently_tagged_enum() {
], ],
); );
// unit with no content
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"),
Token::Str("Unit"),
Token::StructEnd,
],
);
// unit with tag first // unit with tag first
assert_de_tokens( assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>, &AdjacentlyTagged::Unit::<u8>,
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 1 }, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::Str("Unit"),
@ -818,7 +831,7 @@ fn test_adjacently_tagged_enum() {
assert_de_tokens( assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>, &AdjacentlyTagged::Unit::<u8>,
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 1 }, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,
@ -834,7 +847,7 @@ fn test_adjacently_tagged_enum() {
assert_de_tokens( assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>, &AdjacentlyTagged::Unit::<u8>,
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 3 }, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("f"), Token::Str("f"),
Token::Unit, Token::Unit,
@ -975,7 +988,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens( assert_de_tokens(
&AdjacentlyTagged::Unit, &AdjacentlyTagged::Unit,
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 2}, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::Str("Unit"),
@ -989,7 +1002,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>( assert_de_tokens_error::<AdjacentlyTagged>(
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 3}, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::Str("Unit"),
@ -1004,7 +1017,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>( assert_de_tokens_error::<AdjacentlyTagged>(
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 3}, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("h"), Token::Str("h"),
], ],
@ -1013,7 +1026,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>( assert_de_tokens_error::<AdjacentlyTagged>(
&[ &[
Token::Struct { name: "AdjacentlyTagged", len: 3}, Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,