Skip to main content

test_r_macro/
lib.rs

1mod deps;
2mod dynamic;
3mod helpers;
4mod hosted_rpc;
5mod suite;
6mod test;
7
8use proc_macro::TokenStream;
9
10#[proc_macro]
11pub fn uses_test_r(_item: TokenStream) -> TokenStream {
12    r#"
13        #[cfg(test)]
14        pub fn main() -> std::process::ExitCode {
15            test_r::core::test_runner()
16        }
17    "#
18    .parse()
19    .unwrap()
20}
21
22#[proc_macro_attribute]
23pub fn test(attr: TokenStream, item: TokenStream) -> TokenStream {
24    test::test_impl(attr, item, false)
25}
26
27#[proc_macro_attribute]
28pub fn bench(attr: TokenStream, item: TokenStream) -> TokenStream {
29    test::test_impl(attr, item, true)
30}
31
32#[proc_macro]
33pub fn inherit_test_dep(item: TokenStream) -> TokenStream {
34    deps::inherit_test_dep(item)
35}
36
37#[proc_macro]
38pub fn define_matrix_dimension(item: TokenStream) -> TokenStream {
39    deps::define_matrix_dimension(item)
40}
41
42#[proc_macro_attribute]
43pub fn test_dep(attr: TokenStream, item: TokenStream) -> TokenStream {
44    deps::test_dep(attr, item)
45}
46
47#[proc_macro_attribute]
48pub fn test_gen(_attr: TokenStream, item: TokenStream) -> TokenStream {
49    dynamic::test_gen(item)
50}
51
52#[proc_macro]
53pub fn add_test(input: TokenStream) -> TokenStream {
54    dynamic::add_test(input)
55}
56
57#[proc_macro_attribute]
58pub fn timeout(attr: TokenStream, item: TokenStream) -> TokenStream {
59    suite::timeout(attr, item)
60}
61
62#[proc_macro]
63pub fn timeout_suite(input: TokenStream) -> TokenStream {
64    suite::timeout_suite(input)
65}
66
67#[proc_macro_attribute]
68pub fn flaky(_attr: TokenStream, item: TokenStream) -> TokenStream {
69    item
70}
71
72#[proc_macro_attribute]
73pub fn non_flaky(_attr: TokenStream, item: TokenStream) -> TokenStream {
74    item
75}
76
77#[proc_macro_attribute]
78pub fn always_capture(_attr: TokenStream, item: TokenStream) -> TokenStream {
79    item
80}
81
82#[proc_macro_attribute]
83pub fn never_capture(_attr: TokenStream, item: TokenStream) -> TokenStream {
84    item
85}
86
87#[proc_macro_attribute]
88pub fn always_report_time(_attr: TokenStream, item: TokenStream) -> TokenStream {
89    item
90}
91
92#[proc_macro_attribute]
93pub fn never_report_time(_attr: TokenStream, item: TokenStream) -> TokenStream {
94    item
95}
96
97#[proc_macro_attribute]
98pub fn always_ensure_time(_attr: TokenStream, item: TokenStream) -> TokenStream {
99    item
100}
101
102#[proc_macro_attribute]
103pub fn never_ensure_time(_attr: TokenStream, item: TokenStream) -> TokenStream {
104    item
105}
106
107#[proc_macro_attribute]
108pub fn ignore_detached_panics(_attr: TokenStream, item: TokenStream) -> TokenStream {
109    item
110}
111
112#[proc_macro_attribute]
113pub fn tag(attr: TokenStream, item: TokenStream) -> TokenStream {
114    suite::tag(attr, item)
115}
116
117#[proc_macro]
118pub fn tag_suite(input: TokenStream) -> TokenStream {
119    suite::tag_suite(input)
120}
121
122/// `matrix_suite!(<module>, <dim>, <DepType>)` — apply a previously-defined
123/// matrix dimension to every `#[test]` in the named module.
124///
125/// Unlike `tag_suite!` / `sequential_suite!` (which are pure runtime suite
126/// properties applied to already-registered tests), `matrix_suite!` works by
127/// **runtime test multiplication** (Strategy B): at test-collection time, each
128/// registered test under `<module>` whose `dependencies` contain the untagged
129/// `<DepType>` dep name is duplicated into one test per case of the `<dim>`
130/// dimension. The multiplied cases are named `<test>_<case>`, carry the
131/// `<dim>_<case>` auto-tag (selectable via `:tag:`), and have their dependency
132/// rewritten to the case-specific tagged dep, with the test closure's
133/// compiled getter redirected to that tagged dep via an aliased
134/// `DependencyView`.
135///
136/// Because multiplication happens at runtime over already-registered tests,
137/// `<module>` may be a **file-based module** (`mod worker;`) or a directory
138/// module (`mod api;` with `api/mod.rs`), not just an inline module. This is
139/// the key difference from the earlier compile-time attribute form, which
140/// required an inline module body to rewrite test signatures.
141///
142/// Tests in the module that do not depend on `<DepType>` (or that already
143/// carry an explicit `#[dimension]` / `#[tagged_as]` for that dep) are left
144/// untouched and run exactly once.
145///
146/// `matrix_suite!` must be invoked in a scope where the
147/// `test_r_get_dep_tags_<dim>()` helper emitted by `define_matrix_dimension!`
148/// is in scope (typically the same parent module that declared the dimension).
149///
150/// See `book/src/advanced_features/dependency_injection.md` for the worked
151/// example and the rationale for the runtime-multiplication (Strategy B)
152/// approach.
153#[proc_macro]
154pub fn matrix_suite(item: TokenStream) -> TokenStream {
155    suite::matrix_suite(item)
156}
157
158#[proc_macro_attribute]
159pub fn sequential(_attr: TokenStream, item: TokenStream) -> TokenStream {
160    suite::sequential(item)
161}
162
163#[proc_macro]
164pub fn sequential_suite(input: TokenStream) -> TokenStream {
165    suite::sequential_suite(input)
166}
167
168/// HR1.1: trait-driven boilerplate eliminator for `HostedRpcDep` /
169/// `AsyncHostedRpcDep`.
170///
171/// Apply to a user trait declaration to emit a `<Trait>Stub` worker-side
172/// struct that implements the trait by routing each call through a
173/// [`test_r::core::HostedRpcChannel`], plus a `<Trait>Dispatch` helper
174/// trait blanket-implemented for every `T: Trait` so the owner-side
175/// dispatch impl can delegate to a generated method-table dispatcher
176/// instead of writing the per-method match arms by hand.
177///
178/// Async-mode is auto-detected: if every method in the trait is declared
179/// `async fn`, the macro generates async stub methods and an async
180/// dispatch helper, and the owner is expected to implement
181/// [`test_r::core::AsyncHostedRpcDep`] instead of
182/// [`test_r::core::HostedRpcDep`]. Mixing sync and `async fn` methods in
183/// the same `#[hosted_rpc]` trait is a compile error. There is no
184/// `#[hosted_rpc(async)]` flag.
185///
186/// See the rustdoc on the macro module for the precise wire format and
187/// the remaining restrictions (no generics, no associated types).
188#[proc_macro_attribute]
189pub fn hosted_rpc(attr: TokenStream, item: TokenStream) -> TokenStream {
190    hosted_rpc::hosted_rpc(attr, item)
191}