stubr_attributes/
lib.rs

1#![doc = include_str ! ("../README.md")]
2
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6
7mod apps;
8mod mock;
9mod record;
10
11/// Starts a Stubr mock server and creates a `stubr` variable which can be used to call the server e.g. `stubr.uri()`.
12/// It supports both standard and async test functions.
13///
14/// # Example
15/// ```no_run
16/// # use isahc;
17/// # use stubr_attributes as stubr;
18/// use asserhttp::*; // optional
19///
20/// #[test]
21/// #[stubr::mock] // <- takes stubs under crate's "tests/stubs" by default
22/// #[should_panic] // <- if required place it after '#[stubr::mock]' to avoid unused warnings
23/// fn simple_test() {
24///     isahc::get(stubr.uri()).expect_status_ok();
25/// }
26///
27/// // also works for async functions
28/// #[async_std::test]
29/// #[stubr::mock]
30/// async fn async_test() {
31///     isahc::get(stubr.uri()).await.expect_status_ok();
32/// }
33/// ```
34///
35/// # Configuration
36/// ```no_run
37/// # use stubr_attributes as stubr;
38///
39/// // path to stub file (or directory) under crate's "tests/stubs"
40/// #[test]
41/// #[stubr::mock("path/to/stubs")] // <- or "path/to/stubs/stub.json" for a single file
42/// fn default() {}
43///
44/// // absolute path ; not appending to "tests/stubs"
45/// #[test]
46/// #[stubr::mock(full_path = "tests/other/stubs")]
47/// fn full_path() {}
48///
49/// // start on a dedicated port
50/// #[test]
51/// #[stubr::mock(port = 1234)]
52/// fn port() {}
53/// ```
54#[proc_macro_attribute]
55pub fn mock(args: TokenStream, item: TokenStream) -> TokenStream {
56    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
57    mock::mock_transform(args, item.into()).unwrap().into()
58}
59
60/// Starts a Stubr recorder server and creates a `recorder` variable which can be used to call the server e.g. `stubr.isahc_client()`.
61///
62/// # Example
63/// ```no_run
64/// # use isahc;
65/// # use stubr_attributes as stubr;
66/// use asserhttp::*; // optional
67///
68/// #[test]
69/// #[stubr::mock] // <- start a server to record, stubr itself for example
70/// #[stubr::record] // <- spawns a recorder in a tokio runtime
71/// fn simple_test() {
72///     recorder.isahc_client().get(stubr.uri()).expect_status_ok();
73///     // a recorded stub has been created under 'target/stubs'
74/// }
75///
76/// // Works for async too
77/// #[stubr::record] // <- spawns a recorder in a tokio runtime
78/// #[stubr::mock] // <- start a server to record, stubr itself for example
79/// #[test]
80/// async fn async_simple_test() {
81///     recorder.isahc_client().get_async(stubr.uri()).await.expect_status_ok();
82/// }
83/// ```
84///
85/// # Configuration
86/// ```no_run
87/// # use stubr_attributes as stubr;
88///
89/// // start recorder on a dedicated port
90/// #[test]
91/// #[stubr::record(port = 1234)]
92/// fn port() {}
93/// ```
94#[proc_macro_attribute]
95pub fn record(args: TokenStream, item: TokenStream) -> TokenStream {
96    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
97    record::record_transform(args, item.into()).unwrap().into()
98}
99
100/// Starts a Stubr server for each remote app name supplied.
101///
102/// # Example
103/// ```no_run
104/// # use isahc;
105/// # use stubr_attributes as stubr;
106/// use asserhttp::*; // optional
107///
108/// #[test]
109/// #[stubr::apps("producer-a", "producer-b")] // <- start a server for each app
110/// fn using_producers() {
111///     // a binding is created for each app supplied with the name of the app
112///     isahc::get(producer_a.uri()).expect_status_ok();
113///     isahc::get(producer_b.uri()).expect_status_ok();
114/// }
115/// ```
116#[proc_macro_attribute]
117pub fn apps(args: TokenStream, item: TokenStream) -> TokenStream {
118    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
119    apps::apps_transform(args, item.into()).unwrap().into()
120}