Skip to main content

trillium_testing/
with_server.rs

1use crate::{ServerConnector, block_on, config};
2use std::{error::Error, future::Future};
3use trillium::{Handler, Transport};
4use trillium_server_common::RuntimeTrait;
5use url::Url;
6
7/// Starts a trillium handler bound to a random available port on
8/// localhost, run the async tests provided as the second
9/// argument, and then shut down the server. useful for full
10/// integration tests that actually exercise the tcp layer.
11///
12/// See
13/// [`trillium_client::Conn`](https://docs.trillium.rs/trillium_client/struct.conn)
14/// for usage examples.
15pub fn with_server<H, Fun, Fut>(handler: H, tests: Fun)
16where
17    H: Handler,
18    Fun: FnOnce(Url) -> Fut,
19    Fut: Future<Output = Result<(), Box<dyn Error>>>,
20{
21    let config = config().with_host("localhost").with_port(0);
22    let runtime = config.runtime();
23    runtime.block_on(async move {
24        let handle = config.spawn(handler);
25        let info = handle.info().await;
26        let url = info.shared_state().cloned().unwrap_or_else(|| {
27            let port = info.tcp_socket_addr().map(|t| t.port()).unwrap_or(0);
28            format!("http://localhost:{port}").parse().unwrap()
29        });
30        tests(url).await.unwrap();
31        handle.shut_down().await;
32    });
33}
34
35/// open an in-memory connection to this handler and call an async
36/// function with an open `Box<dyn Transport>`
37pub fn with_transport<H, Fun, Fut>(handler: H, tests: Fun)
38where
39    H: Handler,
40    Fun: FnOnce(Box<dyn Transport>) -> Fut,
41    Fut: Future<Output = Result<(), Box<dyn Error>>>,
42{
43    block_on(async move {
44        let transport = ServerConnector::new(handler).connect(false).await;
45        tests(Box::new(transport));
46    });
47}