Merge pull request #2788 from Mingun/internally-tagged-enum-tests

Consolidate and add new tests of internally tagged enums
This commit is contained in:
David Tolnay 2024-08-15 14:42:28 -07:00 committed by GitHub
commit 1a9ffdbd0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 1478 additions and 756 deletions

View File

@ -1607,58 +1607,6 @@ fn test_collect_other() {
); );
} }
#[test]
fn test_internally_tagged_enum_with_skipped_conflict() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
enum Data {
A,
#[serde(skip)]
#[allow(dead_code)]
B {
t: String,
},
C {
#[serde(default, skip)]
t: String,
},
}
let data = Data::C { t: String::new() };
assert_tokens(
&data,
&[
Token::Struct {
name: "Data",
len: 1,
},
Token::Str("t"),
Token::Str("C"),
Token::StructEnd,
],
);
}
#[test]
fn test_internally_tagged_enum_new_type_with_unit() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
enum Data {
A(()),
}
assert_tokens(
&Data::A(()),
&[
Token::Map { len: Some(1) },
Token::Str("t"),
Token::Str("A"),
Token::MapEnd,
],
);
}
#[test] #[test]
fn test_adjacently_tagged_enum_bytes() { fn test_adjacently_tagged_enum_bytes() {
#[derive(Serialize, Deserialize, PartialEq, Debug)] #[derive(Serialize, Deserialize, PartialEq, Debug)]
@ -1968,29 +1916,6 @@ fn test_transparent_tuple_struct() {
assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]); assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]);
} }
#[test]
fn test_internally_tagged_unit_enum_with_unknown_fields() {
#[derive(Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
enum Data {
A,
}
let data = Data::A;
assert_de_tokens(
&data,
&[
Token::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::Str("b"),
Token::I32(0),
Token::MapEnd,
],
);
}
#[test] #[test]
fn test_expecting_message() { fn test_expecting_message() {
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
@ -2055,27 +1980,6 @@ fn test_expecting_message_externally_tagged_enum() {
); );
} }
#[test]
fn test_expecting_message_internally_tagged_enum() {
#[derive(Deserialize)]
#[serde(tag = "tag")]
#[serde(expecting = "something strange...")]
enum Enum {
InternallyTagged,
}
assert_de_tokens_error::<Enum>(
&[Token::Str("InternallyTagged")],
r#"invalid type: string "InternallyTagged", expected something strange..."#,
);
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
assert_de_tokens_error::<Enum>(
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
"invalid type: unit value, expected variant identifier",
);
}
#[test] #[test]
fn test_expecting_message_adjacently_tagged_enum() { fn test_expecting_message_adjacently_tagged_enum() {
#[derive(Deserialize)] #[derive(Deserialize)]
@ -3123,43 +3027,6 @@ mod flatten {
mod internally_tagged { mod internally_tagged {
use super::*; use super::*;
#[test]
fn straightforward() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
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::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::Str("a"),
Token::I32(0),
Token::Str("b"),
Token::I32(0),
Token::MapEnd,
],
);
}
#[test] #[test]
fn structs() { fn structs() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]

File diff suppressed because it is too large Load Diff

View File

@ -679,485 +679,6 @@ fn test_untagged_enum() {
); );
} }
#[test]
fn test_internally_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Newtype(BTreeMap<String, String>);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Struct {
f: u8,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
enum InternallyTagged {
A { a: u8 },
B,
C(BTreeMap<String, String>),
D(Newtype),
E(Struct),
}
assert_tokens(
&InternallyTagged::A { a: 1 },
&[
Token::Struct {
name: "InternallyTagged",
len: 2,
},
Token::Str("type"),
Token::Str("A"),
Token::Str("a"),
Token::U8(1),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::A { a: 1 },
&[
Token::Seq { len: Some(2) },
Token::Str("A"),
Token::U8(1),
Token::SeqEnd,
],
);
assert_tokens(
&InternallyTagged::B,
&[
Token::Struct {
name: "InternallyTagged",
len: 1,
},
Token::Str("type"),
Token::Str("B"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::B,
&[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd],
);
assert_tokens(
&InternallyTagged::C(BTreeMap::new()),
&[
Token::Map { len: Some(1) },
Token::Str("type"),
Token::Str("C"),
Token::MapEnd,
],
);
assert_de_tokens_error::<InternallyTagged>(
&[
Token::Seq { len: Some(2) },
Token::Str("C"),
Token::Map { len: Some(0) },
Token::MapEnd,
Token::SeqEnd,
],
"invalid type: sequence, expected a map",
);
assert_tokens(
&InternallyTagged::D(Newtype(BTreeMap::new())),
&[
Token::Map { len: Some(1) },
Token::Str("type"),
Token::Str("D"),
Token::MapEnd,
],
);
assert_tokens(
&InternallyTagged::E(Struct { f: 6 }),
&[
Token::Struct {
name: "Struct",
len: 2,
},
Token::Str("type"),
Token::Str("E"),
Token::Str("f"),
Token::U8(6),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::E(Struct { f: 6 }),
&[
Token::Seq { len: Some(2) },
Token::Str("E"),
Token::U8(6),
Token::SeqEnd,
],
);
assert_de_tokens_error::<InternallyTagged>(
&[Token::Map { len: Some(0) }, Token::MapEnd],
"missing field `type`",
);
assert_de_tokens_error::<InternallyTagged>(
&[
Token::Map { len: Some(1) },
Token::Str("type"),
Token::Str("Z"),
Token::MapEnd,
],
"unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`",
);
}
#[test]
fn test_internally_tagged_enum_with_untagged_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind")]
enum InternallyTagged {
Tagged {
a: u8,
},
#[serde(untagged)]
Untagged {
kind: String,
b: u8,
},
}
assert_de_tokens(
&InternallyTagged::Tagged { a: 1 },
&[
Token::Map { len: Some(2) },
Token::Str("kind"),
Token::Str("Tagged"),
Token::Str("a"),
Token::U8(1),
Token::MapEnd,
],
);
assert_tokens(
&InternallyTagged::Tagged { a: 1 },
&[
Token::Struct {
name: "InternallyTagged",
len: 2,
},
Token::Str("kind"),
Token::Str("Tagged"),
Token::Str("a"),
Token::U8(1),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Untagged {
kind: "Foo".to_owned(),
b: 2,
},
&[
Token::Map { len: Some(2) },
Token::Str("kind"),
Token::Str("Foo"),
Token::Str("b"),
Token::U8(2),
Token::MapEnd,
],
);
assert_tokens(
&InternallyTagged::Untagged {
kind: "Foo".to_owned(),
b: 2,
},
&[
Token::Struct {
name: "InternallyTagged",
len: 2,
},
Token::Str("kind"),
Token::Str("Foo"),
Token::Str("b"),
Token::U8(2),
Token::StructEnd,
],
);
assert_tokens(
&InternallyTagged::Untagged {
kind: "Tagged".to_owned(),
b: 2,
},
&[
Token::Struct {
name: "InternallyTagged",
len: 2,
},
Token::Str("kind"),
Token::Str("Tagged"),
Token::Str("b"),
Token::U8(2),
Token::StructEnd,
],
);
}
#[test]
fn test_internally_tagged_bytes() {
#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "type")]
enum InternallyTagged {
String {
string: String,
},
Bytes {
#[serde(with = "bytes")]
bytes: Vec<u8>,
},
}
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Seq { len: Some(1) },
Token::U8(0),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn test_internally_tagged_struct_variant_containing_unit_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum Level {
Info,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "action")]
pub enum Message {
Log { level: Level },
}
assert_de_tokens(
&Level::Info,
&[
Token::Enum { name: "Level" },
Token::BorrowedStr("Info"),
Token::Unit,
],
);
assert_de_tokens(
&Message::Log { level: Level::Info },
&[
Token::Struct {
name: "Message",
len: 2,
},
Token::Str("action"),
Token::Str("Log"),
Token::Str("level"),
Token::Enum { name: "Level" },
Token::BorrowedStr("Info"),
Token::Unit,
Token::StructEnd,
],
);
assert_de_tokens(
&Message::Log { level: Level::Info },
&[
Token::Map { len: Some(2) },
Token::Str("action"),
Token::Str("Log"),
Token::Str("level"),
Token::Enum { name: "Level" },
Token::BorrowedStr("Info"),
Token::Unit,
Token::MapEnd,
],
);
assert_de_tokens(
&Message::Log { level: Level::Info },
&[
Token::Seq { len: Some(2) },
Token::Str("Log"),
Token::Enum { name: "Level" },
Token::BorrowedStr("Info"),
Token::Unit,
Token::SeqEnd,
],
);
}
#[test]
fn test_internally_tagged_borrow() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Input<'a> {
Package { name: &'a str },
}
assert_tokens(
&Input::Package { name: "borrowed" },
&[
Token::Struct {
name: "Input",
len: 2,
},
Token::BorrowedStr("type"),
Token::BorrowedStr("Package"),
Token::BorrowedStr("name"),
Token::BorrowedStr("borrowed"),
Token::StructEnd,
],
);
}
#[test] #[test]
fn test_adjacently_tagged_enum() { fn test_adjacently_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
@ -1552,106 +1073,6 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
); );
} }
#[test]
fn test_enum_in_internally_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Outer {
Inner(Inner),
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Inner {
Unit,
Newtype(u8),
Tuple(u8, u8),
Struct { f: u8 },
}
assert_tokens(
&Outer::Inner(Inner::Unit),
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Unit"),
Token::Unit,
Token::MapEnd,
],
);
assert_tokens(
&Outer::Inner(Inner::Newtype(1)),
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Newtype"),
Token::U8(1),
Token::MapEnd,
],
);
// Reaches crate::private::de::content::VariantDeserializer::tuple_variant
// Content::Seq case
// via ContentDeserializer::deserialize_enum
assert_tokens(
&Outer::Inner(Inner::Tuple(1, 1)),
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Tuple"),
Token::TupleStruct {
name: "Tuple",
len: 2,
},
Token::U8(1),
Token::U8(1),
Token::TupleStructEnd,
Token::MapEnd,
],
);
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
// Content::Map case
// via ContentDeserializer::deserialize_enum
assert_tokens(
&Outer::Inner(Inner::Struct { f: 1 }),
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Struct"),
Token::Struct {
name: "Struct",
len: 1,
},
Token::Str("f"),
Token::U8(1),
Token::StructEnd,
Token::MapEnd,
],
);
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
// Content::Seq case
// via ContentDeserializer::deserialize_enum
assert_de_tokens(
&Outer::Inner(Inner::Struct { f: 1 }),
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Struct"),
Token::Seq { len: Some(1) },
Token::U8(1), // f
Token::SeqEnd,
Token::MapEnd,
],
);
}
#[test] #[test]
fn test_internally_tagged_struct() { fn test_internally_tagged_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
@ -2186,50 +1607,6 @@ fn test_untagged_newtype_variant_containing_unit_struct_not_map() {
); );
} }
#[test]
fn test_internally_tagged_newtype_variant_containing_unit_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Info;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "topic")]
enum Message {
Info(Info),
}
assert_tokens(
&Message::Info(Info),
&[
Token::Map { len: Some(1) },
Token::Str("topic"),
Token::Str("Info"),
Token::MapEnd,
],
);
assert_de_tokens(
&Message::Info(Info),
&[
Token::Struct {
name: "Message",
len: 1,
},
Token::Str("topic"),
Token::Str("Info"),
Token::StructEnd,
],
);
assert_de_tokens(
&Message::Info(Info),
&[
Token::Seq { len: Some(1) },
Token::Str("Info"),
Token::SeqEnd,
],
);
}
#[test] #[test]
fn test_packed_struct_can_derive_serialize() { fn test_packed_struct_can_derive_serialize() {
#[derive(Copy, Clone, Serialize)] #[derive(Copy, Clone, Serialize)]