Added Url encoding and fixed bugs that cropped up in the process.

This commit is contained in:
2019-12-10 10:15:27 -08:00
parent 1269db042b
commit 1922c99979
6 changed files with 107 additions and 10 deletions

View File

@@ -7,6 +7,7 @@ pub use crate::all_of;
pub use crate::any_of;
pub mod request;
pub mod response;
pub mod sequence;
pub trait Mapper<IN>: Send + fmt::Debug
where
@@ -40,7 +41,10 @@ pub fn any() -> Any {
}
#[derive(Debug)]
pub struct Any;
impl<IN> Mapper<IN> for Any {
impl<IN> Mapper<IN> for Any
where
IN: ?Sized,
{
type Out = bool;
fn map(&mut self, _input: &IN) -> bool {
@@ -65,6 +69,23 @@ where
}
}
pub fn deref<C>(inner: C) -> Deref<C> {
Deref(inner)
}
#[derive(Debug)]
pub struct Deref<C>(C);
impl<C, IN> Mapper<IN> for Deref<C>
where
C: Mapper<IN::Target>,
IN: std::ops::Deref,
{
type Out = C::Out;
fn map(&mut self, input: &IN) -> C::Out {
self.0.map(input.deref())
}
}
pub trait IntoRegex {
fn into_regex(self) -> regex::bytes::Regex;
}
@@ -173,15 +194,15 @@ where
}
}
pub fn uri_decoded<C>(inner: C) -> UriDecoded<C>
pub fn url_decoded<C>(inner: C) -> UrlDecoded<C>
where
C: Mapper<[(String, String)]>,
{
UriDecoded(inner)
UrlDecoded(inner)
}
#[derive(Debug)]
pub struct UriDecoded<C>(C);
impl<IN, C> Mapper<IN> for UriDecoded<C>
pub struct UrlDecoded<C>(C);
impl<IN, C> Mapper<IN> for UrlDecoded<C>
where
IN: AsRef<[u8]> + ?Sized,
C: Mapper<[(String, String)]>,
@@ -335,12 +356,12 @@ mod tests {
}
#[test]
fn test_uri_decoded() {
fn test_url_decoded() {
let expected = vec![
("key 1".to_owned(), "value 1".to_owned()),
("key2".to_owned(), "".to_owned()),
];
let mut c = request::query(uri_decoded(eq(expected)));
let mut c = request::query(url_decoded(eq(expected)));
let req = http::Request::get("https://example.com/path?key%201=value%201&key2")
.body("")
.unwrap();

View File

@@ -88,12 +88,13 @@ pub fn body<C>(inner: C) -> Body<C> {
pub struct Body<C>(C);
impl<C, B> Mapper<hyper::Request<B>> for Body<C>
where
C: Mapper<B>,
B: ToOwned,
C: Mapper<B::Owned>,
{
type Out = C::Out;
fn map(&mut self, input: &hyper::Request<B>) -> C::Out {
self.0.map(input.body())
self.0.map(&input.body().to_owned())
}
}

View File

@@ -46,6 +46,27 @@ impl Responder for JsonEncoded {
}
}
pub fn url_encoded<T>(data: T) -> impl Responder
where
T: serde::Serialize,
{
UrlEncoded(serde_urlencoded::to_string(&data).unwrap())
}
#[derive(Debug)]
pub struct UrlEncoded(String);
impl Responder for UrlEncoded {
fn respond(&mut self) -> Pin<Box<dyn Future<Output = http::Response<hyper::Body>> + Send>> {
async fn _respond(body: String) -> http::Response<hyper::Body> {
hyper::Response::builder()
.status(200)
.header("Content-Type", "application/x-www-form-urlencoded")
.body(body.into())
.unwrap()
}
Box::pin(_respond(self.0.clone()))
}
}
impl<B> Responder for hyper::Response<B>
where
B: Clone + Into<hyper::Body> + Send + fmt::Debug,

View File

@@ -109,6 +109,11 @@ impl Server {
/// all expectations leaving the server running in a clean state.
pub fn verify_and_clear(&mut self) {
let mut state = self.state.lock();
if std::thread::panicking() {
// If the test is already panicking don't double panic on drop.
state.expected.clear();
return;
}
for expectation in state.expected.iter() {
let is_valid_cardinality = match &expectation.cardinality {
Times::AnyNumber => true,