use hexify::assert_eq_slices;
use monotonic_time_rs::Millis;
use nimble_host::{err::HostError, Host};
use nimble_host_logic::{GameStateProvider, HostConnectionId};
use nimble_participant::ParticipantId;
use nimble_sample_step::SampleStep;
use tick_id::TickId;
pub struct TestStateProvider {
pub tick_id: TickId,
pub payload: Vec<u8>,
}
impl GameStateProvider for TestStateProvider {
fn state(&self, _: TickId) -> (TickId, Vec<u8>) {
(self.tick_id, self.payload.clone())
}
}
fn create_and_connect<
StepT: Clone
+ std::fmt::Debug
+ std::fmt::Display
+ std::cmp::Eq
+ flood_rs::Deserialize
+ flood_rs::Serialize,
>() -> Result<(Host<StepT>, HostConnectionId, TestStateProvider), HostError> {
#[rustfmt::skip]
let connect_datagram: &[u8] = &[
0x00, 0x00,
0x05, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0, 2, 0, ];
let application_version = app_version::Version::new(0, 1, 2);
let mut host = Host::<StepT>::new(application_version, TickId(0));
let not_used_connection_id = host
.create_connection()
.expect("should have connection here");
assert_eq!(not_used_connection_id.0, 0);
let connection_id = host
.create_connection()
.expect("should have connection here");
assert_eq!(connection_id.0, 1);
let state_provider = TestStateProvider {
tick_id: TickId(32),
payload: vec![0xff],
};
let now = Millis::new(0);
host.update(connection_id, now, connect_datagram, &state_provider)?;
Ok((host, connection_id, state_provider))
}
#[test_log::test]
fn join_game() -> Result<(), HostError> {
let (mut host, connection_id, state_provider) = create_and_connect::<SampleStep>()?;
#[rustfmt::skip]
let join_datagram: &[u8] = &[
0x00, 0x01,
0x01, 0x00, 0x00, 0x02, 0x42, 0xFF, ];
let now = Millis::new(0);
assert_eq!(host.session().participants.len(), 0);
let maybe_join_response_datagrams =
host.update(connection_id, now, join_datagram, &state_provider)?;
assert_eq!(maybe_join_response_datagrams.len(), 1);
assert_eq!(host.session().participants.len(), 2);
let expected_participant_id = ParticipantId(0);
let participant = host
.session()
.participants
.get(&expected_participant_id)
.expect("should have participant");
assert_eq!(participant.borrow().id.0, 0);
assert_eq!(participant.borrow().client_local_index, 0x42);
#[rustfmt::skip]
let expected_join_response: &[u8] = &[
0x00, 0x01,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x00, 0xFF, 0x01, ];
assert_eq_slices(&maybe_join_response_datagrams[0], expected_join_response);
Ok(())
}
#[test_log::test]
fn game_step() -> Result<(), HostError> {
let (mut host, connection_id, state_provider) = create_and_connect::<SampleStep>()?;
#[rustfmt::skip]
let feed_predicted_steps = &[
0x00, 0x01,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
let now = Millis::new(0);
let maybe_step_response_datagrams =
host.update(connection_id, now, feed_predicted_steps, &state_provider)?;
#[rustfmt::skip]
let expected_game_step_response = &[
0x00, 0x01,
0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, ];
assert_eq_slices(
&maybe_step_response_datagrams[0],
expected_game_step_response,
);
Ok(())
}