fix(net)!: remove Drop assertions for any unused plans
All checks were successful
Test / build (map[name:nightly]) (push) Successful in 8m36s
Test / build (map[name:stable]) (push) Successful in 10m10s
Release Please / Release-plz (push) Successful in 1m50s

Tests should use the existing `assert_no_unused_plans` method available
on both `Net` and `MockNet`.

This removes the problem of assetions being applied early when there are
multiple clones of the `Net` or `MockNet` and one of them is dropped.

feat(net): add `MockNet:;plans_left`

tests(net): add tests for MockNet::try_from
This commit is contained in:
Paul Campbell 2024-12-28 17:48:27 +00:00
parent 9b7a2870ff
commit 8007f01d94
2 changed files with 60 additions and 41 deletions

View file

@ -553,6 +553,7 @@ fn basic_auth_header_value(
pub struct MockNet {
plans: Rc<RefCell<Plans>>,
}
impl MockNet {
/// Helper to create a default [Client].
///
@ -617,6 +618,11 @@ impl MockNet {
tracing::debug!("reset plans");
self.plans.take();
}
/// Returns the number of plans added and not yet matched against.
pub fn plans_left(&self) -> usize {
self.plans.borrow().len()
}
}
impl From<MockNet> for Net {
fn from(mock_net: MockNet) -> Self {
@ -628,47 +634,6 @@ impl From<MockNet> for Net {
}
}
impl Drop for MockNet {
#[cfg_attr(test, mutants::skip)]
#[tracing::instrument]
fn drop(&mut self) {
// Don't assert during panic to avoid double panic
if std::thread::panicking() {
return;
}
let unused = self.plans.take();
if !unused.is_empty() {
log_unused_plans(&unused);
assert!(
unused.is_empty(),
"{} expected requests were not made",
unused.len()
);
}
}
}
impl Drop for Net {
#[cfg_attr(test, mutants::skip)]
#[tracing::instrument]
fn drop(&mut self) {
// Don't assert during panic to avoid double panic
if std::thread::panicking() {
return;
}
if let Some(plans) = &self.plans {
let unused = plans.try_lock().expect("lock plans").take();
if !unused.is_empty() {
log_unused_plans(&unused);
assert!(
unused.is_empty(),
"{} expected requests were not made",
unused.len()
);
}
}
}
}
#[cfg_attr(test, mutants::skip)]
fn log_unused_plans(unused: &[Plan]) {
if !unused.is_empty() {

View file

@ -642,3 +642,57 @@ async fn test_get_with_user_agent() {
assert_eq!(response.status(), StatusCode::FORBIDDEN);
assert_eq!(valid.status(), StatusCode::OK);
}
#[test]
fn test_reset_removes_all_plans() {
//given
let mock_net = kxio::net::mock();
let url = "https://www.example.com/path";
mock_net
.on()
.get(url)
.user_agent("007")
.respond(StatusCode::OK)
.mock()
.expect("mock");
mock_net
.on()
.get(url)
.user_agent("orange")
.respond(StatusCode::FORBIDDEN)
.mock()
.expect("mock");
assert_eq!(mock_net.plans_left(), 2);
//when
mock_net.reset();
//then
assert_eq!(mock_net.plans_left(), 0);
}
#[tokio::test]
async fn try_from_with_net_from_a_mock_net() {
//given
let mock_net = kxio::net::mock();
let net = Net::from(mock_net);
//when
let result = MockNet::try_from(net).await;
//then
assert!(result.is_ok());
}
#[tokio::test]
async fn try_from_with_net_not_from_a_mock_net() {
//given
let net = kxio::net::new();
//when
let result = MockNet::try_from(net).await;
//then
assert!(result.is_err());
}