1#![warn(
2 missing_debug_implementations,
3 missing_docs,
4 rust_2018_idioms,
5 unreachable_pub
6)]
7#![forbid(unsafe_code)]
8#![allow(elided_lifetimes_in_paths)]
9pub mod builder;
47pub mod mock;
48
49pub use builder::Builder;
50
51#[cfg(test)]
52mod tests {
53 use std::convert::Infallible;
54
55 use super::*;
56 use tower_async_layer::{Identity, Layer};
57 use tower_async_service::Service;
58
59 #[tokio::test]
60 async fn test_runner_ok_with_success() {
61 Builder::new("ping")
62 .send_response("pong")
63 .expect_request("ping")
64 .test(Identity::new())
65 .await
66 .expect_response("pong");
67 }
68
69 #[tokio::test]
70 #[should_panic]
71 async fn test_runner_ok_with_success_panics() {
72 Builder::new("ping")
73 .send_response("pong")
74 .expect_request("pong")
75 .test(Identity::new())
76 .await
77 .expect_response("pong");
78 }
79
80 #[derive(Debug)]
81 struct ApologeticService<S> {
82 inner: S,
83 }
84
85 impl<S, Request> Service<Request> for ApologeticService<S>
86 where
87 S: Service<Request>,
88 {
89 type Response = ();
90 type Error = &'static str;
91
92 async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
93 let _ = self.inner.call(request).await;
94 Err("Sorry!")
95 }
96 }
97
98 struct ApolgeticLayer;
99
100 impl<S> Layer<S> for ApolgeticLayer {
101 type Service = ApologeticService<S>;
102
103 fn layer(&self, inner: S) -> Self::Service {
104 ApologeticService { inner }
105 }
106 }
107
108 #[tokio::test]
109 async fn test_runner_ok_with_failure() {
110 Builder::new("ping")
111 .send_response("pong")
112 .expect_request("ping")
113 .test(ApolgeticLayer)
114 .await
115 .expect_error("Sorry!");
116 }
117
118 #[tokio::test]
119 #[should_panic]
120 async fn test_runner_ok_with_failure_panics() {
121 Builder::new("ping")
122 .send_response("pong")
123 .expect_request("ping")
124 .test(ApolgeticLayer)
125 .await
126 .expect_response(());
127 }
128
129 #[tokio::test]
130 async fn test_runner_err_with_error() {
131 Builder::new("ping")
132 .send_error("oops")
133 .expect_request("ping")
134 .test(Identity::new())
135 .await
136 .expect_error("oops");
137 }
138
139 #[tokio::test]
140 #[should_panic]
141 async fn test_runner_err_with_error_panics() {
142 Builder::new("ping")
143 .send_error("oops")
144 .expect_request("ping")
145 .test(Identity::new())
146 .await
147 .expect_response(());
148 }
149
150 #[derive(Debug)]
151 struct DebugFmtService<S> {
152 inner: S,
153 }
154
155 impl<S, Request> Service<Request> for DebugFmtService<S>
156 where
157 S: Service<Request>,
158 S::Response: std::fmt::Debug,
159 S::Error: std::fmt::Debug,
160 {
161 type Response = String;
162 type Error = Infallible;
163
164 async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
165 Ok(format!(
166 "DebugFmtService: {:?}",
167 self.inner.call(request).await
168 ))
169 }
170 }
171
172 struct DebugFmtLayer;
173
174 impl<S> Layer<S> for DebugFmtLayer {
175 type Service = DebugFmtService<S>;
176
177 fn layer(&self, inner: S) -> Self::Service {
178 DebugFmtService { inner }
179 }
180 }
181
182 #[tokio::test]
183 async fn test_runner_err_with_response() {
184 Builder::new("ping")
185 .send_error("Sorry!")
186 .expect_request("ping")
187 .test(DebugFmtLayer)
188 .await
189 .expect_response("DebugFmtService: Err(\"Sorry!\")".to_string());
190 }
191
192 #[tokio::test]
193 #[should_panic]
194 async fn test_runner_err_with_response_panics() {
195 Builder::new("ping")
196 .send_error("Sorry!")
197 .expect_request("ping")
198 .test(DebugFmtLayer)
199 .await
200 .expect_response("Sorry!".to_string());
201 }
202}