cargo_fixture_macros/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::ToTokens;
5use syn::parse_macro_input;
6use types::{Args, TestFn, WrappedFn};
7
8mod types;
9
10macro_rules! tri {
11    ($what:expr) => {
12        match $what {
13            Ok(what) => what,
14            Err(err) => return proc_macro::TokenStream::from(err.to_compile_error()),
15        }
16    };
17}
18
19/// Annotate a test function as a fixture test.
20///
21/// The attribute marks the function with an appropriate `cfg` attribute to be `#[ignore]`d when the `_fixture` feature is not active,
22/// i.e. when not running under `cargo fixture`.
23/// It also wraps the function with a `TestClient` connection.
24///
25/// The function's signature must be:
26///
27/// ```rust
28/// async fn foo(client: TestClient)
29/// ```
30///
31/// `#[with_fixture]` must come _before_ attributes like `#[tokio::test]`.
32///
33/// ### Serial connection
34/// To have the `TestClient` connected with `serial` set to `true`, use the `serial` syntax:
35///
36/// ```rust
37/// #[with_fixture(serial)]
38/// ```
39///
40/// ## Example
41///
42/// ```
43/// #[with_fixture]
44/// #[tokio::test]
45/// async fn with_fixture_example(mut client: TestClient) {
46///     let example: Value = client.get_value("example").await.unwrap();
47/// }
48/// ```
49#[proc_macro_attribute]
50pub fn with_fixture(args: TokenStream, input: TokenStream) -> TokenStream {
51    let args = parse_macro_input!(args as Args);
52    let test_fn = parse_macro_input!(input as TestFn);
53    tri!(WrappedFn::wrap(test_fn, args))
54        .into_token_stream()
55        .into()
56}