test_context/lib.rs
1#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
2
3// Reimported to allow for use in the macro.
4pub use futures;
5
6pub use test_context_macros::test_context;
7
8/// The trait to implement to get setup/teardown functionality for tests.
9pub trait TestContext
10where
11 Self: Sized,
12{
13 /// Create the context. This is run once before each test that uses the context.
14 fn setup() -> Self;
15
16 /// Perform any additional cleanup of the context besides that already provided by
17 /// normal "drop" semantics.
18 fn teardown(self) {}
19}
20
21/// The trait to implement to get setup/teardown functionality for async tests.
22pub trait AsyncTestContext
23where
24 Self: Sized,
25{
26 /// Create the context. This is run once before each test that uses the context.
27 fn setup() -> impl std::future::Future<Output = Self> + Send;
28
29 /// Perform any additional cleanup of the context besides that already provided by
30 /// normal "drop" semantics.
31 fn teardown(self) -> impl std::future::Future<Output = ()> + Send {
32 async {}
33 }
34}
35
36// Automatically impl TestContext for anything Send that impls AsyncTestContext.
37//
38// A future improvement may be to use feature flags to enable using a specific runtime
39// to run the future synchronously. This is the easiest way to implement it, though, and
40// introduces no new dependencies.
41impl<T> TestContext for T
42where
43 T: AsyncTestContext + Send,
44{
45 fn setup() -> Self {
46 futures::executor::block_on(<T as AsyncTestContext>::setup())
47 }
48
49 fn teardown(self) {
50 futures::executor::block_on(<T as AsyncTestContext>::teardown(self))
51 }
52}