TestComponent: assert closer to callsite
Attempts to assert closer to callsite to make it easier to debug. This requires that we also pay attention to remaining items in the expect_buffer. This check is done on Drop. Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
b61766d462
commit
c438402b15
4 changed files with 48 additions and 41 deletions
|
@ -12,6 +12,7 @@ use std::marker::Send;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::thread;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use futures::{task::Poll, Stream};
|
||||
|
@ -162,7 +163,6 @@ impl From<Message> for TestElement {
|
|||
#[derive(Debug)]
|
||||
pub struct TestComponent {
|
||||
in_buffer: VecDeque<TestElement>,
|
||||
out_buffer: VecDeque<TestElement>,
|
||||
expect_buffer: VecDeque<Expect>,
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,6 @@ impl TestComponent {
|
|||
.map(|el| TestElement(el))
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
out_buffer: VecDeque::new(),
|
||||
expect_buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
@ -212,33 +211,39 @@ impl TestComponent {
|
|||
.push_back(Expect::Presence(Box::new(callback), desc.into()))
|
||||
}
|
||||
|
||||
/// Asserts expected output and actual output are the same
|
||||
pub fn assert(&mut self) {
|
||||
loop {
|
||||
let out = self.out_buffer.pop_front();
|
||||
let expected = self.expect_buffer.pop_front();
|
||||
|
||||
match (out, expected) {
|
||||
(None, None) => break,
|
||||
(Some(out), Some(expected)) => match expected {
|
||||
Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)),
|
||||
Expect::Iq(cb, _) => cb(Iq::try_from(out.0).unwrap()),
|
||||
Expect::Message(cb, _) => cb(Message::try_from(out.0).unwrap()),
|
||||
Expect::Presence(cb, _) => cb(Presence::try_from(out.0).unwrap()),
|
||||
},
|
||||
(Some(out), None) => panic!("Missing matching expected element: {:?}", out),
|
||||
(None, Some(expected)) => match expected {
|
||||
Expect::Element(el) => panic!("Missing matching sent element: {:?}", el),
|
||||
Expect::Iq(_, desc) => panic!("Missing iq: {}", desc),
|
||||
Expect::Message(_, desc) => panic!("Missing message: {}", desc),
|
||||
Expect::Presence(_, desc) => panic!("Missing presence: {}", desc),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _send_stanza<E: Into<TestElement> + Send>(&mut self, el: E) -> Result<(), Error> {
|
||||
Ok(self.out_buffer.push_back(el.into()))
|
||||
let out: TestElement = el.into();
|
||||
let expected = self.expect_buffer.pop_front();
|
||||
|
||||
match expected {
|
||||
Some(expected) => match expected {
|
||||
Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)),
|
||||
Expect::Iq(cb, _) => match Iq::try_from(out.0.clone()) {
|
||||
Ok(iq) => cb(iq),
|
||||
_ => panic!(
|
||||
"Mismatch stanza type. Expected iq, got: {}",
|
||||
String::from(&out)
|
||||
),
|
||||
},
|
||||
Expect::Message(cb, _) => match Message::try_from(out.0.clone()) {
|
||||
Ok(message) => cb(message),
|
||||
_ => panic!(
|
||||
"Mismatch stanza type. Expected message, got: {}",
|
||||
String::from(&out)
|
||||
),
|
||||
},
|
||||
Expect::Presence(cb, _) => match Presence::try_from(out.0.clone()) {
|
||||
Ok(presence) => cb(presence),
|
||||
_ => panic!(
|
||||
"Mismatch stanza type. Expected presence, got: {}",
|
||||
String::from(&out)
|
||||
),
|
||||
},
|
||||
},
|
||||
None => panic!("Missing matching expected element: {:?}", out),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,6 +259,21 @@ impl Stream for TestComponent {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for TestComponent {
|
||||
fn drop(&mut self) {
|
||||
// Don't assert if we're already panicking. Rustc displays a huge backtrace when "panicked
|
||||
// while panicking" even when nobody asks for it (RUST_BACKTRACE unset). Let the error
|
||||
// appear if there isn't any other error.
|
||||
if !thread::panicking() {
|
||||
assert_eq!(
|
||||
self.expect_buffer.len(),
|
||||
0,
|
||||
"Remaining expected elements in the buffer"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ComponentTrait for TestComponent {
|
||||
async fn send_stanza<E: Into<Element> + Send>(&mut self, el: E) -> Result<(), Error> {
|
||||
|
|
|
@ -473,7 +473,6 @@ mod tests {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
component.assert();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -534,7 +533,6 @@ mod tests {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
component.assert();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -634,7 +632,6 @@ mod tests {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
component.assert();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -706,6 +703,5 @@ mod tests {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
component.assert();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,5 +61,4 @@ async fn test_iq_unimplemented() {
|
|||
|
||||
component.expect(reply);
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ async fn test_join_presence_empty_room() {
|
|||
}, "Room subject to participant1");
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
|
||||
assert_eq!(rooms.len(), 1);
|
||||
match rooms.get(&roomjid) {
|
||||
|
@ -160,7 +159,6 @@ async fn test_join_presence_nick_already_assigned() {
|
|||
);
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
|
||||
match rooms.get(&roomjid) {
|
||||
Some(room) => assert_eq!(room.occupants.len(), 1),
|
||||
|
@ -263,7 +261,6 @@ async fn test_join_presence_existing_room() {
|
|||
}, "Subject for participant2");
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
|
||||
match rooms.get(&roomjid) {
|
||||
Some(room) => assert_eq!(room.occupants.len(), 2),
|
||||
|
@ -330,7 +327,6 @@ async fn test_presence_resync() {
|
|||
);
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
|
||||
match rooms.get(&roomjid) {
|
||||
Some(room) => assert_eq!(room.occupants.len(), 2),
|
||||
|
@ -354,7 +350,6 @@ async fn test_leave_non_existing_room() {
|
|||
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
// The leave should be ignored, there should be no output at all.
|
||||
component.assert();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -394,7 +389,6 @@ async fn test_leave_last_participant() {
|
|||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
|
||||
component.assert();
|
||||
assert_eq!(rooms.len(), 0);
|
||||
}
|
||||
|
||||
|
@ -457,7 +451,6 @@ async fn test_leave_room_not_last() {
|
|||
);
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
assert_eq!(rooms.len(), 1);
|
||||
match rooms.get(&roomjid) {
|
||||
Some(room) => assert_eq!(room.occupants.len(), 1),
|
||||
|
@ -547,7 +540,6 @@ async fn test_join_msn() {
|
|||
component.expect_message(|_| (), "Subject message for participant2");
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
component.assert();
|
||||
|
||||
assert_eq!(rooms.len(), 1);
|
||||
match rooms.get(&roomjid) {
|
||||
|
|
Loading…
Reference in a new issue