Add support for using testserver in doctests. (#218)
Doctests run against a normally-built copy of the crate, i.e. one without #[cfg(test)] set, so we can't use the conditional compilation feature. Instead, define a static var that indicates whether the library is running in test mode or not. For each doctest, insert a hidden call that sets this var to true. Then, when ureq::agent() is called, it returns a test_agent instead. This required moving testserver out of the test mod and into src/, so that it can be included unconditionally (i.e. when cfg(test) is false). This PR converts one doctest as an example. If we land this PR, I'll send a followup to convert the rest.
This commit is contained in:
committed by
GitHub
parent
a0b901f35b
commit
acc36ac370
30
src/lib.rs
30
src/lib.rs
@@ -121,6 +121,8 @@ pub use serde_json::json;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
#[doc(hidden)]
|
||||
mod testserver;
|
||||
|
||||
pub use crate::agent::Agent;
|
||||
pub use crate::agent::AgentBuilder;
|
||||
@@ -137,17 +139,41 @@ pub use cookie::Cookie;
|
||||
#[cfg(feature = "json")]
|
||||
pub use serde_json::{to_value as serde_to_value, Map as SerdeMap, Value as SerdeValue};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
/// Creates an agent builder.
|
||||
pub fn builder() -> AgentBuilder {
|
||||
AgentBuilder::new()
|
||||
}
|
||||
|
||||
// is_test returns false so long as it has only ever been called with false.
|
||||
// If it has ever been called with true, it will always return true after that.
|
||||
// This is a public but hidden function used to allow doctests to use the test_agent.
|
||||
// Note that we use this approach for doctests rather the #[cfg(test)], because
|
||||
// doctests are run against a copy of the crate build without cfg(test) set.
|
||||
// We also can't use #[cfg(doctest)] to do this, because cfg(doctest) is only set
|
||||
// when collecting doctests, not when building the crate.
|
||||
#[doc(hidden)]
|
||||
pub fn is_test(is: bool) -> bool {
|
||||
static IS_TEST: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false));
|
||||
if is {
|
||||
IS_TEST.store(true, Ordering::SeqCst);
|
||||
}
|
||||
let x = IS_TEST.load(Ordering::SeqCst);
|
||||
return x;
|
||||
}
|
||||
|
||||
/// Agents are used to keep state between requests.
|
||||
pub fn agent() -> Agent {
|
||||
#[cfg(not(test))]
|
||||
return AgentBuilder::new().build();
|
||||
if is_test(false) {
|
||||
return testserver::test_agent();
|
||||
} else {
|
||||
return AgentBuilder::new().build();
|
||||
}
|
||||
#[cfg(test)]
|
||||
return test::test_agent();
|
||||
return testserver::test_agent();
|
||||
}
|
||||
|
||||
/// Make a request setting the HTTP method via a string.
|
||||
|
||||
Reference in New Issue
Block a user