foundry_test_utils/
macros.rs

1/// A macro to generate a new integration test case
2///
3/// The `forgetest!` macro's first argument is the name of the test, the second argument is a
4/// closure to configure and execute the test. The `TestProject` provides utility functions to setup
5/// the project's workspace. The `TestCommand` is a wrapper around the actual `forge` executable
6/// that this then executed with the configured command arguments.
7///
8/// # Example
9///
10/// run `forge init`
11///
12/// ```no_run
13/// use foundry_test_utils::*;
14/// forgetest!(my_test, |prj, cmd| {
15///     // adds `init` to forge's command arguments
16///     cmd.arg("init");
17///     // executes forge <args> and panics if the command failed or output is empty
18///     cmd.assert_success().stdout_eq(str![[r#""#]]);
19/// });
20/// ```
21///
22/// Configure a hardhat project layout by adding a `PathStyle::HardHat` argument
23///
24/// ```no_run
25/// use foundry_test_utils::*;
26/// use foundry_test_utils::foundry_compilers::PathStyle;
27/// forgetest!(can_clean_hardhat, PathStyle::HardHat, |prj, cmd| {
28///     prj.assert_create_dirs_exists();
29///     prj.assert_style_paths_exist(PathStyle::HardHat);
30///     cmd.arg("clean");
31///     cmd.assert_empty_stdout();
32///     prj.assert_cleaned();
33/// });
34#[macro_export]
35macro_rules! forgetest {
36    ($(#[$attr:meta])* $test:ident, |$prj:ident, $cmd:ident| $e:expr) => {
37        $crate::forgetest!($(#[$attr])* $test, $crate::foundry_compilers::PathStyle::Dapptools, |$prj, $cmd| $e);
38    };
39    ($(#[$attr:meta])* $test:ident, $style:expr, |$prj:ident, $cmd:ident| $e:expr) => {
40        #[expect(clippy::disallowed_macros)]
41        #[test]
42        $(#[$attr])*
43        fn $test() {
44            let (mut $prj, mut $cmd) = $crate::util::setup_forge(stringify!($test), $style);
45            $e
46        }
47    };
48}
49
50#[macro_export]
51macro_rules! forgetest_async {
52    ($(#[$attr:meta])* $test:ident, |$prj:ident, $cmd:ident| $e:expr) => {
53        $crate::forgetest_async!($(#[$attr])* $test, $crate::foundry_compilers::PathStyle::Dapptools, |$prj, $cmd| $e);
54    };
55    ($(#[$attr:meta])* $test:ident, $style:expr, |$prj:ident, $cmd:ident| $e:expr) => {
56        #[expect(clippy::disallowed_macros)]
57        #[tokio::test(flavor = "multi_thread")]
58        $(#[$attr])*
59        async fn $test() {
60            let (mut $prj, mut $cmd) = $crate::util::setup_forge(stringify!($test), $style);
61            $e
62        }
63    };
64}
65
66#[macro_export]
67macro_rules! casttest {
68    ($(#[$attr:meta])* $test:ident, $($async:ident)? |$prj:ident, $cmd:ident| $e:expr) => {
69        $crate::casttest!($(#[$attr])* $test, $crate::foundry_compilers::PathStyle::Dapptools, $($async)? |$prj, $cmd| $e);
70    };
71    ($(#[$attr:meta])* $test:ident, $style:expr, |$prj:ident, $cmd:ident| $e:expr) => {
72        #[expect(clippy::disallowed_macros)]
73        #[test]
74        $(#[$attr])*
75        fn $test() {
76            let (mut $prj, mut $cmd) = $crate::util::setup_cast(stringify!($test), $style);
77            $e
78        }
79    };
80    ($(#[$attr:meta])* $test:ident, $style:expr, async |$prj:ident, $cmd:ident| $e:expr) => {
81        #[expect(clippy::disallowed_macros)]
82        #[tokio::test(flavor = "multi_thread")]
83        $(#[$attr])*
84        async fn $test() {
85            let (mut $prj, mut $cmd) = $crate::util::setup_cast(stringify!($test), $style);
86            $e
87        }
88    };
89}
90
91/// Same as `forgetest` but returns an already initialized project workspace (`forge init`)
92#[macro_export]
93macro_rules! forgetest_init {
94    ($(#[$attr:meta])* $test:ident, |$prj:ident, $cmd:ident| $e:expr) => {
95        $crate::forgetest_init!($(#[$attr])* $test, $crate::foundry_compilers::PathStyle::Dapptools, |$prj, $cmd| $e);
96    };
97    ($(#[$attr:meta])* $test:ident, $style:expr, |$prj:ident, $cmd:ident| $e:expr) => {
98        #[test]
99        $(#[$attr])*
100        fn $test() {
101            let (mut $prj, mut $cmd) = $crate::util::setup_forge(stringify!($test), $style);
102            $crate::util::initialize($prj.root());
103            $e
104        }
105    };
106}
107
108/// Setup forge soldeer
109#[macro_export]
110macro_rules! forgesoldeer {
111    ($(#[$attr:meta])* $test:ident, |$prj:ident, $cmd:ident| $e:expr) => {
112        $crate::forgesoldeer!($(#[$attr])* $test, $crate::foundry_compilers::PathStyle::Dapptools, |$prj, $cmd| $e);
113    };
114    ($(#[$attr:meta])* $test:ident, $style:expr, |$prj:ident, $cmd:ident| $e:expr) => {
115        #[expect(clippy::disallowed_macros)]
116        #[test]
117        $(#[$attr])*
118        fn $test() {
119            let (mut $prj, mut $cmd) = $crate::util::setup_forge(stringify!($test), $style);
120            $crate::util::initialize($prj.root());
121            $e
122        }
123    };
124}