diff options
author | Joey Sacchini <joey@sacchini.net> | 2020-09-29 17:05:58 -0400 |
---|---|---|
committer | Joey Sacchini <joey@sacchini.net> | 2020-09-29 17:05:58 -0400 |
commit | 56181da142f5e95a067feea5c4558fef2a2d49a7 (patch) | |
tree | 08d5bbcaaa13cf915248cf9dba2a0955d4b573cf | |
parent | 2e6119a65f260f460dd67860dd5f5af7286bcb42 (diff) | |
download | mcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.tar.gz mcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.tar.bz2 mcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.zip |
implement automated testing of all data-types
-rw-r--r-- | src/lib.rs | 7 | ||||
-rw-r--r-- | src/nbt.rs | 63 | ||||
-rw-r--r-- | src/protocol.rs | 121 | ||||
-rw-r--r-- | src/status.rs | 21 | ||||
-rw-r--r-- | src/test_macros.rs | 80 | ||||
-rw-r--r-- | src/types.rs | 196 | ||||
-rw-r--r-- | src/v1_15_2.rs | 668 |
7 files changed, 1096 insertions, 60 deletions
@@ -8,6 +8,7 @@ extern crate test; mod serialize; mod deserialize; pub mod utils; +#[macro_export] pub mod protocol; pub mod uuid; pub mod nbt; @@ -16,4 +17,8 @@ pub mod v1_15_2; pub mod status; pub use serialize::*; -pub use deserialize::*;
\ No newline at end of file +pub use deserialize::*; + +#[cfg(test)] +#[macro_export] +mod test_macros;
\ No newline at end of file @@ -1,6 +1,7 @@ use std::fmt; use crate::{DeserializeResult, DeserializeErr, Deserialized}; use crate::utils::{read_short, take, read_int, read_long, read_one_byte, write_long, write_int, write_short}; +use crate::protocol::TestRandom; #[derive(Clone, Debug, PartialEq)] pub struct NamedTag { @@ -21,6 +22,16 @@ impl NamedTag { } } +#[cfg(test)] +impl TestRandom for NamedTag { + fn test_gen_random() -> Self { + Self { + name: String::test_gen_random(), + payload: Tag::test_gen_random(), + } + } +} + impl fmt::Display for NamedTag { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("TAG_{}('{}'): ", self.payload.tag_type_name(), self.name))?; @@ -104,6 +115,50 @@ impl Tag { } } +#[cfg(test)] +impl TestRandom for Tag { + fn test_gen_random() -> Self { + let random_idx = rand::random::<usize>() % 8; + match random_idx { + 0 => Tag::Byte(i8::test_gen_random()), + 1 => Tag::Short(i16::test_gen_random()), + 2 => Tag::Int(i32::test_gen_random()), + 3 => Tag::Long(i64::test_gen_random()), + 4 => Tag::Float(f32::test_gen_random()), + 5 => Tag::Double(f64::test_gen_random()), + 6 => Tag::String(String::test_gen_random()), + 7 => Tag::List({ + let count = rand::random::<usize>() % 256; + let mut out = Vec::with_capacity(count); + let random_idx = rand::random::<usize>() % 6; + for _ in 0..count { + out.push(match random_idx { + 0 => Tag::Byte(i8::test_gen_random()), + 1 => Tag::Short(i16::test_gen_random()), + 2 => Tag::Int(i32::test_gen_random()), + 3 => Tag::Long(i64::test_gen_random()), + 4 => Tag::Float(f32::test_gen_random()), + 5 => Tag::Double(f64::test_gen_random()), + 6 => Tag::String(String::test_gen_random()), + other => panic!("impossible {}", other) + }); + } + + out + }), + 8 => Tag::Compound({ + let count = rand::random::<usize>() % 256; + let mut out = Vec::with_capacity(count); + for _ in 0..count { + out.push(NamedTag::test_gen_random()); + } + out + }), + other => panic!("impossible {}", other), + } + } +} + #[inline] fn write_contents<F>(contents: &Vec<F>) -> String where F: fmt::Display { format!("{} entries\n{{\n{}\n}}", contents.len(), contents.iter() @@ -466,7 +521,7 @@ mod tests { let (unzipped, result) = read_bigtest_with_bytes(); let serialized = result.bytes(); assert_eq!(unzipped, serialized); - let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(serialized.as_slice()).expect("deserialize serialized nbt"); + let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(serialized.as_slice()).expect("deserialize serialized nbt"); assert_eq!(unserialized, result); } @@ -477,7 +532,7 @@ mod tests { )).with_name("test"); let bytes = original.bytes(); - let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array"); + let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array"); assert_eq!(original, unserialized); } @@ -488,7 +543,7 @@ mod tests { )).with_name("test"); let bytes = original.bytes(); - let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array"); + let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array"); assert_eq!(original, unserialized); } @@ -504,7 +559,7 @@ mod tests { fn read_bigtest_with_bytes() -> (Vec<u8>, NamedTag) { let unzipped = read_compressed_file("src/testdata/bigtest.nbt").expect("read nbt data"); - let Deserialized{value: result, data: rest} = NamedTag::root_compound_tag_from_bytes(unzipped.as_slice()).expect("deserialize nbt"); + let Deserialized { value: result, data: rest } = NamedTag::root_compound_tag_from_bytes(unzipped.as_slice()).expect("deserialize nbt"); assert_eq!(rest.len(), 0); (unzipped, result) diff --git a/src/protocol.rs b/src/protocol.rs index 01265df..e768fdb 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -13,6 +13,7 @@ pub struct ProtocolPacketSpec { pub direction: String, pub id: i32, pub name: String, + pub body_struct: String, pub fields: Vec<ProtocolPacketField>, } @@ -35,7 +36,7 @@ pub trait Packet<I: PacketIdentifier>: Serialize { #[derive(Debug)] pub enum PacketErr { UnknownId(i32), - DeserializeFailed(DeserializeErr) + DeserializeFailed(DeserializeErr), } #[derive(Debug, Clone, PartialEq)] @@ -48,6 +49,11 @@ pub trait ProtocolType: Serialize + Deserialize {} impl<T: Serialize + Deserialize> ProtocolType for T {} +#[cfg(test)] +pub trait TestRandom { + fn test_gen_random() -> Self; +} + #[macro_export] macro_rules! as_item { ($i:item) => { $i }; @@ -82,6 +88,13 @@ macro_rules! __protocol_body_def_helper { Deserialized::ok(Self::default(), data) } } + + #[cfg(test)] + impl TestRandom for $bodyt { + fn test_gen_random() -> Self { + Self::default() + } + } }; ($bodyt: ident { $($fname: ident: $ftyp: ty ),+ }) => { $crate::as_item! { @@ -107,6 +120,13 @@ macro_rules! __protocol_body_def_helper { Deserialized::ok(Self{ $($fname),+ }, _rest) } } + + #[cfg(test)] + impl TestRandom for $bodyt { + fn test_gen_random() -> Self { + Self{ $($fname: <$ftyp>::test_gen_random()),+ } + } + } } } @@ -189,6 +209,7 @@ macro_rules! define_protocol { direction: stringify!($direction).to_owned(), id: $id, name: stringify!($nam).to_owned(), + body_struct: stringify!($body).to_owned(), fields: vec!( $(crate::protocol::ProtocolPacketField{ name: stringify!($fnam).to_owned(), @@ -206,6 +227,13 @@ macro_rules! define_protocol { } #[macro_export] +macro_rules! count_num { + () => { 0 }; + ($item: tt) => { 1 }; + ($item: tt, $($rest: tt),+) => { 1 + count_num!($($rest),+) } +} + +#[macro_export] macro_rules! proto_enum_with_type { ($typ: ty, $from_nam: ident, $as_nam: ident, $fmt: literal, $typname: ident, $(($bval: literal, $nam: ident)),*) => { $crate::as_item! { @@ -274,6 +302,20 @@ macro_rules! proto_enum_with_type { (*self).into() } } + + #[cfg(test)] + impl TestRandom for $typname { + fn test_gen_random() -> Self { + let mut idx: usize = (rand::random::<usize>() % (count_num!($($bval),+))) + 1; + $( + idx -= 1; + if idx == 0 { + return $typname::$nam; + } + )+ + panic!("cannot generate random {}", stringify!($typname)); + } + } } } @@ -345,5 +387,80 @@ macro_rules! proto_byte_flag { Ok(u8::mc_deserialize(data)?.map(move |b| $typname(b))) } } + + #[cfg(test)] + impl TestRandom for $typname { + fn test_gen_random() -> Self { + let mut out = <$typname>::default(); + $(paste::paste! { + out.[<set_ $nam>](rand::random::<bool>()); + })+ + out + } + } } -}
\ No newline at end of file +} + +#[macro_export] +macro_rules! counted_array_type { + ($name: ident, $countert: ty, $tousize_fn: ident, $fromusize_fn: ident) => { + #[derive(Debug, Clone, PartialEq)] + pub struct $name<T> where T: Debug + Clone + PartialEq { + pub data: Vec<T> + } + + impl<T> Serialize for $name<T> where T: Serialize + Debug + Clone + PartialEq { + fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { + let count: $countert = $fromusize_fn(self.data.len()); + to.serialize_other(&count)?; + + for entry in &self.data { + to.serialize_other(entry)?; + } + + Ok(()) + } + } + + impl<T> Deserialize for $name<T> where T: Deserialize + Debug + Clone + PartialEq { + fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { + let Deserialized{value: raw_count, mut data} = <$countert>::mc_deserialize(data)?; + let count: usize = $tousize_fn(raw_count); + + let mut out = Vec::with_capacity(count); + for _ in 0..count { + let Deserialized{value: next, data: rest} = T::mc_deserialize(data)?; + data = rest; + out.push(next); + } + + Deserialized::ok(Self { data: out }, data) + } + } + + impl<T> Into<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { + fn into(self) -> Vec<T> { + self.data + } + } + + impl<T> From<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { + fn from(data: Vec<T>) -> Self { + Self { data } + } + } + + #[cfg(test)] + impl<T> TestRandom for $name<T> where T: TestRandom + Debug + Clone + PartialEq { + fn test_gen_random() -> Self { + let elem_count: usize = rand::random::<usize>() % 32; + let mut out = Vec::with_capacity(elem_count); + for _ in 0..elem_count { + out.push(T::test_gen_random()); + } + + Self { data: out } + } + } + } +} diff --git a/src/status.rs b/src/status.rs index b8f9029..7d254aa 100644 --- a/src/status.rs +++ b/src/status.rs @@ -3,6 +3,7 @@ use crate::{SerializeResult, SerializeErr, Serialize as McSerialize, Deserialize use crate::uuid::UUID4; use serde::{Serialize, Serializer, Deserialize, Deserializer}; use std::fmt; +use crate::protocol::TestRandom; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct StatusSpec { @@ -31,6 +32,26 @@ impl McDeserialize for StatusSpec { } } + +#[cfg(test)] +impl TestRandom for StatusSpec { + fn test_gen_random() -> Self { + Self { + version: StatusVersionSpec{ + protocol: rand::random(), + name: String::test_gen_random(), + }, + players: StatusPlayersSpec{ + sample: Vec::default(), + max: rand::random(), + online: rand::random(), + }, + favicon: None, + description: Chat::test_gen_random(), + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct StatusVersionSpec { pub name: String, diff --git a/src/test_macros.rs b/src/test_macros.rs new file mode 100644 index 0000000..cc573a7 --- /dev/null +++ b/src/test_macros.rs @@ -0,0 +1,80 @@ +use crate::{Serializer, SerializeResult}; +#[cfg(test)] +#[macro_export] +macro_rules! packet_test_cases { + ($pnam: ident, $varnam: ident, $bodnam: ident, $testnam: ident, $benchnams: ident, $benchnamd: ident) => { + #[test] + fn $testnam() { + for _ in 0..10 { + let packet = $pnam::$varnam($bodnam::test_gen_random()); + let mut out = BytesSerializer::default(); + packet.mc_serialize(&mut out).expect("serialize succeeds"); + let bytes = out.into_bytes(); + + let raw_packet = RawPacket{ + id: packet.id(), + data: bytes, + }; + + let deserialized = <$pnam>::mc_deserialize(raw_packet).expect("deserialize succeeds"); + assert_eq!(packet, deserialized); + } + } + + #[bench] + fn $benchnams(b: &mut Bencher) { + let packet = $pnam::$varnam($bodnam::test_gen_random()); + let mut serializer = BenchSerializer::default(); + packet.mc_serialize(&mut serializer).expect("serialize succeeds"); + b.bytes = serializer.len() as u64; + serializer.reset(); + + b.iter(|| { + packet.mc_serialize(&mut serializer).expect("serialize succeeds"); + serializer.reset(); + }) + } + + #[bench] + fn $benchnamd(b: &mut Bencher) { + let packet = $pnam::$varnam($bodnam::test_gen_random()); + let mut serializer = BytesSerializer::default(); + packet.mc_serialize(&mut serializer).expect("serialize succeeds"); + + let bytes = serializer.into_bytes(); + b.bytes = bytes.len() as u64; + let raw_packet = RawPacket{ + id: packet.id(), + data: bytes, + }; + b.iter(|| { + $pnam::mc_deserialize(raw_packet.clone()).expect("deserialize succeeds"); + }) + } + } +} + +#[cfg(test)] +#[derive(Clone, Debug, Default, PartialEq)] +pub struct BenchSerializer { + data: Vec<u8> +} + +#[cfg(test)] +impl Serializer for BenchSerializer { + fn serialize_bytes(&mut self, data: &[u8]) -> SerializeResult { + self.data.extend_from_slice(data); + Ok(()) + } +} + +#[cfg(test)] +impl BenchSerializer { + pub fn reset(&mut self) { + self.data.clear(); + } + + pub fn len(&self) -> usize { + self.data.len() + } +}
\ No newline at end of file diff --git a/src/types.rs b/src/types.rs index f62ede9..9d8f595 100644 --- a/src/types.rs +++ b/src/types.rs @@ -4,6 +4,9 @@ use crate::*; use crate::utils::*; use crate::uuid::UUID4; +#[cfg(test)] +use crate::protocol::TestRandom; + // bool impl Serialize for bool { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -23,6 +26,13 @@ impl Deserialize for bool { } } +#[cfg(test)] +impl TestRandom for bool { + fn test_gen_random() -> Self { + rand::random() + } +} + // u8 impl Serialize for u8 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -36,6 +46,13 @@ impl Deserialize for u8 { } } +#[cfg(test)] +impl TestRandom for u8 { + fn test_gen_random() -> Self { + rand::random() + } +} + // i8 impl Serialize for i8 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -49,6 +66,13 @@ impl Deserialize for i8 { } } +#[cfg(test)] +impl TestRandom for i8 { + fn test_gen_random() -> Self { + rand::random() + } +} + // u16 impl Serialize for u16 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -63,6 +87,13 @@ impl Deserialize for u16 { } } +#[cfg(test)] +impl TestRandom for u16 { + fn test_gen_random() -> Self { + rand::random() + } +} + // i16 impl Serialize for i16 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -76,6 +107,13 @@ impl Deserialize for i16 { } } +#[cfg(test)] +impl TestRandom for i16 { + fn test_gen_random() -> Self { + rand::random() + } +} + // int impl Serialize for i32 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -90,6 +128,13 @@ impl Deserialize for i32 { } } +#[cfg(test)] +impl TestRandom for i32 { + fn test_gen_random() -> Self { + rand::random() + } +} + // long impl Serialize for i64 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { @@ -104,6 +149,13 @@ impl Deserialize for i64 { } } +#[cfg(test)] +impl TestRandom for i64 { + fn test_gen_random() -> Self { + rand::random() + } +} + // float impl Serialize for f32 { @@ -120,6 +172,13 @@ impl Deserialize for f32 { } } +#[cfg(test)] +impl TestRandom for f32 { + fn test_gen_random() -> Self { + rand::random() + } +} + // double impl Serialize for f64 { //noinspection ALL @@ -135,6 +194,13 @@ impl Deserialize for f64 { } } +#[cfg(test)] +impl TestRandom for f64 { + fn test_gen_random() -> Self { + rand::random() + } +} + // VAR INT AND VAR LONG const VAR_INT_BYTES: usize = 5; const VAR_LONG_BYTES: usize = 10; @@ -188,6 +254,14 @@ impl std::fmt::Display for VarInt { } } +#[cfg(test)] +impl TestRandom for VarInt { + fn test_gen_random() -> Self { + let out: i32 = rand::random(); + Self(out) + } +} + #[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Default, Hash, Ord, Eq)] pub struct VarLong(pub i64); @@ -204,6 +278,14 @@ impl Deserialize for VarLong { } } +#[cfg(test)] +impl TestRandom for VarLong { + fn test_gen_random() -> Self { + let out: i64 = rand::random(); + Self(out) + } +} + fn serialize_var_num(data: u64, out: &mut [u8]) -> &[u8] { let mut v: u64 = data; let mut byte_idx = 0; @@ -274,6 +356,28 @@ impl Deserialize for String { } } +#[cfg(test)] +impl TestRandom for String { + fn test_gen_random() -> Self { + let raw_len: u8 = rand::random(); + let len = raw_len as usize; + let mut out = String::with_capacity(len); + for _ in 0..len { + let c_idx: u8 = rand::random::<u8>() % 36; + + let c = if c_idx <= 10 { + (48 + c_idx) as char + } else { + ((c_idx - 10) + 65) as char + }; + + out.push(c) + } + + out + } +} + // position #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub struct IntPosition { @@ -335,6 +439,20 @@ impl Deserialize for IntPosition { } } +#[cfg(test)] +impl TestRandom for IntPosition { + fn test_gen_random() -> Self { + let x: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25); + let z: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25); + let y: i16 = ((rand::random::<u16>() % (1 << 12)) as i16) - (1 << 11); + Self{ + x, + y, + z + } + } +} + // angle #[derive(Copy, Clone, PartialEq, Hash, Debug)] pub struct Angle { @@ -355,6 +473,15 @@ impl Deserialize for Angle { } } +#[cfg(test)] +impl TestRandom for Angle { + fn test_gen_random() -> Self { + Self{ + value: rand::random() + } + } +} + // UUID impl Serialize for UUID4 { @@ -388,6 +515,13 @@ impl Deserialize for UUID4 { } } +#[cfg(test)] +impl TestRandom for UUID4 { + fn test_gen_random() -> Self { + UUID4::random() + } +} + // NBT #[derive(Clone, PartialEq, Debug)] @@ -420,6 +554,13 @@ impl Into<nbt::NamedTag> for NamedNbtTag { } } +#[cfg(test)] +impl TestRandom for NamedNbtTag { + fn test_gen_random() -> Self { + Self { root: nbt::NamedTag::test_gen_random() } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct FixedInt { raw: i32 @@ -449,6 +590,13 @@ impl FixedInt { } } +#[cfg(test)] +impl TestRandom for FixedInt { + fn test_gen_random() -> Self { + FixedInt::new(f64::test_gen_random(), 16) + } +} + // chat #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] pub struct Chat { @@ -704,6 +852,19 @@ impl Chat { to.push(formatter) } } + + pub fn from_text(text: &str) -> Chat { + Chat{ + text: text.to_owned(), + bold: None, + italic: None, + underlined: None, + strikethrough: None, + obfuscated: None, + color: None, + extra: None, + } + } } impl Serialize for Chat { @@ -724,6 +885,14 @@ impl Deserialize for Chat { } } +#[cfg(test)] +impl TestRandom for Chat { + fn test_gen_random() -> Self { + let str = String::test_gen_random(); + Chat::from_text(str.as_str()) + } +} + #[derive(Default)] pub struct BytesSerializer { data: Vec<u8> @@ -774,6 +943,18 @@ impl<T> Deserialize for Option<T> where T: Deserialize { } } +#[cfg(test)] +impl<T> TestRandom for Option<T> where T: TestRandom { + fn test_gen_random() -> Self { + let is_present: bool = rand::random(); + if is_present { + Some(T::test_gen_random()) + } else { + None + } + } +} + // SLOT #[derive(Debug, PartialEq, Clone)] pub struct Slot { @@ -813,6 +994,21 @@ impl Deserialize for Slot { } #[cfg(test)] +impl TestRandom for Slot { + fn test_gen_random() -> Self { + let item_id = VarInt::test_gen_random(); + let item_count = i8::test_gen_random() % 65; + let nbt = <Option<nbt::NamedTag>>::test_gen_random(); + + Self{ + item_id, + item_count, + nbt + } + } +} + +#[cfg(test)] mod tests { use super::*; use std::fmt::Debug; diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs index d2ee960..1569d80 100644 --- a/src/v1_15_2.rs +++ b/src/v1_15_2.rs @@ -1,6 +1,9 @@ use crate::{*, uuid::*, types::*}; use std::fmt::Debug; +#[cfg(test)] +use crate::protocol::TestRandom; + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum PacketDirection { ClientBound, @@ -804,56 +807,6 @@ proto_byte_enum!(HandshakeNextState, 0x02 :: Login ); -macro_rules! counted_array_type { - ($name: ident, $countert: ty, $tousize_fn: ident, $fromusize_fn: ident) => { - #[derive(Debug, Clone, PartialEq)] - pub struct $name<T> where T: Debug + Clone + PartialEq { - pub data: Vec<T> - } - - impl<T> Serialize for $name<T> where T: Serialize + Debug + Clone + PartialEq { - fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let count: $countert = $fromusize_fn(self.data.len()); - to.serialize_other(&count)?; - - for entry in &self.data { - to.serialize_other(entry)?; - } - - Ok(()) - } - } - - impl<T> Deserialize for $name<T> where T: Deserialize + Debug + Clone + PartialEq { - fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - let Deserialized{value: raw_count, mut data} = <$countert>::mc_deserialize(data)?; - let count: usize = $tousize_fn(raw_count); - - let mut out = Vec::with_capacity(count); - for _ in 0..count { - let Deserialized{value: next, data: rest} = T::mc_deserialize(data)?; - data = rest; - out.push(next); - } - - Deserialized::ok(Self { data: out }, data) - } - } - - impl<T> Into<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { - fn into(self) -> Vec<T> { - self.data - } - } - - impl<T> From<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { - fn from(data: Vec<T>) -> Self { - Self { data } - } - } - } -} - #[inline] fn varint_to_usize(v: VarInt) -> usize { v.into() @@ -927,6 +880,19 @@ impl From<Vec<u8>> for RemainingBytes { } } +#[cfg(test)] +impl TestRandom for RemainingBytes { + fn test_gen_random() -> Self { + let mut size: usize = rand::random::<usize>() % 256; + let mut out = Vec::with_capacity(size); + for _ in 0..size { + out.push(rand::random()); + } + + Self{ data: out } + } +} + proto_byte_enum!(CardinalDirection, 0x00 :: South, 0x01 :: West, @@ -1052,12 +1018,12 @@ proto_byte_enum!(ChatPosition, #[derive(Copy, Clone, PartialEq, Debug)] pub struct BlockChangeHorizontalPosition { pub rel_x: u8, - pub rel_y: u8, + pub rel_z: u8, } impl Serialize for BlockChangeHorizontalPosition { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - to.serialize_byte((self.rel_x & 0xF) << 4 | (self.rel_y & 0xF)) + to.serialize_byte((self.rel_x & 0xF) << 4 | (self.rel_z & 0xF)) } } @@ -1066,12 +1032,22 @@ impl Deserialize for BlockChangeHorizontalPosition { Ok(u8::mc_deserialize(data)?.map(move |b| { BlockChangeHorizontalPosition { rel_x: (b >> 4) & 0xF, - rel_y: b & 0xF, + rel_z: b & 0xF, } })) } } +#[cfg(test)] +impl TestRandom for BlockChangeHorizontalPosition { + fn test_gen_random() -> Self { + BlockChangeHorizontalPosition{ + rel_x: rand::random(), + rel_z: rand::random(), + } + } +} + __protocol_body_def_helper!(MultiBlockChangeRecord { horizontal_position: BlockChangeHorizontalPosition, y_coordinate: u8, @@ -1126,6 +1102,14 @@ impl Deserialize for BossBarAction { } } +#[cfg(test)] +impl TestRandom for BossBarAction { + fn test_gen_random() -> Self { + // todo + BossBarAction::Remove + } +} + proto_varint_enum!(BossBarColor, 0x00 :: Pink, 0x01 :: Blue, @@ -1322,6 +1306,14 @@ impl Deserialize for GameChangeReason { } } +#[cfg(test)] +impl TestRandom for GameChangeReason { + fn test_gen_random() -> Self { + // todo + GameChangeReason::PufferfishSting + } +} + proto_varint_enum!(MapIconType, 0x00 :: WhiteArrow, 0x01 :: GreenArrow, @@ -1414,6 +1406,13 @@ impl From<Option<MapColumnsSpec>> for MapColumns { } } +#[cfg(test)] +impl TestRandom for MapColumns { + fn test_gen_random() -> Self { + <Option<MapColumnsSpec>>::test_gen_random().into() + } +} + __protocol_body_def_helper!(TradeSpec { input_item_1: Option<Slot>, output_item: Option<Slot>, @@ -1516,6 +1515,13 @@ impl Deserialize for CombatEvent { } } +#[cfg(test)] +impl TestRandom for CombatEvent { + fn test_gen_random() -> Self { + CombatEvent::Enter // todo + } +} + #[derive(Clone, PartialEq, Debug)] pub struct PlayerInfoAction<A: Clone + PartialEq + Debug> { pub uuid: UUID4, @@ -1637,6 +1643,15 @@ impl Deserialize for PlayerInfoActionList { } } +#[cfg(test)] +impl TestRandom for PlayerInfoActionList { + fn test_gen_random() -> Self { + PlayerInfoActionList::Remove({ + vec!(UUID4::random()) + }) + } +} + fn serialize_vec_directly<I: Serialize, S: Serializer>(items: &Vec<I>, to: &mut S) -> SerializeResult { for item in items { to.serialize_other(item)?; @@ -1801,6 +1816,15 @@ impl Deserialize for WorldBorderAction { } } +#[cfg(test)] +impl TestRandom for WorldBorderAction { + fn test_gen_random() -> Self { + WorldBorderAction::SetSize(WorldBorderSetSizeSpec{ + diameter: f64::test_gen_random() + }) + } +} + #[derive(Clone, Copy, PartialEq, Debug, Eq)] pub enum ScoreboardPosition { List, @@ -1847,6 +1871,13 @@ impl Deserialize for ScoreboardPosition { } } +#[cfg(test)] +impl TestRandom for ScoreboardPosition { + fn test_gen_random() -> Self { + ScoreboardPosition::Sidebar + } +} + proto_varint_enum!(EquipmentSlot, 0x00 :: MainHand, 0x01 :: OffHand, @@ -1911,6 +1942,13 @@ impl Deserialize for ScoreboardObjectiveAction { } } +#[cfg(test)] +impl TestRandom for ScoreboardObjectiveAction { + fn test_gen_random() -> Self { + ScoreboardObjectiveAction::Remove + } +} + __protocol_body_def_helper!(EntityPropertySpec { key: String, value: f64, @@ -2028,6 +2066,13 @@ impl Deserialize for InteractKind { } } +#[cfg(test)] +impl TestRandom for InteractKind { + fn test_gen_random() -> Self { + InteractKind::Attack + } +} + proto_byte_flag!(ClientPlayerAbilities, 0x01 :: creative, 0x02 :: flying, @@ -2241,6 +2286,16 @@ impl Deserialize for RecipeSpec { } } +#[cfg(test)] +impl TestRandom for RecipeSpec { + fn test_gen_random() -> Self { + RecipeSpec { + recipe: Recipe::CraftingRepairItem, + id: String::test_gen_random(), + } + } +} + __protocol_body_def_helper!(RecipeIngredient { items: VarIntCountedArray<Option<Slot>> }); @@ -2292,6 +2347,19 @@ impl Deserialize for RecipeCraftingShapedSpec { } } +#[cfg(test)] +impl TestRandom for RecipeCraftingShapedSpec { + fn test_gen_random() -> Self { + RecipeCraftingShapedSpec { + width: VarInt::test_gen_random(), + height: VarInt::test_gen_random(), + group: String::test_gen_random(), + ingredients: vec!(RecipeIngredient::test_gen_random()), + result: <Option<Slot>>::test_gen_random(), + } + } +} + __protocol_body_def_helper!(RecipeSmeltingSpec { group: String, ingredient: RecipeIngredient, @@ -2388,4 +2456,498 @@ impl Deserialize for ChunkData { block_entities, }, data) } +} + +#[cfg(test)] +impl TestRandom for ChunkData { + fn test_gen_random() -> Self { + ChunkData{ + chunk_x: rand::random(), + chunk_z: rand::random(), + primary_bit_mask: VarInt::test_gen_random(), + heightmaps: NamedNbtTag::test_gen_random(), + biomes: None, + data: <VarIntCountedArray<u8>>::test_gen_random(), + block_entities: vec![] + } + } +} + +#[cfg(test)] +pub mod tests { + + use super::*; + use crate::packet_test_cases; + use crate::protocol::{RawPacket, Packet}; + use crate::types::BytesSerializer; + use crate::test_macros::BenchSerializer; + use test::Bencher; + + packet_test_cases!(Packet578, Handshake, HandshakeSpec, + test_handshake, bench_write_handshake, bench_read_handshake); + + packet_test_cases!(Packet578, StatusRequest, StatusRequestSpec, + test_status_request, bench_write_status_request, bench_read_status_request); + + packet_test_cases!(Packet578, StatusPing, StatusPingSpec, + test_status_ping, bench_write_status_ping, bench_read_status_ping); + + packet_test_cases!(Packet578, StatusResponse, StatusResponseSpec, + test_status_response, bench_write_status_response, bench_read_status_response); + + packet_test_cases!(Packet578, StatusPong, StatusPongSpec, + test_status_pong, bench_write_status_pong, bench_read_status_pong); + + packet_test_cases!(Packet578, LoginDisconnect, LoginDisconnectSpec, + test_login_disconnect, bench_write_login_disconnect, bench_read_login_disconnect); + + packet_test_cases!(Packet578, LoginEncryptionRequest, LoginEncryptionRequestSpec, + test_login_encryption_request, bench_write_login_encryption_request, bench_read_login_encryption_request); + + packet_test_cases!(Packet578, LoginSuccess, LoginSuccessSpec, + test_login_success, bench_write_login_success, bench_read_login_success); + + packet_test_cases!(Packet578, LoginSetCompression, LoginSetCompressionSpec, + test_login_set_compression, bench_write_login_set_compression, bench_read_login_set_compression); + + packet_test_cases!(Packet578, LoginPluginRequest, LoginPluginRequestSpec, + test_login_plugin_request, bench_write_login_plugin_request, bench_read_login_plugin_request); + + packet_test_cases!(Packet578, LoginStart, LoginStartSpec, + test_login_start, bench_write_login_start, bench_read_login_start); + + packet_test_cases!(Packet578, LoginEncryptionResponse, LoginEncryptionResponseSpec, + test_login_encryption_response, bench_write_login_encryption_response, bench_read_login_encryption_response); + + packet_test_cases!(Packet578, LoginPluginResponse, LoginPluginResponseSpec, + test_login_plugin_response, bench_write_login_plugin_response, bench_read_login_plugin_response); + + packet_test_cases!(Packet578, PlaySpawnEntity, PlaySpawnEntitySpec, + test_play_spawn_entity, bench_write_play_spawn_entity, bench_read_play_spawn_entity); + + packet_test_cases!(Packet578, PlaySpawnExperienceOrb, PlaySpawnExperienceOrbSpec, + test_play_spawn_experience_orb, bench_write_play_spawn_experience_orb, bench_read_play_spawn_experience_orb); + + packet_test_cases!(Packet578, PlaySpawnWeatherEntity, PlaySpawnWeatherEntitySpec, + test_play_spawn_weather_entity, bench_write_play_spawn_weather_entity, bench_read_play_spawn_weather_entity); + + packet_test_cases!(Packet578, PlaySpawnLivingEntity, PlaySpawnLivingEntitySpec, + test_play_spawn_living_entity, bench_write_play_spawn_living_entity, bench_read_play_spawn_living_entity); + + packet_test_cases!(Packet578, PlaySpawnPainting, PlaySpawnPaintingSpec, + test_play_spawn_painting, bench_write_play_spawn_painting, bench_read_play_spawn_painting); + + packet_test_cases!(Packet578, PlaySpawnPlayer, PlaySpawnPlayerSpec, + test_play_spawn_player, bench_write_play_spawn_player, bench_read_play_spawn_player); + + packet_test_cases!(Packet578, PlayEntityAnimation, PlayEntityAnimationSpec, + test_play_entity_animation, bench_write_play_entity_animation, bench_read_play_entity_animation); + + packet_test_cases!(Packet578, PlayStatistics, PlayStatisticsSpec, + test_play_statistics, bench_write_play_statistics, bench_read_play_statistics); + + packet_test_cases!(Packet578, PlayAcknowledgePlayerDigging, PlayAcknowledgePlayerDiggingSpec, + test_play_acknowledge_player_digging, bench_write_play_acknowledge_player_digging, bench_read_play_acknowledge_player_digging); + + packet_test_cases!(Packet578, PlayBlockBreakAnimation, PlayBlockBreakAnimationSpec, + test_play_block_break_animation, bench_write_play_block_break_animation, bench_read_play_block_break_animation); + + packet_test_cases!(Packet578, PlayBlockEntityData, PlayBlockEntityDataSpec, + test_play_block_entity_data, bench_write_play_block_entity_data, bench_read_play_block_entity_data); + + packet_test_cases!(Packet578, PlayBlockAction, PlayBlockActionSpec, + test_play_block_action, bench_write_play_block_action, bench_read_play_block_action); + + packet_test_cases!(Packet578, PlayBlockChange, PlayBlockChangeSpec, + test_play_block_change, bench_write_play_block_change, bench_read_play_block_change); + + packet_test_cases!(Packet578, PlayBossBar, PlayBossBarSpec, + test_play_boss_bar, bench_write_play_boss_bar, bench_read_play_boss_bar); + + packet_test_cases!(Packet578, PlayServerDifficulty, PlayServerDifficultySpec, + test_play_server_difficulty, bench_write_play_server_difficulty, bench_read_play_server_difficulty); + + packet_test_cases!(Packet578, PlayServerChatMessage, PlayServerChatMessageSpec, + test_play_server_chat_message, bench_write_play_server_chat_message, bench_read_play_server_chat_message); + + packet_test_cases!(Packet578, PlayMultiBlockChange, PlayMultiBlockChangeSpec, + test_play_multi_block_change, bench_write_play_multi_block_change, bench_read_play_multi_block_change); + + packet_test_cases!(Packet578, PlayTabComplete, PlayTabCompleteSpec, + test_play_tab_complete, bench_write_play_tab_complete, bench_read_play_tab_complete); + + packet_test_cases!(Packet578, PlayDeclareCommands, PlayDeclareCommandsSpec, + test_play_declare_commands, bench_write_play_declare_commands, bench_read_play_declare_commands); + + packet_test_cases!(Packet578, PlayServerWindowConfirmation, PlayServerWindowConfirmationSpec, + test_play_server_window_confirmation, bench_write_play_server_window_confirmation, bench_read_play_server_window_confirmation); + + packet_test_cases!(Packet578, PlayServerCloseWindow, PlayServerCloseWindowSpec, + test_play_server_close_window, bench_write_play_server_close_window, bench_read_play_server_close_window); + + packet_test_cases!(Packet578, PlayWindowItems, PlayWindowItemsSpec, + test_play_window_items, bench_write_play_window_items, bench_read_play_window_items); + + packet_test_cases!(Packet578, PlayWindowProperty, PlayWindowPropertySpec, + test_play_window_property, bench_write_play_window_property, bench_read_play_window_property); + + packet_test_cases!(Packet578, PlaySetSlot, PlaySetSlotSpec, + test_play_set_slot, bench_write_play_set_slot, bench_read_play_set_slot); + + packet_test_cases!(Packet578, PlaySetCooldown, PlaySetCooldownSpec, + test_play_set_cooldown, bench_write_play_set_cooldown, bench_read_play_set_cooldown); + + packet_test_cases!(Packet578, PlayServerPluginMessage, PlayServerPluginMessageSpec, + test_play_server_plugin_message, bench_write_play_server_plugin_message, bench_read_play_server_plugin_message); + + packet_test_cases!(Packet578, PlayNamedSoundEffect, PlayNamedSoundEffectSpec, + test_play_named_sound_effect, bench_write_play_named_sound_effect, bench_read_play_named_sound_effect); + + packet_test_cases!(Packet578, PlayDisconnect, PlayDisconnectSpec, + test_play_disconnect, bench_write_play_disconnect, bench_read_play_disconnect); + + packet_test_cases!(Packet578, PlayEntityStatus, PlayEntityStatusSpec, + test_play_entity_status, bench_write_play_entity_status, bench_read_play_entity_status); + + packet_test_cases!(Packet578, PlayExposion, PlayExposionSpec, + test_play_exposion, bench_write_play_exposion, bench_read_play_exposion); + + packet_test_cases!(Packet578, PlayUnloadChunk, PlayUnloadChunkSpec, + test_play_unload_chunk, bench_write_play_unload_chunk, bench_read_play_unload_chunk); + + packet_test_cases!(Packet578, PlayChangeGameState, PlayChangeGameStateSpec, + test_play_change_game_state, bench_write_play_change_game_state, bench_read_play_change_game_state); + + packet_test_cases!(Packet578, PlayOpenHorseWindow, PlayOpenHorseWindowSpec, + test_play_open_horse_window, bench_write_play_open_horse_window, bench_read_play_open_horse_window); + + packet_test_cases!(Packet578, PlayServerKeepAlive, PlayServerKeepAliveSpec, + test_play_server_keep_alive, bench_write_play_server_keep_alive, bench_read_play_server_keep_alive); + + packet_test_cases!(Packet578, PlayChunkData, PlayChunkDataWrapper, + test_play_chunk_data, bench_write_play_chunk_data, bench_read_play_chunk_data); + + packet_test_cases!(Packet578, PlayEffect, PlayEffectSpec, + test_play_effect, bench_write_play_effect, bench_read_play_effect); + + packet_test_cases!(Packet578, PlayParticle, PlayParticleSpec, + test_play_particle, bench_write_play_particle, bench_read_play_particle); + + packet_test_cases!(Packet578, PlayUpdateLight, PlayUpdateLoightSpec, + test_play_update_light, bench_write_play_update_light, bench_read_play_update_light); + + packet_test_cases!(Packet578, PlayJoinGame, PlayJoinGameSpec, + test_play_join_game, bench_write_play_join_game, bench_read_play_join_game); + + packet_test_cases!(Packet578, PlayMapData, PlayMapDataSpec, + test_play_map_data, bench_write_play_map_data, bench_read_play_map_data); + + packet_test_cases!(Packet578, PlayTradeList, PlayTradeListSpec, + test_play_trade_list, bench_write_play_trade_list, bench_read_play_trade_list); + + packet_test_cases!(Packet578, PlayEntityPosition, PlayEntityPositionSpec, + test_play_entity_position, bench_write_play_entity_position, bench_read_play_entity_position); + + packet_test_cases!(Packet578, PlayEntityPositionAndRotation, PlayEntityPositionAndRotationSpec, + test_play_entity_position_and_rotation, bench_write_play_entity_position_and_rotation, bench_read_play_entity_position_and_rotation); + + packet_test_cases!(Packet578, PlayEntityRotation, PlayEntityRotationSpec, + test_play_entity_rotation, bench_write_play_entity_rotation, bench_read_play_entity_rotation); + + packet_test_cases!(Packet578, PlayEntityMovement, PlayEntityMovementSpec, + test_play_entity_movement, bench_write_play_entity_movement, bench_read_play_entity_movement); + + packet_test_cases!(Packet578, PlayServerVehicleMove, PlayEntityVehicleMoveSpec, + test_play_server_vehicle_move, bench_write_play_server_vehicle_move, bench_read_play_server_vehicle_move); + + packet_test_cases!(Packet578, PlayOpenBook, PlayOpenBookSpec, + test_play_open_book, bench_write_play_open_book, bench_read_play_open_book); + + packet_test_cases!(Packet578, PlayOpenWindow, PlayOpenWindowSpec, + test_play_open_window, bench_write_play_open_window, bench_read_play_open_window); + + packet_test_cases!(Packet578, PlayOpenSignEditor, PlayOpenSignEditorSpec, + test_play_open_sign_editor, bench_write_play_open_sign_editor, bench_read_play_open_sign_editor); + + packet_test_cases!(Packet578, PlayCraftRecipeResponse, PlayCraftRecipeResponseSpec, + test_play_craft_recipe_response, bench_write_play_craft_recipe_response, bench_read_play_craft_recipe_response); + + packet_test_cases!(Packet578, PlayServerPlayerAbilities, PlayServerPlayerAbilitiesSpec, + test_play_server_player_abilities, bench_write_play_server_player_abilities, bench_read_play_server_player_abilities); + + packet_test_cases!(Packet578, PlayCombatEvent, PlayCombatEventSpec, + test_play_combat_event, bench_write_play_combat_event, bench_read_play_combat_event); + + packet_test_cases!(Packet578, PlayPlayerInfo, PlayPlayerInfoSpec, + test_play_player_info, bench_write_play_player_info, bench_read_play_player_info); + + packet_test_cases!(Packet578, PlayFacePlayer, PlayFacePlayerSpec, + test_play_face_player, bench_write_play_face_player, bench_read_play_face_player); + + packet_test_cases!(Packet578, PlayServerPlayerPositionAndLook, PlayServerPlayerPositionAndLookSpec, + test_play_server_player_position_and_look, bench_write_play_server_player_position_and_look, bench_read_play_server_player_position_and_look); + + packet_test_cases!(Packet578, PlayUnlockRecipes, PlayUnlockRecipesSpec, + test_play_unlock_recipes, bench_write_play_unlock_recipes, bench_read_play_unlock_recipes); + + packet_test_cases!(Packet578, PlayDestroyEntities, PlayDestroyEntitiesSpec, + test_play_destroy_entities, bench_write_play_destroy_entities, bench_read_play_destroy_entities); + + packet_test_cases!(Packet578, PlayRemoveEntityEffect, PlayRemoveEntityEffectSpec, + test_play_remove_entity_effect, bench_write_play_remove_entity_effect, bench_read_play_remove_entity_effect); + + packet_test_cases!(Packet578, PlayResourcePackSend, PlayResourcePackSendSpec, + test_play_resource_pack_send, bench_write_play_resource_pack_send, bench_read_play_resource_pack_send); + + packet_test_cases!(Packet578, PlayRespawn, PlayRespawnSpec, + test_play_respawn, bench_write_play_respawn, bench_read_play_respawn); + + packet_test_cases!(Packet578, PlayEntityHeadLook, PlayEntityHeadLookSpec, + test_play_entity_head_look, bench_write_play_entity_head_look, bench_read_play_entity_head_look); + + packet_test_cases!(Packet578, PlaySelectAdvancementTab, PlaySelectAdvancementTabSpec, + test_play_select_advancement_tab, bench_write_play_select_advancement_tab, bench_read_play_select_advancement_tab); + + packet_test_cases!(Packet578, PlayWorldBorder, PlayWorldBorderSpec, + test_play_world_border, bench_write_play_world_border, bench_read_play_world_border); + + packet_test_cases!(Packet578, PlayCamera, PlayCameraSpec, + test_play_camera, bench_write_play_camera, bench_read_play_camera); + + packet_test_cases!(Packet578, PlayServerHeldItemChange, PlayServerHeldItemChangeSpec, + test_play_server_held_item_change, bench_write_play_server_held_item_change, bench_read_play_server_held_item_change); + + packet_test_cases!(Packet578, PlayUpdateViewPosition, PlayUpdateViewPositionSpec, + test_play_update_view_position, bench_write_play_update_view_position, bench_read_play_update_view_position); + + packet_test_cases!(Packet578, PlayUpdateViewDistance, PlayUpdateViewDistanceSpec, + test_play_update_view_distance, bench_write_play_update_view_distance, bench_read_play_update_view_distance); + + packet_test_cases!(Packet578, PlayDisplayScoreboard, PlayDisplayScoreboardSpec, + test_play_display_scoreboard, bench_write_play_display_scoreboard, bench_read_play_display_scoreboard); + + packet_test_cases!(Packet578, PlayEntityMetadata, PlayEntityMetadataSpec, + test_play_entity_metadata, bench_write_play_entity_metadata, bench_read_play_entity_metadata); + + packet_test_cases!(Packet578, PlayAttachEntity, PlayAttachEntitySpec, + test_play_attach_entity, bench_write_play_attach_entity, bench_read_play_attach_entity); + + packet_test_cases!(Packet578, PlayEntityVelocity, PlayEntityVelocitySpec, + test_play_entity_velocity, bench_write_play_entity_velocity, bench_read_play_entity_velocity); + + packet_test_cases!(Packet578, PlayEntityEquipment, PlayEntityEquiptmentSpec, + test_play_entity_equipment, bench_write_play_entity_equipment, bench_read_play_entity_equipment); + + packet_test_cases!(Packet578, PlaySetExperience, PlaySetExperienceSpec, + test_play_set_experience, bench_write_play_set_experience, bench_read_play_set_experience); + + packet_test_cases!(Packet578, PlayUpdatehealth, PlayUpdateHealthSpec, + test_play_updatehealth, bench_write_play_updatehealth, bench_read_play_updatehealth); + + packet_test_cases!(Packet578, PlayScoreboardObjective, PlayScoreboardObjectiveSpec, + test_play_scoreboard_objective, bench_write_play_scoreboard_objective, bench_read_play_scoreboard_objective); + + packet_test_cases!(Packet578, PlaySetPassengers, PlaySetPassengersSpec, + test_play_set_passengers, bench_write_play_set_passengers, bench_read_play_set_passengers); + + packet_test_cases!(Packet578, PlaySpawnPosition, PlaySpawnPositionSpec, + test_play_spawn_position, bench_write_play_spawn_position, bench_read_play_spawn_position); + + packet_test_cases!(Packet578, PlayTimeUpdate, PlayTimeUpdateSpec, + test_play_time_update, bench_write_play_time_update, bench_read_play_time_update); + + packet_test_cases!(Packet578, PlayEntitySoundEffect, PlayEntitySoundEffectSpec, + test_play_entity_sound_effect, bench_write_play_entity_sound_effect, bench_read_play_entity_sound_effect); + + packet_test_cases!(Packet578, PlaySoundEffect, PlaySoundEffectSpec, + test_play_sound_effect, bench_write_play_sound_effect, bench_read_play_sound_effect); + + packet_test_cases!(Packet578, PlayerPlayerListHeaderAndFooter, PlayPlayerListHeaderAndFooterSpec, + test_player_player_list_header_and_footer, bench_write_player_player_list_header_and_footer, bench_read_player_player_list_header_and_footer); + + packet_test_cases!(Packet578, PlayNbtQueryResponse, PlayNbtQueryResponseSpec, + test_play_nbt_query_response, bench_write_play_nbt_query_response, bench_read_play_nbt_query_response); + + packet_test_cases!(Packet578, PlayCollectItem, PlayCollectItemSpec, + test_play_collect_item, bench_write_play_collect_item, bench_read_play_collect_item); + + packet_test_cases!(Packet578, PlayEntityTeleport, PlayEntityTeleportSpec, + test_play_entity_teleport, bench_write_play_entity_teleport, bench_read_play_entity_teleport); + + packet_test_cases!(Packet578, PlayAdvancements, PlayAdvancementsSpec, + test_play_advancements, bench_write_play_advancements, bench_read_play_advancements); + + packet_test_cases!(Packet578, PlayEntityProperties, PlayEntityPropertiesSpec, + test_play_entity_properties, bench_write_play_entity_properties, bench_read_play_entity_properties); + + packet_test_cases!(Packet578, PlayEntityEffect, PlayEntityEffectSpec, + test_play_entity_effect, bench_write_play_entity_effect, bench_read_play_entity_effect); + + packet_test_cases!(Packet578, PlayDeclareRecipes, PlayDeclareRecipesSpec, + test_play_declare_recipes, bench_write_play_declare_recipes, bench_read_play_declare_recipes); + + packet_test_cases!(Packet578, PlayTags, PlayTagsSpec, + test_play_tags, bench_write_play_tags, bench_read_play_tags); + + packet_test_cases!(Packet578, PlayTeleportConfirm, PlayTeleportConfirmSpec, + test_play_teleport_confirm, bench_write_play_teleport_confirm, bench_read_play_teleport_confirm); + + packet_test_cases!(Packet578, PlayQueryBlockNbt, PlayQueryBlockNbtSpec, + test_play_query_block_nbt, bench_write_play_query_block_nbt, bench_read_play_query_block_nbt); + + packet_test_cases!(Packet578, PlayQueryEntityNbt, PlayQueryEntityNbtSpec, + test_play_query_entity_nbt, bench_write_play_query_entity_nbt, bench_read_play_query_entity_nbt); + + packet_test_cases!(Packet578, PlaySetDifficulty, PlaySetDifficultySpec, + test_play_set_difficulty, bench_write_play_set_difficulty, bench_read_play_set_difficulty); + + packet_test_cases!(Packet578, PlayClientChatMessage, PlayClientChatMessageSpec, + test_play_client_chat_message, bench_write_play_client_chat_message, bench_read_play_client_chat_message); + + packet_test_cases!(Packet578, PlayClientStatus, PlayClientStatusSpec, + test_play_client_status, bench_write_play_client_status, bench_read_play_client_status); + + packet_test_cases!(Packet578, PlayClientSettings, PlayClientSettingsSpec, + test_play_client_settings, bench_write_play_client_settings, bench_read_play_client_settings); + + packet_test_cases!(Packet578, PlayClientTabComplete, PlayClientTabCompleteSpec, + test_play_client_tab_complete, bench_write_play_client_tab_complete, bench_read_play_client_tab_complete); + + packet_test_cases!(Packet578, PlayClientWindowConfirmation, PlayClientWindowConfirmationSpec, + test_play_client_window_confirmation, bench_write_play_client_window_confirmation, bench_read_play_client_window_confirmation); + + packet_test_cases!(Packet578, PlayClickWindowButton, PlayClickWindowButtonSpec, + test_play_click_window_button, bench_write_play_click_window_button, bench_read_play_click_window_button); + + packet_test_cases!(Packet578, PlayClickWindow, PlayClickWindowSpec, + test_play_click_window, bench_write_play_click_window, bench_read_play_click_window); + + packet_test_cases!(Packet578, PlayClientCloseWindow, PlayClientCloseWindowSpec, + test_play_client_close_window, bench_write_play_client_close_window, bench_read_play_client_close_window); + + packet_test_cases!(Packet578, PlayClientPluginMessage, PlayClientPluginMessageSpec, + test_play_client_plugin_message, bench_write_play_client_plugin_message, bench_read_play_client_plugin_message); + + packet_test_cases!(Packet578, PlayEditBook, PlayEditBookSpec, + test_play_edit_book, bench_write_play_edit_book, bench_read_play_edit_book); + + packet_test_cases!(Packet578, PlayInteractEntity, PlayInteractEntitySpec, + test_play_interact_entity, bench_write_play_interact_entity, bench_read_play_interact_entity); + + packet_test_cases!(Packet578, PlayClientKeepAlive, PlayClientKeepAliveSpec, + test_play_client_keep_alive, bench_write_play_client_keep_alive, bench_read_play_client_keep_alive); + + packet_test_cases!(Packet578, PlayLockDifficulty, PlayLockDifficultySpec, + test_play_lock_difficulty, bench_write_play_lock_difficulty, bench_read_play_lock_difficulty); + + packet_test_cases!(Packet578, PlayPlayerPosition, PlayPlayerPositionSpec, + test_play_player_position, bench_write_play_player_position, bench_read_play_player_position); + + packet_test_cases!(Packet578, PlayClientPlayerPositionAndRotation, PlayClientPlayerPositionAndRotationSpec, + test_play_client_player_position_and_rotation, bench_write_play_client_player_position_and_rotation, bench_read_play_client_player_position_and_rotation); + + packet_test_cases!(Packet578, PlayPlayerRotation, PlayPlayerRotationSpec, + test_play_player_rotation, bench_write_play_player_rotation, bench_read_play_player_rotation); + + packet_test_cases!(Packet578, PlayPlayerMovement, PlayPlayerMovementSpec, + test_play_player_movement, bench_write_play_player_movement, bench_read_play_player_movement); + + packet_test_cases!(Packet578, PlayClientVehicleMove, PlayClientVehicleMoveSpec, + test_play_client_vehicle_move, bench_write_play_client_vehicle_move, bench_read_play_client_vehicle_move); + + packet_test_cases!(Packet578, PlaySteerBoat, PlaySteerBoatSpec, + test_play_steer_boat, bench_write_play_steer_boat, bench_read_play_steer_boat); + + packet_test_cases!(Packet578, PlayPickItem, PlayPickItemSpec, + test_play_pick_item, bench_write_play_pick_item, bench_read_play_pick_item); + + packet_test_cases!(Packet578, PlayCraftRecipeRequest, PlayCraftRecipeRequestSpec, + test_play_craft_recipe_request, bench_write_play_craft_recipe_request, bench_read_play_craft_recipe_request); + + packet_test_cases!(Packet578, PlayClientPlayerAbilities, PlayClientPlayerAbilitiesSpec, + test_play_client_player_abilities, bench_write_play_client_player_abilities, bench_read_play_client_player_abilities); + + packet_test_cases!(Packet578, PlayPlayerDigging, PlayPlayerDiggingSpec, + test_play_player_digging, bench_write_play_player_digging, bench_read_play_player_digging); + + packet_test_cases!(Packet578, PlayEntityAction, PlayEntityActionSpec, + test_play_entity_action, bench_write_play_entity_action, bench_read_play_entity_action); + + packet_test_cases!(Packet578, PlaySteerVehicle, PlaySteerVehicleSpec, + test_play_steer_vehicle, bench_write_play_steer_vehicle, bench_read_play_steer_vehicle); + + packet_test_cases!(Packet578, PlayNameItem, PlayNameItemSpec, + test_play_name_item, bench_write_play_name_item, bench_read_play_name_item); + + packet_test_cases!(Packet578, PlayResourcePackStatus, PlayResourcePackStatusSpec, + test_play_resource_pack_status, bench_write_play_resource_pack_status, bench_read_play_resource_pack_status); + + packet_test_cases!(Packet578, PlaySelectTrade, PlaySelectTradeSpec, + test_play_select_trade, bench_write_play_select_trade, bench_read_play_select_trade); + + packet_test_cases!(Packet578, PlaySetBeaconEffect, PlaySetBeaconEffectSpec, + test_play_set_beacon_effect, bench_write_play_set_beacon_effect, bench_read_play_set_beacon_effect); + + packet_test_cases!(Packet578, PlayClientHeldItemChange, PlayClientHeldItemChangeSpec, + test_play_client_held_item_change, bench_write_play_client_held_item_change, bench_read_play_client_held_item_change); + + packet_test_cases!(Packet578, PlayUpdateCommandBlock, PlayUpdateCommandBlockSpec, + test_play_update_command_block, bench_write_play_update_command_block, bench_read_play_update_command_block); + + packet_test_cases!(Packet578, PlayUpdateCommandBlockMinecart, PlayUpdateCommandBlockMinecartSpec, + test_play_update_command_block_minecart, bench_write_play_update_command_block_minecart, bench_read_play_update_command_block_minecart); + + packet_test_cases!(Packet578, PlayCreativeInventoryAction, PlayCreativeInventoryActionSpec, + test_play_creative_inventory_action, bench_write_play_creative_inventory_action, bench_read_play_creative_inventory_action); + + packet_test_cases!(Packet578, PlayUpdateJigsawBlock, PlayUpdateJigsawBlockSpec, + test_play_update_jigsaw_block, bench_write_play_update_jigsaw_block, bench_read_play_update_jigsaw_block); + + packet_test_cases!(Packet578, PlayUpdateStructureBlock, PlayUpdateStructureBlockSpec, + test_play_update_structure_block, bench_write_play_update_structure_block, bench_read_play_update_structure_block); + + packet_test_cases!(Packet578, PlayUpdateSign, PlayUpdateSignSpec, + test_play_update_sign, bench_write_play_update_sign, bench_read_play_update_sign); + + packet_test_cases!(Packet578, PlayClientAnimation, PlayClientAnimationSpec, + test_play_client_animation, bench_write_play_client_animation, bench_read_play_client_animation); + + packet_test_cases!(Packet578, PlaySpectate, PlaySpectateSpec, + test_play_spectate, bench_write_play_spectate, bench_read_play_spectate); + + packet_test_cases!(Packet578, PlayBlockPlacement, PlayBlockPlacementSpec, + test_play_block_placement, bench_write_play_block_placement, bench_read_play_block_placement); + + packet_test_cases!(Packet578, PlayUseItem, PlayUseItemSpec, + test_play_use_item, bench_write_play_use_item, bench_read_play_use_item); + + #[test] + fn test_generate_test_cases() { + Packet578::describe().packets.iter().map(move |packet| { + let snake_case = to_snake_case(packet.name.clone()); + format!("packet_test_cases!(Packet578, {}, {},\n test_{}, bench_write_{}, bench_read_{});\n", + packet.name, packet.body_struct, snake_case, snake_case, snake_case).to_owned() + }).for_each(move |line| { + println!("{}", line) + }) + } + + fn to_snake_case(camel: String) -> String { + let mut parts = Vec::new(); + let mut buf = String::new(); + for c in camel.chars() { + if !buf.is_empty() && char::is_uppercase(c) { + parts.push(buf); + buf = String::new(); + } + + buf.push(c.to_ascii_lowercase()); + } + + if !buf.is_empty() { + parts.push(buf); + } + + parts.join("_") + } }
\ No newline at end of file |