1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (C) 2025-2026 Daniel Mueller <deso@posteo.net>
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//! The procedural macro powering `test-fork`.
use TokenStream;
use parse_macro_input;
use ItemFn;
use try_bench;
use try_fork;
use try_test;
/// A procedural macro for running a test in a separate process.
///
/// # Example
///
/// Use the attribute for all tests in scope:
/// ```rust,ignore
/// use test_fork::test;
///
/// #[test]
/// fn test1() {
/// assert_eq!(2 + 2, 4);
/// }
/// ```
///
/// Use it only on a single test:
/// ```rust,ignore
/// #[test_fork::test]
/// fn test2() {
/// assert_eq!(2 + 3, 5);
/// }
/// ```
/// A procedural macro for running a benchmark in a separate process.
///
/// # Example
///
/// Use the attribute for all benchmarks in scope:
/// ```rust,ignore
/// use test_fork::bench;
///
/// #[bench]
/// fn bench1(b: &mut Bencher) {
/// b.iter(|| sleep(Duration::from_millis(1)));
/// }
/// ```
///
/// Use it only on a single benchmark:
/// ```rust,ignore
/// #[test_fork::bench]
/// fn bench2(b: &mut Bencher) {
/// b.iter(|| sleep(Duration::from_millis(1)));
/// }
/// A procedural macro for running a test or benchmark in a separate
/// process.
///
/// This attribute is able to cater to both tests and benchmarks, while
/// #[[macro@test]] is specific to tests and #[[macro@bench]] to
/// benchmarks.
///
/// Contrary to both, this attribute does not in itself make a function
/// a test/benchmark, so it will *always* have to be combined with an
/// additional "inner" attribute. However, it can be more convenient for
/// annotating only a sub-set of tests/benchmarks for running in
/// separate processes, especially when non-standard attributes are
/// involved:
///
/// # Example
///
/// ```rust,ignore
/// use test_fork::fork;
///
/// #[fork]
/// #[test]
/// fn test3() {
/// assert_eq!(2 + 4, 6);
/// }
///
/// #[fork]
/// #[bench]
/// fn bench3(b: &mut Bencher) {
/// b.iter(|| sleep(Duration::from_millis(1)));
/// }
/// ```