#![warn(
missing_debug_implementations,
missing_docs,
rust_2018_idioms,
unreachable_pub
)]
#![forbid(unsafe_code)]
#![allow(elided_lifetimes_in_paths)]
pub mod builder;
pub mod mock;
pub use builder::Builder;
#[cfg(test)]
mod tests {
use std::convert::Infallible;
use super::*;
use tower_async_layer::{Identity, Layer};
use tower_async_service::Service;
#[tokio::test]
async fn test_runner_ok_with_success() {
Builder::new("ping")
.send_response("pong")
.expect_request("ping")
.test(Identity::new())
.await
.expect_response("pong");
}
#[tokio::test]
#[should_panic]
async fn test_runner_ok_with_success_panics() {
Builder::new("ping")
.send_response("pong")
.expect_request("pong")
.test(Identity::new())
.await
.expect_response("pong");
}
#[derive(Debug)]
struct ApologeticService<S> {
inner: S,
}
impl<S, Request> Service<Request> for ApologeticService<S>
where
S: Service<Request>,
{
type Response = ();
type Error = &'static str;
async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
let _ = self.inner.call(request).await;
Err("Sorry!")
}
}
struct ApolgeticLayer;
impl<S> Layer<S> for ApolgeticLayer {
type Service = ApologeticService<S>;
fn layer(&self, inner: S) -> Self::Service {
ApologeticService { inner }
}
}
#[tokio::test]
async fn test_runner_ok_with_failure() {
Builder::new("ping")
.send_response("pong")
.expect_request("ping")
.test(ApolgeticLayer)
.await
.expect_error("Sorry!");
}
#[tokio::test]
#[should_panic]
async fn test_runner_ok_with_failure_panics() {
Builder::new("ping")
.send_response("pong")
.expect_request("ping")
.test(ApolgeticLayer)
.await
.expect_response(());
}
#[tokio::test]
async fn test_runner_err_with_error() {
Builder::new("ping")
.send_error("oops")
.expect_request("ping")
.test(Identity::new())
.await
.expect_error("oops");
}
#[tokio::test]
#[should_panic]
async fn test_runner_err_with_error_panics() {
Builder::new("ping")
.send_error("oops")
.expect_request("ping")
.test(Identity::new())
.await
.expect_response(());
}
#[derive(Debug)]
struct DebugFmtService<S> {
inner: S,
}
impl<S, Request> Service<Request> for DebugFmtService<S>
where
S: Service<Request>,
S::Response: std::fmt::Debug,
S::Error: std::fmt::Debug,
{
type Response = String;
type Error = Infallible;
async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
Ok(format!(
"DebugFmtService: {:?}",
self.inner.call(request).await
))
}
}
struct DebugFmtLayer;
impl<S> Layer<S> for DebugFmtLayer {
type Service = DebugFmtService<S>;
fn layer(&self, inner: S) -> Self::Service {
DebugFmtService { inner }
}
}
#[tokio::test]
async fn test_runner_err_with_response() {
Builder::new("ping")
.send_error("Sorry!")
.expect_request("ping")
.test(DebugFmtLayer)
.await
.expect_response("DebugFmtService: Err(\"Sorry!\")".to_string());
}
#[tokio::test]
#[should_panic]
async fn test_runner_err_with_response_panics() {
Builder::new("ping")
.send_error("Sorry!")
.expect_request("ping")
.test(DebugFmtLayer)
.await
.expect_response("Sorry!".to_string());
}
}