From 5e37ade519df3ad1c82d18b12d7b2216e549678e Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 01:46:37 +0500 Subject: [PATCH 01/19] Move all adjacently tagged enum tests (except flatten) into a dedicated module Moved and renamed: From test_annotatons - test_adjacently_tagged_enum_bytes => bytes - flatten::enum_::adjacently_tagged::straitforward=> struct_with_flatten - test_expecting_message_adjacently_tagged_enum => expecting_message - test_partially_untagged_adjacently_tagged_enum => partially_untagged From test_macros - test_adjacently_tagged_newtype_struct => newtype_with_newtype - test_adjacently_tagged_enum - test_adjacently_tagged_enum_deny_unknown_fields => deny_unknown_fields --- test_suite/tests/test_annotations.rs | 157 ----- .../tests/test_enum_adjacently_tagged.rs | 594 ++++++++++++++++++ test_suite/tests/test_macros.rs | 422 ------------- 3 files changed, 594 insertions(+), 579 deletions(-) create mode 100644 test_suite/tests/test_enum_adjacently_tagged.rs diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 9aa328725..9d03280d2 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -1607,59 +1607,6 @@ fn test_collect_other() { ); } -#[test] -fn test_adjacently_tagged_enum_bytes() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t", content = "c")] - enum Data { - A { a: i32 }, - } - - let data = Data::A { a: 0 }; - - assert_tokens( - &data, - &[ - Token::Struct { - name: "Data", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "Data", - variant: "A", - }, - Token::Str("c"), - Token::Struct { name: "A", len: 1 }, - Token::Str("a"), - Token::I32(0), - Token::StructEnd, - Token::StructEnd, - ], - ); - - assert_de_tokens( - &data, - &[ - Token::Struct { - name: "Data", - len: 2, - }, - Token::Bytes(b"t"), - Token::UnitVariant { - name: "Data", - variant: "A", - }, - Token::Bytes(b"c"), - Token::Struct { name: "A", len: 1 }, - Token::Str("a"), - Token::I32(0), - Token::StructEnd, - Token::StructEnd, - ], - ); -} - #[test] fn test_partially_untagged_enum() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -1846,38 +1793,6 @@ fn test_partially_untagged_internally_tagged_enum() { // TODO test error output } -#[test] -fn test_partially_untagged_adjacently_tagged_enum() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t", content = "c")] - enum Data { - A(u32), - B, - #[serde(untagged)] - Var(u32), - } - - let data = Data::A(7); - - assert_de_tokens( - &data, - &[ - Token::Map { len: None }, - Token::Str("t"), - Token::Str("A"), - Token::Str("c"), - Token::U32(7), - Token::MapEnd, - ], - ); - - let data = Data::Var(42); - - assert_de_tokens(&data, &[Token::U32(42)]); - - // TODO test error output -} - #[test] fn test_transparent_struct() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -1980,32 +1895,6 @@ fn test_expecting_message_externally_tagged_enum() { ); } -#[test] -fn test_expecting_message_adjacently_tagged_enum() { - #[derive(Deserialize)] - #[serde(tag = "tag", content = "content")] - #[serde(expecting = "something strange...")] - enum Enum { - AdjacentlyTagged, - } - - assert_de_tokens_error::( - &[Token::Str("AdjacentlyTagged")], - r#"invalid type: string "AdjacentlyTagged", expected something strange..."#, - ); - - assert_de_tokens_error::( - &[Token::Map { len: None }, Token::Unit], - r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#, - ); - - // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message - assert_de_tokens_error::( - &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], - "invalid type: unit value, expected variant of enum Enum", - ); -} - #[test] fn test_expecting_message_untagged_tagged_enum() { #[derive(Deserialize)] @@ -2891,52 +2780,6 @@ mod flatten { mod adjacently_tagged { use super::*; - #[test] - fn straightforward() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t", content = "c")] - enum Data { - A { - a: i32, - #[serde(flatten)] - flat: Flat, - }, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Flat { - b: i32, - } - - let data = Data::A { - a: 0, - flat: Flat { b: 0 }, - }; - - assert_tokens( - &data, - &[ - Token::Struct { - name: "Data", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "Data", - variant: "A", - }, - Token::Str("c"), - Token::Map { len: None }, - Token::Str("a"), - Token::I32(0), - Token::Str("b"), - Token::I32(0), - Token::MapEnd, - Token::StructEnd, - ], - ); - } - #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { outer: u32, diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs new file mode 100644 index 000000000..e50d2e0a2 --- /dev/null +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -0,0 +1,594 @@ +#![deny(trivial_numeric_casts)] +#![allow( + clippy::derive_partial_eq_without_eq, + clippy::enum_variant_names, + clippy::redundant_field_names, + clippy::too_many_lines +)] + +use serde_derive::{Deserialize, Serialize}; +use serde_test::{ + assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token, +}; + +#[test] +fn test_adjacently_tagged_enum() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "t", content = "c")] + enum AdjacentlyTagged { + Unit, + Newtype(T), + Tuple(u8, u8), + Struct { f: u8 }, + } + + // unit with no content + assert_ser_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // unit with no content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // unit with tag first + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("c"), + Token::Unit, + Token::StructEnd, + ], + ); + + // unit with content first + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Unit, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // unit with excess content (f, g, h) + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("f"), + Token::Unit, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("g"), + Token::Unit, + Token::Str("c"), + Token::Unit, + Token::Str("h"), + Token::Unit, + Token::StructEnd, + ], + ); + + // newtype with tag first + assert_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::Str("c"), + Token::U8(1), + Token::StructEnd, + ], + ); + + // newtype with content first + assert_de_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::U8(1), + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + + // optional newtype with no content field + assert_de_tokens( + &AdjacentlyTagged::Newtype::>(None), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + + // tuple with tag first + assert_tokens( + &AdjacentlyTagged::Tuple::(1, 1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Tuple", + }, + Token::Str("c"), + Token::Tuple { len: 2 }, + Token::U8(1), + Token::U8(1), + Token::TupleEnd, + Token::StructEnd, + ], + ); + + // tuple with content first + assert_de_tokens( + &AdjacentlyTagged::Tuple::(1, 1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Tuple { len: 2 }, + Token::U8(1), + Token::U8(1), + Token::TupleEnd, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Tuple", + }, + Token::StructEnd, + ], + ); + + // struct with tag first + assert_tokens( + &AdjacentlyTagged::Struct:: { f: 1 }, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Struct", + }, + Token::Str("c"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::StructEnd, + ], + ); + + // struct with content first + assert_de_tokens( + &AdjacentlyTagged::Struct:: { f: 1 }, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Struct", + }, + Token::StructEnd, + ], + ); + + // integer field keys + assert_de_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::U64(1), // content field + Token::U8(1), + Token::U64(0), // tag field + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + + // byte-array field keys + assert_de_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Bytes(b"c"), + Token::U8(1), + Token::Bytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); +} + +#[test] +fn bytes() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t", content = "c")] + enum Data { + A { a: i32 }, + } + + let data = Data::A { a: 0 }; + + assert_tokens( + &data, + &[ + Token::Struct { + name: "Data", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "Data", + variant: "A", + }, + Token::Str("c"), + Token::Struct { name: "A", len: 1 }, + Token::Str("a"), + Token::I32(0), + Token::StructEnd, + Token::StructEnd, + ], + ); + + assert_de_tokens( + &data, + &[ + Token::Struct { + name: "Data", + len: 2, + }, + Token::Bytes(b"t"), + Token::UnitVariant { + name: "Data", + variant: "A", + }, + Token::Bytes(b"c"), + Token::Struct { name: "A", len: 1 }, + Token::Str("a"), + Token::I32(0), + Token::StructEnd, + Token::StructEnd, + ], + ); +} + +#[test] +fn struct_with_flatten() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t", content = "c")] + enum Data { + A { + a: i32, + #[serde(flatten)] + flat: Flat, + }, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Flat { + b: i32, + } + + let data = Data::A { + a: 0, + flat: Flat { b: 0 }, + }; + + assert_tokens( + &data, + &[ + Token::Struct { + name: "Data", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "Data", + variant: "A", + }, + Token::Str("c"), + Token::Map { len: None }, + Token::Str("a"), + Token::I32(0), + Token::Str("b"), + Token::I32(0), + Token::MapEnd, + Token::StructEnd, + ], + ); +} + +#[test] +fn expecting_message() { + #[derive(Deserialize)] + #[serde(tag = "tag", content = "content")] + #[serde(expecting = "something strange...")] + enum Enum { + AdjacentlyTagged, + } + + assert_de_tokens_error::( + &[Token::Str("AdjacentlyTagged")], + r#"invalid type: string "AdjacentlyTagged", expected something strange..."#, + ); + + assert_de_tokens_error::( + &[Token::Map { len: None }, Token::Unit], + r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#, + ); + + // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message + assert_de_tokens_error::( + &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], + "invalid type: unit value, expected variant of enum Enum", + ); +} + +#[test] +fn partially_untagged() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t", content = "c")] + enum Data { + A(u32), + B, + #[serde(untagged)] + Var(u32), + } + + let data = Data::A(7); + + assert_de_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("t"), + Token::Str("A"), + Token::Str("c"), + Token::U32(7), + Token::MapEnd, + ], + ); + + let data = Data::Var(42); + + assert_de_tokens(&data, &[Token::U32(42)]); + + // TODO test error output +} + +#[test] +fn newtype_with_newtype() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct GenericNewTypeStruct(T); + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "t", content = "c")] + enum E { + Newtype(GenericNewTypeStruct), + Null, + } + + assert_de_tokens( + &E::Newtype(GenericNewTypeStruct(5u32)), + &[ + Token::Struct { name: "E", len: 2 }, + Token::Str("c"), + Token::NewtypeStruct { + name: "GenericNewTypeStruct", + }, + Token::U32(5), + Token::Str("t"), + Token::UnitVariant { + name: "E", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); +} + +#[test] +fn deny_unknown_fields() { + #[derive(Debug, PartialEq, Deserialize)] + #[serde(tag = "t", content = "c", deny_unknown_fields)] + enum AdjacentlyTagged { + Unit, + } + + assert_de_tokens( + &AdjacentlyTagged::Unit, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("c"), + Token::Unit, + Token::StructEnd, + ], + ); + + assert_de_tokens_error::( + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("c"), + Token::Unit, + Token::Str("h"), + ], + r#"invalid value: string "h", expected "t" or "c""#, + ); + + assert_de_tokens_error::( + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("h"), + ], + r#"invalid value: string "h", expected "t" or "c""#, + ); + + assert_de_tokens_error::( + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Unit, + Token::Str("h"), + ], + r#"invalid value: string "h", expected "t" or "c""#, + ); + + assert_de_tokens_error::( + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::U64(0), // tag field + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::U64(3), + ], + r#"invalid value: integer `3`, expected "t" or "c""#, + ); + + assert_de_tokens_error::( + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Bytes(b"c"), + Token::Unit, + Token::Bytes(b"h"), + ], + r#"invalid value: byte array, expected "t" or "c""#, + ); +} diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 72137ddd0..aaab95816 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -453,34 +453,6 @@ fn test_untagged_newtype_struct() { ); } -#[test] -fn test_adjacently_tagged_newtype_struct() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t", content = "c")] - enum E { - Newtype(GenericNewTypeStruct), - Null, - } - - assert_de_tokens( - &E::Newtype(GenericNewTypeStruct(5u32)), - &[ - Token::Struct { name: "E", len: 2 }, - Token::Str("c"), - Token::NewtypeStruct { - name: "GenericNewTypeStruct", - }, - Token::U32(5), - Token::Str("t"), - Token::UnitVariant { - name: "E", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); -} - #[test] fn test_generic_tuple_struct() { assert_tokens( @@ -679,400 +651,6 @@ fn test_untagged_enum() { ); } -#[test] -fn test_adjacently_tagged_enum() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t", content = "c")] - enum AdjacentlyTagged { - Unit, - Newtype(T), - Tuple(u8, u8), - Struct { f: u8 }, - } - - // unit with no content - assert_ser_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 1, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); - - // unit with no content - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); - - // unit with tag first - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("c"), - Token::Unit, - Token::StructEnd, - ], - ); - - // unit with content first - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Unit, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); - - // unit with excess content (f, g, h) - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("f"), - Token::Unit, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("g"), - Token::Unit, - Token::Str("c"), - Token::Unit, - Token::Str("h"), - Token::Unit, - Token::StructEnd, - ], - ); - - // newtype with tag first - assert_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::Str("c"), - Token::U8(1), - Token::StructEnd, - ], - ); - - // newtype with content first - assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::U8(1), - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); - - // optional newtype with no content field - assert_de_tokens( - &AdjacentlyTagged::Newtype::>(None), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 1, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); - - // tuple with tag first - assert_tokens( - &AdjacentlyTagged::Tuple::(1, 1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Tuple", - }, - Token::Str("c"), - Token::Tuple { len: 2 }, - Token::U8(1), - Token::U8(1), - Token::TupleEnd, - Token::StructEnd, - ], - ); - - // tuple with content first - assert_de_tokens( - &AdjacentlyTagged::Tuple::(1, 1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Tuple { len: 2 }, - Token::U8(1), - Token::U8(1), - Token::TupleEnd, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Tuple", - }, - Token::StructEnd, - ], - ); - - // struct with tag first - assert_tokens( - &AdjacentlyTagged::Struct:: { f: 1 }, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::Str("c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::StructEnd, - ], - ); - - // struct with content first - assert_de_tokens( - &AdjacentlyTagged::Struct:: { f: 1 }, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::StructEnd, - ], - ); - - // integer field keys - assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::U64(1), // content field - Token::U8(1), - Token::U64(0), // tag field - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); - - // byte-array field keys - assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Bytes(b"c"), - Token::U8(1), - Token::Bytes(b"t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); -} - -#[test] -fn test_adjacently_tagged_enum_deny_unknown_fields() { - #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "t", content = "c", deny_unknown_fields)] - enum AdjacentlyTagged { - Unit, - } - - assert_de_tokens( - &AdjacentlyTagged::Unit, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("c"), - Token::Unit, - Token::StructEnd, - ], - ); - - assert_de_tokens_error::( - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("c"), - Token::Unit, - Token::Str("h"), - ], - r#"invalid value: string "h", expected "t" or "c""#, - ); - - assert_de_tokens_error::( - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("h"), - ], - r#"invalid value: string "h", expected "t" or "c""#, - ); - - assert_de_tokens_error::( - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Unit, - Token::Str("h"), - ], - r#"invalid value: string "h", expected "t" or "c""#, - ); - - assert_de_tokens_error::( - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::U64(0), // tag field - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::U64(3), - ], - r#"invalid value: integer `3`, expected "t" or "c""#, - ); - - assert_de_tokens_error::( - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Bytes(b"c"), - Token::Unit, - Token::Bytes(b"h"), - ], - r#"invalid value: byte array, expected "t" or "c""#, - ); -} - #[test] fn test_internally_tagged_struct() { #[derive(Debug, PartialEq, Serialize, Deserialize)] From 5a359e10f4a5e1a7230e58c2fd4b09d63b5664a9 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 01:57:15 +0500 Subject: [PATCH 02/19] Group Newtype variant checks in test_adjacently_tagged_enum together --- .../tests/test_enum_adjacently_tagged.rs | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index e50d2e0a2..a7968336b 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -174,6 +174,44 @@ fn test_adjacently_tagged_enum() { ], ); + // integer field keys + assert_de_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::U64(1), // content field + Token::U8(1), + Token::U64(0), // tag field + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + + // byte-array field keys + assert_de_tokens( + &AdjacentlyTagged::Newtype::(1), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Bytes(b"c"), + Token::U8(1), + Token::Bytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + // tuple with tag first assert_tokens( &AdjacentlyTagged::Tuple::(1, 1), @@ -267,44 +305,6 @@ fn test_adjacently_tagged_enum() { Token::StructEnd, ], ); - - // integer field keys - assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::U64(1), // content field - Token::U8(1), - Token::U64(0), // tag field - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); - - // byte-array field keys - assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Bytes(b"c"), - Token::U8(1), - Token::Bytes(b"t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); } #[test] From bee74707154049eb823732043c0e422b7b04a742 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 02:19:31 +0500 Subject: [PATCH 03/19] Split test test_adjacently_tagged_enum into four tests for each variant (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_adjacently_tagged.rs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index a7968336b..d60817cca 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -11,17 +11,17 @@ use serde_test::{ assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token, }; -#[test] -fn test_adjacently_tagged_enum() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t", content = "c")] - enum AdjacentlyTagged { - Unit, - Newtype(T), - Tuple(u8, u8), - Struct { f: u8 }, - } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(tag = "t", content = "c")] +enum AdjacentlyTagged { + Unit, + Newtype(T), + Tuple(u8, u8), + Struct { f: u8 }, +} +#[test] +fn unit() { // unit with no content assert_ser_tokens( &AdjacentlyTagged::Unit::, @@ -118,7 +118,10 @@ fn test_adjacently_tagged_enum() { Token::StructEnd, ], ); +} +#[test] +fn newtype() { // newtype with tag first assert_tokens( &AdjacentlyTagged::Newtype::(1), @@ -211,7 +214,10 @@ fn test_adjacently_tagged_enum() { Token::StructEnd, ], ); +} +#[test] +fn tuple() { // tuple with tag first assert_tokens( &AdjacentlyTagged::Tuple::(1, 1), @@ -255,7 +261,10 @@ fn test_adjacently_tagged_enum() { Token::StructEnd, ], ); +} +#[test] +fn struct_() { // struct with tag first assert_tokens( &AdjacentlyTagged::Struct:: { f: 1 }, From 59628d171272d8dd2de0508a177b0980cbf38694 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 02:48:56 +0500 Subject: [PATCH 04/19] Create only one value for all checks --- .../tests/test_enum_adjacently_tagged.rs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index d60817cca..4b2db7a27 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -122,9 +122,11 @@ fn unit() { #[test] fn newtype() { + let value = AdjacentlyTagged::Newtype::(1); + // newtype with tag first assert_tokens( - &AdjacentlyTagged::Newtype::(1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -143,7 +145,7 @@ fn newtype() { // newtype with content first assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -179,7 +181,7 @@ fn newtype() { // integer field keys assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -198,7 +200,7 @@ fn newtype() { // byte-array field keys assert_de_tokens( - &AdjacentlyTagged::Newtype::(1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -218,9 +220,11 @@ fn newtype() { #[test] fn tuple() { + let value = AdjacentlyTagged::Tuple::(1, 1); + // tuple with tag first assert_tokens( - &AdjacentlyTagged::Tuple::(1, 1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -242,7 +246,7 @@ fn tuple() { // tuple with content first assert_de_tokens( - &AdjacentlyTagged::Tuple::(1, 1), + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -265,9 +269,11 @@ fn tuple() { #[test] fn struct_() { + let value = AdjacentlyTagged::Struct:: { f: 1 }; + // struct with tag first assert_tokens( - &AdjacentlyTagged::Struct:: { f: 1 }, + &value, &[ Token::Struct { name: "AdjacentlyTagged", @@ -292,7 +298,7 @@ fn struct_() { // struct with content first assert_de_tokens( - &AdjacentlyTagged::Struct:: { f: 1 }, + &value, &[ Token::Struct { name: "AdjacentlyTagged", From 36b9a859c447244aa6ae4fd73dfe0d01f840e9e1 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 23:03:26 +0500 Subject: [PATCH 05/19] Test deserialization of the serialized unit format for adjacently tagged enum --- test_suite/tests/test_enum_adjacently_tagged.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 4b2db7a27..9836e4b02 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -7,9 +7,7 @@ )] use serde_derive::{Deserialize, Serialize}; -use serde_test::{ - assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token, -}; +use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "t", content = "c")] @@ -23,7 +21,7 @@ enum AdjacentlyTagged { #[test] fn unit() { // unit with no content - assert_ser_tokens( + assert_tokens( &AdjacentlyTagged::Unit::, &[ Token::Struct { @@ -39,7 +37,7 @@ fn unit() { ], ); - // unit with no content + // unit with no content and incorrect hint for number of elements assert_de_tokens( &AdjacentlyTagged::Unit::, &[ From 9d0f811221bbb7b9ec520278f036ed93ba5a3647 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 23:08:25 +0500 Subject: [PATCH 06/19] Remove unnecessary generic --- test_suite/tests/test_enum_adjacently_tagged.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 9836e4b02..eccdc3356 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -480,22 +480,22 @@ fn partially_untagged() { #[test] fn newtype_with_newtype() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct GenericNewTypeStruct(T); + struct NewtypeStruct(u32); #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "t", content = "c")] enum E { - Newtype(GenericNewTypeStruct), + Newtype(NewtypeStruct), Null, } assert_de_tokens( - &E::Newtype(GenericNewTypeStruct(5u32)), + &E::Newtype(NewtypeStruct(5)), &[ Token::Struct { name: "E", len: 2 }, Token::Str("c"), Token::NewtypeStruct { - name: "GenericNewTypeStruct", + name: "NewtypeStruct", }, Token::U32(5), Token::Str("t"), From 5445f1741b1269f81b67403ad8b602f214ae7452 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 23:10:12 +0500 Subject: [PATCH 07/19] Reuse AdjacentlyTagged enum in newtype_with_newtype test --- test_suite/tests/test_enum_adjacently_tagged.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index eccdc3356..f3be60d34 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -482,17 +482,13 @@ fn newtype_with_newtype() { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct NewtypeStruct(u32); - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t", content = "c")] - enum E { - Newtype(NewtypeStruct), - Null, - } - assert_de_tokens( - &E::Newtype(NewtypeStruct(5)), + &AdjacentlyTagged::Newtype(NewtypeStruct(5)), &[ - Token::Struct { name: "E", len: 2 }, + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, Token::Str("c"), Token::NewtypeStruct { name: "NewtypeStruct", @@ -500,7 +496,7 @@ fn newtype_with_newtype() { Token::U32(5), Token::Str("t"), Token::UnitVariant { - name: "E", + name: "AdjacentlyTagged", variant: "Newtype", }, Token::StructEnd, From df07751e6fad8d5ceeaa9f41e73fb6371de86ee6 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 23:11:31 +0500 Subject: [PATCH 08/19] Group newtype and newtype_with_newtype tests --- .../tests/test_enum_adjacently_tagged.rs | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index f3be60d34..ecb35d591 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -216,6 +216,33 @@ fn newtype() { ); } +#[test] +fn newtype_with_newtype() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct NewtypeStruct(u32); + + assert_de_tokens( + &AdjacentlyTagged::Newtype(NewtypeStruct(5)), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::NewtypeStruct { + name: "NewtypeStruct", + }, + Token::U32(5), + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); +} + #[test] fn tuple() { let value = AdjacentlyTagged::Tuple::(1, 1); @@ -477,33 +504,6 @@ fn partially_untagged() { // TODO test error output } -#[test] -fn newtype_with_newtype() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct NewtypeStruct(u32); - - assert_de_tokens( - &AdjacentlyTagged::Newtype(NewtypeStruct(5)), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::NewtypeStruct { - name: "NewtypeStruct", - }, - Token::U32(5), - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); -} - #[test] fn deny_unknown_fields() { #[derive(Debug, PartialEq, Deserialize)] From 42e63ff942311f2e15e9e8ae4c7f903934c53e6d Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 02:59:20 +0500 Subject: [PATCH 09/19] Reuse AdjacentlyTagged enum in `bytes` test Change 0i32 to 1u8 so the test can be merged with the previous in the next commit --- .../tests/test_enum_adjacently_tagged.rs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index ecb35d591..9894f9622 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -349,51 +349,51 @@ fn struct_() { #[test] fn bytes() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t", content = "c")] - enum Data { - A { a: i32 }, - } - - let data = Data::A { a: 0 }; + let value = AdjacentlyTagged::Struct:: { f: 1 }; assert_tokens( - &data, + &value, &[ Token::Struct { - name: "Data", + name: "AdjacentlyTagged", len: 2, }, Token::Str("t"), Token::UnitVariant { - name: "Data", - variant: "A", + name: "AdjacentlyTagged", + variant: "Struct", }, Token::Str("c"), - Token::Struct { name: "A", len: 1 }, - Token::Str("a"), - Token::I32(0), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), Token::StructEnd, Token::StructEnd, ], ); assert_de_tokens( - &data, + &value, &[ Token::Struct { - name: "Data", + name: "AdjacentlyTagged", len: 2, }, Token::Bytes(b"t"), Token::UnitVariant { - name: "Data", - variant: "A", + name: "AdjacentlyTagged", + variant: "Struct", }, Token::Bytes(b"c"), - Token::Struct { name: "A", len: 1 }, - Token::Str("a"), - Token::I32(0), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), Token::StructEnd, Token::StructEnd, ], From 3dc6829303556d4bfdbc63d1315c81dc2456f57c Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 14 Aug 2023 03:05:50 +0500 Subject: [PATCH 10/19] Integrate `bytes` test into `struct_` test `newtype` test also integrates test with `Bytes` tag, so be like Removed the first assert_tokens because it is the same as the first assert in the merged method --- .../tests/test_enum_adjacently_tagged.rs | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 9894f9622..55be6ca6a 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -345,36 +345,8 @@ fn struct_() { Token::StructEnd, ], ); -} - -#[test] -fn bytes() { - let value = AdjacentlyTagged::Struct:: { f: 1 }; - - assert_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::Str("c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::StructEnd, - ], - ); + // byte-array field keys assert_de_tokens( &value, &[ From a7f0bab078ea5226c244069f43738c5e896483c2 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 12 Aug 2024 00:49:58 +0500 Subject: [PATCH 11/19] Document fields in internal structs used to deserialize adjacently tagged enums --- serde/src/private/de.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index c146539ee..6c81b720b 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -904,7 +904,9 @@ mod content { /// Not public API. pub struct TagOrContentFieldVisitor { + /// Name of the tag field of the adjacently tagged enum pub tag: &'static str, + /// Name of the content field of the adjacently tagged enum pub content: &'static str, } @@ -979,7 +981,9 @@ mod content { /// Not public API. pub struct TagContentOtherFieldVisitor { + /// Name of the tag field of the adjacently tagged enum pub tag: &'static str, + /// Name of the content field of the adjacently tagged enum pub content: &'static str, } From 29dc6c33674f48e4010cc72cee8ab8d0118d5c50 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 12 Aug 2024 00:45:29 +0500 Subject: [PATCH 12/19] Unit: add tests for deserialization from sequence (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_adjacently_tagged.rs | 237 +++++++++++------- 1 file changed, 141 insertions(+), 96 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 55be6ca6a..ee397855f 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -18,104 +18,149 @@ enum AdjacentlyTagged { Struct { f: u8 }, } -#[test] -fn unit() { - // unit with no content - assert_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 1, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); - - // unit with no content and incorrect hint for number of elements - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); - - // unit with tag first - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("c"), - Token::Unit, - Token::StructEnd, - ], - ); +mod unit { + use super::*; + + #[test] + fn map_str_tag_only() { + // Map: tag only + assert_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // Map: tag only and incorrect hint for number of elements + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + } - // unit with content first - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Unit, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::StructEnd, - ], - ); + #[test] + fn map_str_tag_content() { + // Map: tag + content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("c"), + Token::Unit, + Token::StructEnd, + ], + ); + // Map: content + tag + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Unit, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // Map: tag + content + excess fields (f, g, h) + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("f"), + Token::Unit, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Str("g"), + Token::Unit, + Token::Str("c"), + Token::Unit, + Token::Str("h"), + Token::Unit, + Token::StructEnd, + ], + ); + } - // unit with excess content (f, g, h) - assert_de_tokens( - &AdjacentlyTagged::Unit::, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("f"), - Token::Unit, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Unit", - }, - Token::Str("g"), - Token::Unit, - Token::Str("c"), - Token::Unit, - Token::Str("h"), - Token::Unit, - Token::StructEnd, - ], - ); + #[test] + fn seq_tag_content() { + // Seq: tag and content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Seq { len: Some(2) }, + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::Unit, + Token::SeqEnd, + ], + ); + + // Seq: tag (as string) and content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Seq { len: None }, + Token::Str("Unit"), // tag + Token::Unit, // content + Token::SeqEnd, + ], + ); + + // Seq: tag (as borrowed string) and content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Seq { len: None }, + Token::BorrowedStr("Unit"), // tag + Token::Unit, // content + Token::SeqEnd, + ], + ); + } } #[test] From a02da49b87cb7d416cb672c55d61c6a9177630b0 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 12 Aug 2024 01:06:51 +0500 Subject: [PATCH 13/19] Unit: add tests for deserialization from integer tag and content fields --- .../tests/test_enum_adjacently_tagged.rs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index ee397855f..6c2520234 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -58,6 +58,26 @@ mod unit { ); } + #[test] + fn map_int_tag_only() { + // Map: tag (as number) only + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::U16(0), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + } + #[test] fn map_str_tag_content() { // Map: tag + content @@ -123,6 +143,47 @@ mod unit { ); } + #[test] + fn map_int_tag_content() { + // Map: tag (as number) + content (as number) + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::U8(0), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::U8(1), + Token::Unit, + Token::StructEnd, + ], + ); + + // Map: content (as number) + tag (as number) + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::U64(1), + Token::Unit, + Token::U64(0), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + } + #[test] fn seq_tag_content() { // Seq: tag and content From 6bfe1c435ad8f946f8269b9a39af79507a897cdd Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:35:54 +0500 Subject: [PATCH 14/19] Unit: add tests for deserialization from bytes tag and content fields --- .../tests/test_enum_adjacently_tagged.rs | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 6c2520234..8546c9a41 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -78,6 +78,43 @@ mod unit { ); } + #[test] + fn map_bytes_tag_only() { + // Map: tag only + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::Bytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + + // Map: tag only + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::BorrowedBytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + } + #[test] fn map_str_tag_content() { // Map: tag + content @@ -184,6 +221,47 @@ mod unit { ); } + #[test] + fn map_bytes_tag_content() { + // Map: tag + content + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::BorrowedBytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::BorrowedBytes(b"c"), + Token::Unit, + Token::StructEnd, + ], + ); + + // Map: content + tag + assert_de_tokens( + &AdjacentlyTagged::Unit::, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Bytes(b"c"), + Token::Unit, + Token::Bytes(b"t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Unit", + }, + Token::StructEnd, + ], + ); + } + #[test] fn seq_tag_content() { // Seq: tag and content From d5a9c11b5c9a72aca31a4fa5898c54945b26f325 Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:46:41 +0500 Subject: [PATCH 15/19] No need to test integer and byte array field names, they already tested for Unit case There is no difference what variant is deserialized so we can test only one kind of variant --- .../tests/test_enum_adjacently_tagged.rs | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 8546c9a41..6c8489eb9 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -360,44 +360,6 @@ fn newtype() { Token::StructEnd, ], ); - - // integer field keys - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::U64(1), // content field - Token::U8(1), - Token::U64(0), // tag field - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); - - // byte-array field keys - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Bytes(b"c"), - Token::U8(1), - Token::Bytes(b"t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); } #[test] @@ -529,31 +491,6 @@ fn struct_() { Token::StructEnd, ], ); - - // byte-array field keys - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Bytes(b"t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::Bytes(b"c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::StructEnd, - ], - ); } #[test] From b0d651be402838a7640c8f1751f5553af456730a Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:10:26 +0500 Subject: [PATCH 16/19] Newtype: add tests for deserialization from sequence (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_adjacently_tagged.rs | 158 ++++++++++++------ 1 file changed, 103 insertions(+), 55 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 6c8489eb9..b1437bbe9 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -302,64 +302,112 @@ mod unit { } } -#[test] -fn newtype() { - let value = AdjacentlyTagged::Newtype::(1); +mod newtype { + use super::*; - // newtype with tag first - assert_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::Str("c"), - Token::U8(1), - Token::StructEnd, - ], - ); + #[test] + fn map_tag_content() { + let value = AdjacentlyTagged::Newtype::(1); - // newtype with content first - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::U8(1), - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); + // Map: tag + content + assert_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::Str("c"), + Token::U8(1), + Token::StructEnd, + ], + ); - // optional newtype with no content field - assert_de_tokens( - &AdjacentlyTagged::Newtype::>(None), - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 1, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Newtype", - }, - Token::StructEnd, - ], - ); + // Map: content + tag + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::U8(1), + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + } + + #[test] + fn map_tag_only() { + // optional newtype with no content field + assert_de_tokens( + &AdjacentlyTagged::Newtype::>(None), + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 1, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::StructEnd, + ], + ); + } + + #[test] + fn seq() { + let value = AdjacentlyTagged::Newtype::(1); + + // Seq: tag and content + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Newtype", + }, + Token::U8(1), + Token::SeqEnd, + ], + ); + + // Seq: tag (as string) and content + assert_de_tokens( + &value, + &[ + Token::Seq { len: None }, + Token::Str("Newtype"), // tag + Token::U8(1), // content + Token::SeqEnd, + ], + ); + + // Seq: tag (as borrowed string) and content + assert_de_tokens( + &value, + &[ + Token::Seq { len: None }, + Token::BorrowedStr("Newtype"), // tag + Token::U8(1), // content + Token::SeqEnd, + ], + ); + } } #[test] From a94d8750fb91d9773553b03e544cf98547a9c8bf Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:12:33 +0500 Subject: [PATCH 17/19] Newtype: move up the test with tag only --- .../tests/test_enum_adjacently_tagged.rs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index b1437bbe9..d21ac73c1 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -306,58 +306,58 @@ mod newtype { use super::*; #[test] - fn map_tag_content() { - let value = AdjacentlyTagged::Newtype::(1); - - // Map: tag + content - assert_tokens( - &value, + fn map_tag_only() { + // optional newtype with no content field + assert_de_tokens( + &AdjacentlyTagged::Newtype::>(None), &[ Token::Struct { name: "AdjacentlyTagged", - len: 2, + len: 1, }, Token::Str("t"), Token::UnitVariant { name: "AdjacentlyTagged", variant: "Newtype", }, - Token::Str("c"), - Token::U8(1), Token::StructEnd, ], ); + } - // Map: content + tag - assert_de_tokens( + #[test] + fn map_tag_content() { + let value = AdjacentlyTagged::Newtype::(1); + + // Map: tag + content + assert_tokens( &value, &[ Token::Struct { name: "AdjacentlyTagged", len: 2, }, - Token::Str("c"), - Token::U8(1), Token::Str("t"), Token::UnitVariant { name: "AdjacentlyTagged", variant: "Newtype", }, + Token::Str("c"), + Token::U8(1), Token::StructEnd, ], ); - } - #[test] - fn map_tag_only() { - // optional newtype with no content field + // Map: content + tag assert_de_tokens( - &AdjacentlyTagged::Newtype::>(None), + &value, &[ Token::Struct { name: "AdjacentlyTagged", - len: 1, + len: 2, }, + Token::Str("c"), + Token::U8(1), Token::Str("t"), Token::UnitVariant { name: "AdjacentlyTagged", From c383e4f9535e4ffdbda36d5c5c2a01bc0518237a Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:18:20 +0500 Subject: [PATCH 18/19] Tuple: add tests for deserialization from sequence (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_adjacently_tagged.rs | 116 +++++++++++------- 1 file changed, 71 insertions(+), 45 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index d21ac73c1..5584f662b 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -437,53 +437,79 @@ fn newtype_with_newtype() { ); } -#[test] -fn tuple() { - let value = AdjacentlyTagged::Tuple::(1, 1); +mod tuple { + use super::*; - // tuple with tag first - assert_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Tuple", - }, - Token::Str("c"), - Token::Tuple { len: 2 }, - Token::U8(1), - Token::U8(1), - Token::TupleEnd, - Token::StructEnd, - ], - ); + #[test] + fn map() { + let value = AdjacentlyTagged::Tuple::(1, 1); - // tuple with content first - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Tuple { len: 2 }, - Token::U8(1), - Token::U8(1), - Token::TupleEnd, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Tuple", - }, - Token::StructEnd, - ], - ); + // Map: tag + content + assert_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Tuple", + }, + Token::Str("c"), + Token::Tuple { len: 2 }, + Token::U8(1), + Token::U8(1), + Token::TupleEnd, + Token::StructEnd, + ], + ); + + // Map: content + tag + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Tuple { len: 2 }, + Token::U8(1), + Token::U8(1), + Token::TupleEnd, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Tuple", + }, + Token::StructEnd, + ], + ); + } + + #[test] + fn seq() { + let value = AdjacentlyTagged::Tuple::(1, 1); + + // Seq: tag + content + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Tuple", + }, + Token::Tuple { len: 2 }, + Token::U8(1), + Token::U8(1), + Token::TupleEnd, + Token::SeqEnd, + ], + ); + } } #[test] From 9f72ce695e3d7e58a16d4909217f0f1a8d63373e Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 16 Aug 2024 22:22:26 +0500 Subject: [PATCH 19/19] Struct: add tests for deserialization from sequence (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_adjacently_tagged.rs | 131 +++++++++++------- 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/test_suite/tests/test_enum_adjacently_tagged.rs b/test_suite/tests/test_enum_adjacently_tagged.rs index 5584f662b..0bcdbc39e 100644 --- a/test_suite/tests/test_enum_adjacently_tagged.rs +++ b/test_suite/tests/test_enum_adjacently_tagged.rs @@ -512,59 +512,88 @@ mod tuple { } } -#[test] -fn struct_() { - let value = AdjacentlyTagged::Struct:: { f: 1 }; +mod struct_ { + use super::*; - // struct with tag first - assert_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::Str("c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::StructEnd, - ], - ); + #[test] + fn map() { + let value = AdjacentlyTagged::Struct:: { f: 1 }; - // struct with content first - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "AdjacentlyTagged", - len: 2, - }, - Token::Str("c"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::Str("t"), - Token::UnitVariant { - name: "AdjacentlyTagged", - variant: "Struct", - }, - Token::StructEnd, - ], - ); + // Map: tag + content + assert_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Struct", + }, + Token::Str("c"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::StructEnd, + ], + ); + + // Map: content + tag + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "AdjacentlyTagged", + len: 2, + }, + Token::Str("c"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::Str("t"), + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Struct", + }, + Token::StructEnd, + ], + ); + } + + #[test] + fn seq() { + let value = AdjacentlyTagged::Struct:: { f: 1 }; + + // Seq: tag + content + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::UnitVariant { + name: "AdjacentlyTagged", + variant: "Struct", + }, + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::SeqEnd, + ], + ); + } } #[test]