diff -r 6843c4551cde -r 06672690d71b rust/hedgewars-server/src/server/handlers/common.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-server/src/server/handlers/common.rs Mon Dec 10 22:44:46 2018 +0100 @@ -0,0 +1,73 @@ +use crate::{ + server::{actions::Action, core::HWServer}, + protocol::messages::{ + HWProtocolMessage::{self, Rnd}, HWServerMessage::{self, ChatMsg}, + } +}; +use rand::{self, Rng, thread_rng}; + +pub fn rnd_reply(options: &[String]) -> HWServerMessage { + let mut rng = thread_rng(); + let reply = if options.is_empty() { + (*rng.choose(&["heads", "tails"]).unwrap()).to_owned() + } else { + rng.choose(&options).unwrap().clone() + }; + + ChatMsg { + nick: "[random]".to_owned(), + msg: reply.clone(), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::protocol::messages::HWServerMessage::ChatMsg; + use crate::server::actions::{ + Action::{self, Send}, PendingMessage, + }; + + fn reply2string(r: HWServerMessage) -> String { + match r { + ChatMsg { msg: p, .. } => String::from(p), + _ => panic!("expected a ChatMsg"), + } + } + + fn run_handle_test(opts: Vec) { + let opts2 = opts.clone(); + for opt in opts { + while reply2string(rnd_reply(&opts2)) != opt {} + } + } + + /// This test terminates almost surely. + #[test] + fn test_handle_rnd_empty() { + run_handle_test(vec![]) + } + + /// This test terminates almost surely. + #[test] + fn test_handle_rnd_nonempty() { + run_handle_test(vec!["A".to_owned(), "B".to_owned(), "C".to_owned()]) + } + + /// This test terminates almost surely (strong law of large numbers) + #[test] + fn test_distribution() { + let eps = 0.000001; + let lim = 0.5; + let opts = vec![0.to_string(), 1.to_string()]; + let mut ones = 0; + let mut tries = 0; + + while tries < 1000 || ((ones as f64 / tries as f64) - lim).abs() >= eps { + tries += 1; + if reply2string(rnd_reply(&opts)) == 1.to_string() { + ones += 1; + } + } + } +}