use super::room::Room; use super::event::Event; use rand::{self, Rng}; use rand::distributions::Alphanumeric; use crossbeam_channel::{unbounded, Sender, Receiver}; #[derive(Clone, Debug)] pub struct MockRoom { since: String, room_id: String, events_s: Sender>, events_r: Receiver>, pub sender: String, } impl MockRoom { pub fn create(sender: String) -> MockRoom { MockRoom::join(sender, rands()) } pub fn join(sender: String, room_id: String) -> MockRoom { let (s, r) = unbounded(); s.send(vec![]).ok().unwrap(); let mut mr = MockRoom { since: "".to_string(), room_id: room_id.clone(), events_s: s, events_r: r, sender: sender, }; mr.send_as(mr.sender.clone(), format!(r#"{{ "displayname": "{}", "membership": "join" }}"#, mr.sender.clone())).unwrap(); mr } pub fn room(&self) -> impl Room { self.clone() } pub fn send_as(&mut self, id: String, message: String) -> Result { let since = rands(); let e = Event{ sender: id, since: since.clone(), body: message, }; let mut events = self.events_r.recv().ok().unwrap(); events.push(e); self.events_s.send(events).ok().unwrap(); Ok(since.clone()) } } impl Room for MockRoom { fn sync(&mut self) -> Vec { let mut unseen: Vec = vec![]; let mut since = self.since.clone(); let events = self.events_r.recv().ok().unwrap(); for e in &events { if e.since == self.since { unseen.clear(); since = self.since.clone(); } else { unseen.push(e.clone()); since = e.since.clone(); } } self.events_s.send(events).ok().unwrap(); self.since = since; return unseen; } fn send(&mut self, message: String) -> Result { self.send_as(self.sender.clone(), message) } fn room_id(&self) -> String { self.room_id.clone() } fn rollback(&mut self, since: String) { self.since = since; } fn since(&self) -> String { self.since.clone() } } impl Drop for MockRoom { fn drop(&mut self) { println!("MockRoom::drop not impl"); } } pub fn rands() -> String { rand::thread_rng() .sample_iter(&Alphanumeric) .take(10) .collect::() } #[cfg(test)] mod tests { use super::Room; use super::MockRoom; use super::Event; use super::rands; fn _dummy() -> MockRoom { let mut r = MockRoom::create(rands()); r.since = "1".to_string(); let mut events = r.events_r.recv().ok().unwrap(); for i in 0..5 { events.push(Event{ sender: i.to_string(), since: i.to_string(), body: i.to_string(), }); } r.events_s.send(events).ok().unwrap(); r } #[test] fn randstest() { let a = rands(); let b = rands(); assert!(a != b, "a == {} == b == {}", a, b); } #[test] fn create() { let mut r: MockRoom = MockRoom::create(rands()); println!("{:?}", r.sync()); } #[test] fn join() { let rid = "a".to_string(); let mut r: MockRoom = MockRoom::join(rands(), rid.to_string()); assert!(r.room_id == rid); let events = r.sync(); let mut found = false; for e in &events { let j = e.join(); if j.is_some() { found = true; } } assert!(found); } #[test] fn since_tracking_push_two() { let mut r = _dummy(); r.sync(); let mut sinces = vec![]; for _ in 0..10 { sinces.push(r.send("0".to_string()).ok().unwrap()); sinces.push(r.send("0".to_string()).ok().unwrap()); r.sync(); assert!(r.since == *sinces.last().unwrap()); } } #[test] fn since_tracking_push_one() { let mut r = _dummy(); r.sync(); let mut sinces = vec![]; for _ in 0..10 { sinces.push(r.send("0".to_string()).ok().unwrap()); r.sync(); assert!(r.since == *sinces.last().unwrap()); } } #[test] fn since_tracking_push_none() { let mut r = _dummy(); r.sync(); let mut sinces = vec![]; sinces.push(r.send("0".to_string()).ok().unwrap()); assert!(r.sync().len() == 1); assert!(r.since == *sinces.last().unwrap(), "after one send: want {:?}, got {:?}: {:?}", *sinces.last().unwrap(), r.since, sinces); assert!(r.sync().len() == 0); assert!(r.since == *sinces.last().unwrap(), "after no send: want {:?}, got {:?}: {:?}", *sinces.last().unwrap(), r.since, sinces); } #[test] fn sync() { let mut r = _dummy(); let events = r.sync(); assert!(events.len() == 3, "want {}, got {}: {:?}", 3, events.len(), events); assert!(events[0].sender == "2"); assert!(events[0].body == "2"); assert!(events[0].since == "2"); assert!(r.since == "4", "want since==4, got {}", r.since); } #[test] fn send() { let mut r = _dummy(); let message = "message".to_string(); r.sync(); assert!(r.send(message.clone()).ok().unwrap().len() > 0); assert!(r.since == "4"); let events = r.sync(); assert!(events.len() == 1); assert!(events[0].body == message, "want {}, got {}: {:?}", message, events[0].body, events); assert!(r.since != "4"); } #[test] fn rollback() { let mut r = _dummy(); let was = r.since.to_string(); let events = r.sync(); assert!(events.len() == 3); assert!(r.since == "4"); r.rollback(was.to_string()); assert!(r.since == was); let events = r.sync(); assert!(events.len() == 3); assert!(r.since == "4"); } }