1use std::convert::Infallible;
5
6use tower_async_layer::Layer;
7use tower_async_service::Service;
8
9pub mod marker {
10 #[derive(Debug, Default)]
15 pub struct None;
16
17 #[derive(Debug, Default)]
19 pub struct Defined;
20
21 #[derive(Debug, Default)]
23 pub struct Ok<T>(pub T);
24
25 #[derive(Debug, Default)]
27 pub struct Err<T>(pub T);
28}
29
30#[derive(Debug)]
33pub struct Test<In, Out> {
34 output: Out,
35 expected_input: Option<In>,
36}
37
38#[derive(Debug)]
87pub struct Builder<R, T, RequestState> {
88 request: R,
89 tests: T,
90 _request_state: RequestState,
91}
92
93impl<R> Builder<R, marker::None, marker::None> {
98 pub fn new(request: R) -> Self {
100 Self {
101 request,
102 tests: marker::None,
103 _request_state: marker::None,
104 }
105 }
106
107 pub fn send_response<Response>(
109 self,
110 response: Response,
111 ) -> Builder<R, Vec<Test<R, marker::Ok<Response>>>, marker::None> {
112 Builder {
113 request: self.request,
114 tests: vec![Test {
115 output: marker::Ok(response),
116 expected_input: None,
117 }],
118 _request_state: marker::None,
119 }
120 }
121
122 pub fn send_error<Error>(
124 self,
125 error: Error,
126 ) -> Builder<R, Vec<Test<R, marker::Err<Error>>>, marker::None> {
127 Builder {
128 request: self.request,
129 tests: vec![Test {
130 output: marker::Err(error),
131 expected_input: None,
132 }],
133 _request_state: marker::None,
134 }
135 }
136}
137
138impl<R, Response, RequestState> Builder<R, Vec<Test<R, marker::Ok<Response>>>, RequestState> {
143 pub fn send_response(
145 mut self,
146 response: Response,
147 ) -> Builder<R, Vec<Test<R, marker::Ok<Response>>>, marker::None> {
148 self.tests.push(Test {
149 output: marker::Ok(response),
150 expected_input: None,
151 });
152 Builder {
153 request: self.request,
154 tests: self.tests,
155 _request_state: marker::None,
156 }
157 }
158
159 #[allow(clippy::type_complexity)]
161 pub fn send_error<Error>(
162 self,
163 error: Error,
164 ) -> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::None> {
165 let mut tests: Vec<_> = self
166 .tests
167 .into_iter()
168 .map(|test| Test {
169 output: Ok(test.output.0),
170 expected_input: test.expected_input,
171 })
172 .collect();
173 tests.push(Test {
174 output: Err(error),
175 expected_input: None,
176 });
177 Builder {
178 request: self.request,
179 tests,
180 _request_state: marker::None,
181 }
182 }
183}
184
185impl<R, Response, RequestState> Builder<R, Vec<Test<R, marker::Ok<Response>>>, RequestState>
186where
187 R: Send + Sync + std::fmt::Debug + PartialEq,
188 Response: Send + Sync,
189{
190 pub async fn test<L>(
197 self,
198 layer: L,
199 ) -> ResponseTester<
200 <<L as Layer<crate::mock::Mock<R, Response, Infallible>>>::Service as Service<R>>::Response,
201 <<L as Layer<crate::mock::Mock<R, Response, Infallible>>>::Service as Service<R>>::Error,
202 >
203 where
204 L: Layer<crate::mock::Mock<R, Response, Infallible>>,
205 L::Service: Service<R>,
206 {
207 let tests = self
208 .tests
209 .into_iter()
210 .map(|test| Test {
211 output: Ok(test.output.0),
212 expected_input: test.expected_input,
213 })
214 .collect();
215 test_layer(layer, self.request, tests).await
216 }
217}
218
219impl<R, Response> Builder<R, Vec<Test<R, marker::Ok<Response>>>, marker::None> {
220 pub fn expect_request(
223 mut self,
224 request: R,
225 ) -> Builder<R, Vec<Test<R, marker::Ok<Response>>>, marker::Defined> {
226 self.tests.last_mut().unwrap().expected_input = Some(request);
227 Builder {
228 request: self.request,
229 tests: self.tests,
230 _request_state: marker::Defined,
231 }
232 }
233}
234
235impl<R, Error, RequestState> Builder<R, Vec<Test<R, marker::Err<Error>>>, RequestState> {
240 #[allow(clippy::type_complexity)]
243 pub fn send_response<Response>(
244 self,
245 response: Response,
246 ) -> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::None> {
247 let mut tests: Vec<_> = self
248 .tests
249 .into_iter()
250 .map(|test| Test {
251 output: Err(test.output.0),
252 expected_input: test.expected_input,
253 })
254 .collect();
255 tests.push(Test {
256 output: Ok(response),
257 expected_input: None,
258 });
259 Builder {
260 request: self.request,
261 tests,
262 _request_state: marker::None,
263 }
264 }
265
266 pub fn send_error(
268 mut self,
269 error: Error,
270 ) -> Builder<R, Vec<Test<R, marker::Err<Error>>>, marker::None> {
271 self.tests.push(Test {
272 output: marker::Err(error),
273 expected_input: None,
274 });
275 Builder {
276 request: self.request,
277 tests: self.tests,
278 _request_state: marker::None,
279 }
280 }
281}
282
283impl<R, Error, RequestState> Builder<R, Vec<Test<R, marker::Err<Error>>>, RequestState>
284where
285 R: Send + Sync + std::fmt::Debug + PartialEq,
286 Error: Send + Sync,
287{
288 pub async fn test<L>(
295 self,
296 layer: L,
297 ) -> ResponseTester<
298 <<L as Layer<crate::mock::Mock<R, (), Error>>>::Service as Service<R>>::Response,
299 <<L as Layer<crate::mock::Mock<R, (), Error>>>::Service as Service<R>>::Error,
300 >
301 where
302 L: Layer<crate::mock::Mock<R, (), Error>>,
303 L::Service: Service<R>,
304 {
305 let tests = self
306 .tests
307 .into_iter()
308 .map(|test| Test {
309 output: Err(test.output.0),
310 expected_input: test.expected_input,
311 })
312 .collect();
313 test_layer(layer, self.request, tests).await
314 }
315}
316
317impl<R, Error> Builder<R, Vec<Test<R, marker::Err<Error>>>, marker::None> {
318 pub fn expect_request(
321 mut self,
322 request: R,
323 ) -> Builder<R, Vec<Test<R, marker::Err<Error>>>, marker::Defined> {
324 self.tests.last_mut().unwrap().expected_input = Some(request);
325 Builder {
326 request: self.request,
327 tests: self.tests,
328 _request_state: marker::Defined,
329 }
330 }
331}
332
333impl<R, Response, Error, RequestState>
338 Builder<R, Vec<Test<R, Result<Response, Error>>>, RequestState>
339{
340 #[allow(clippy::type_complexity)]
342 pub fn send_response(
343 mut self,
344 response: Response,
345 ) -> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::None> {
346 self.tests.push(Test {
347 output: Ok(response),
348 expected_input: None,
349 });
350 Builder {
351 request: self.request,
352 tests: self.tests,
353 _request_state: marker::None,
354 }
355 }
356
357 #[allow(clippy::type_complexity)]
359 pub fn send_error(
360 mut self,
361 error: Error,
362 ) -> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::None> {
363 self.tests.push(Test {
364 output: Err(error),
365 expected_input: None,
366 });
367 Builder {
368 request: self.request,
369 tests: self.tests,
370 _request_state: marker::None,
371 }
372 }
373}
374
375impl<R, Response, Error, RequestState>
376 Builder<R, Vec<Test<R, Result<Response, Error>>>, RequestState>
377where
378 R: Send + Sync + std::fmt::Debug + PartialEq,
379 Response: Send + Sync,
380 Error: Send + Sync,
381{
382 pub async fn test<L>(
389 self,
390 layer: L,
391 ) -> ResponseTester<
392 <<L as Layer<crate::mock::Mock<R, Response, Error>>>::Service as Service<R>>::Response,
393 <<L as Layer<crate::mock::Mock<R, Response, Error>>>::Service as Service<R>>::Error,
394 >
395 where
396 L: Layer<crate::mock::Mock<R, Response, Error>>,
397 L::Service: Service<R>,
398 {
399 test_layer(layer, self.request, self.tests).await
400 }
401}
402
403#[allow(clippy::type_complexity)]
404impl<R, Response, Error> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::None> {
405 pub fn expect_request(
408 mut self,
409 request: R,
410 ) -> Builder<R, Vec<Test<R, Result<Response, Error>>>, marker::Defined> {
411 self.tests.last_mut().unwrap().expected_input = Some(request);
412 Builder {
413 request: self.request,
414 tests: self.tests,
415 _request_state: marker::Defined,
416 }
417 }
418}
419
420async fn test_layer<L, Request, Response, Error>(
425 layer: L,
426 request: Request,
427 tests: Vec<Test<Request, Result<Response, Error>>>,
428) -> ResponseTester<<<L as Layer<crate::mock::Mock<Request, Response, Error>>>::Service as Service<Request>>::Response, <<L as Layer<crate::mock::Mock<Request, Response, Error>>>::Service as Service<Request>>::Error>
429where
430 L: Layer<crate::mock::Mock<Request, Response, Error>>,
431 L::Service: Service<Request>,
432 Request: Send + Sync + std::fmt::Debug + PartialEq,
433 Response: Send + Sync,
434 Error: Send + Sync,
435{
436 let (service, handle) = crate::mock::spawn();
437
438 let layer = layer;
439 let service = layer.layer(service);
440
441 let (input_results, expected_inputs): (Vec<_>, Vec<_>) = tests
442 .into_iter()
443 .map(|test| (test.output, test.expected_input))
444 .unzip();
445
446 {
447 let mut handle = handle.lock().await;
448 for result in input_results {
449 handle.push_result(result);
450 }
451 }
452
453 let response = service.call(request).await;
454
455 {
456 let mut handle = handle.lock().await;
457 for expected_input in expected_inputs {
458 let request = handle.pop_request();
459 if let Some(expected_request) = expected_input {
460 assert_eq!(request, expected_request);
461 }
462 }
463 }
464
465 ResponseTester::new(response)
466}
467
468#[derive(Debug)]
474pub struct ResponseTester<Response, Error> {
475 result: Result<Response, Error>,
476}
477
478impl<Response, Error> ResponseTester<Response, Error> {
480 pub(crate) fn new(result: Result<Response, Error>) -> Self {
482 Self { result }
483 }
484}
485
486impl<Response, Error> ResponseTester<Response, Error>
487where
488 Response: PartialEq + std::fmt::Debug,
489 Error: std::fmt::Debug,
490{
491 pub fn expect_response(self, expected: Response) {
498 match self.result {
499 Ok(response) => assert_eq!(response, expected),
500 Err(err) => panic!("expected response, got error: {:?}", err),
501 }
502 }
503}
504
505impl<Response, Error> ResponseTester<Response, Error>
506where
507 Response: std::fmt::Debug,
508 Error: PartialEq + std::fmt::Debug,
509{
510 pub fn expect_error(self, expected: Error) {
517 match self.result {
518 Ok(response) => panic!("expected error, got response: {:?}", response),
519 Err(err) => assert_eq!(err, expected),
520 }
521 }
522}