use grovewright_core::codec::{DecodeError, Reader, Writer}; use grovewright_core::command::Command; use grovewright_core::map::Pos; use grovewright_core::player::{PlayerId, MAX_NAME_BYTES}; fn round_trip(command: &Command) -> Command { let mut w = Writer::new(); command.encode(&mut w); let bytes = w.into_bytes(); let mut r = Reader::new(&bytes); let decoded = Command::decode(&mut r).expect("command decodes"); r.finish().expect("no bytes are left over"); decoded } #[test] fn every_command_survives_encoding() { let commands = [ Command::Join { key: [7; 16], name: "Ada".to_owned(), }, Command::Leave { player: PlayerId(3), }, Command::Dig { player: PlayerId(1), pos: Pos::new(-4, 1_000), }, ]; for command in &commands { assert_eq!(&round_trip(command), command); } } #[test] fn an_overlong_name_is_shortened_when_encoded() { let command = Command::Join { key: [1; 16], name: "x".repeat(MAX_NAME_BYTES + 10), }; assert_eq!( round_trip(&command), Command::Join { key: [1; 16], name: "x".repeat(MAX_NAME_BYTES), } ); } #[test] fn an_unknown_command_is_rejected() { assert_eq!( Command::decode(&mut Reader::new(&[0xEE])), Err(DecodeError::InvalidValue("command tag")) ); } #[test] fn a_cut_off_command_is_rejected() { let mut w = Writer::new(); Command::Dig { player: PlayerId(0), pos: Pos::new(1, 2), } .encode(&mut w); let bytes = w.into_bytes(); assert_eq!( Command::decode(&mut Reader::new(&bytes[..bytes.len() - 1])), Err(DecodeError::UnexpectedEnd) ); } #[test] fn several_commands_can_follow_each_other_in_one_buffer() { let commands = vec![ Command::Leave { player: PlayerId(2), }, Command::Dig { player: PlayerId(0), pos: Pos::new(5, 6), }, ]; let mut w = Writer::new(); for command in &commands { command.encode(&mut w); } let bytes = w.into_bytes(); let mut r = Reader::new(&bytes); let mut decoded = Vec::new(); while r.remaining() > 0 { decoded.push(Command::decode(&mut r).unwrap()); } assert_eq!(decoded, commands); }