Skip to main content

miden_test_utils/
test_builders.rs

1// MACROS TO BUILD TESTS
2// ================================================================================================
3
4/// Returns a Test struct in non debug mode from a string of one or more operations and any
5/// specified stack and advice inputs.
6///
7/// Parameters are expected in the following order:
8/// `source`, `stack_inputs` (optional), `advice_stack` (optional), `merkle_store` (optional)
9///
10/// * `source`: a string of one or more operations, e.g. "push.1 push.2".
11/// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before
12///   executing the `source`. Stack inputs can be provided independently without any advice inputs.
13/// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and
14///   `merkle_store` are also expected.
15/// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and
16///   `advice_stack` are also expected.
17#[macro_export]
18macro_rules! build_op_test {
19    ($op_str:expr) => {{
20        let source = format!("
21proc.truncate_stack.4
22    loc_storew.0 dropw movupw.3
23    sdepth neq.16
24    while.true
25        dropw movupw.3
26        sdepth neq.16
27    end
28    loc_loadw.0
29end
30
31begin {} exec.truncate_stack end",
32            $op_str
33        );
34        $crate::build_test!(&source)
35    }};
36    ($op_str:expr, $($tail:tt)+) => {{
37        let source = format!("
38proc.truncate_stack.4
39    loc_storew.0 dropw movupw.3
40    sdepth neq.16
41    while.true
42        dropw movupw.3
43        sdepth neq.16
44    end
45    loc_loadw.0
46end
47
48begin {} exec.truncate_stack end",
49            $op_str
50        );
51        $crate::build_test!(&source, $($tail)+)
52    }};
53}
54
55/// Returns a Test struct in non debug mode from the provided source string, and any specified
56/// stack and advice inputs.
57///
58/// Parameters are expected in the following order:
59/// `source`, `stack_inputs` (optional), `advice_stack` (optional), `merkle_store` (optional)
60///
61/// * `source`: a well-formed source string.
62/// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before
63///   executing the `source`. Stack inputs can be provided independently without any advice inputs.
64/// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and
65///   `merkle_store` are also expected.
66/// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and
67///   `advice_stack` are also expected.
68#[macro_export]
69macro_rules! build_test {
70    ($($params:tt)+) => {{
71        $crate::build_test_by_mode!(false, $($params)+)
72    }}
73}
74
75/// Returns a Test struct in debug mode from the provided source string and any specified stack
76/// and advice inputs.
77///
78/// Parameters are expected in the following order:
79/// `source`, `stack_inputs` (optional), `advice_stack` (optional), `merkle_store` (optional)
80///
81/// * `source`: a well-formed source string.
82/// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before
83///   executing the `source`. Stack inputs can be provided independently without any advice inputs.
84/// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and
85///   `merkle_store` are also expected.
86/// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and
87///   `advice_stack` are also expected.
88///
89/// NOTE: use `miden_stdlib::tests::build_debug_test` to include the standard library in the test.
90#[macro_export]
91macro_rules! build_debug_test {
92    ($($params:tt)+) => {{
93        $crate::build_test_by_mode!(true, $($params)+)
94    }}
95}
96
97/// Returns a Test struct in the specified debug or non-debug mode using the provided source string
98/// and any specified stack and advice inputs.
99///
100/// Parameters start with a boolean flag, `in_debug_mode`, specifying whether the test is built in
101/// debug or non-debug mode. After that, they match the parameters of `build_test` and
102///`build_debug_test` macros.
103///
104/// This macro is an internal test builder, and is not intended to be called directly from tests.
105/// Instead, the build_test and build_debug_test wrappers should be used.
106#[macro_export]
107macro_rules! build_test_by_mode {
108    ($in_debug_mode:expr, $source:expr) => {{
109        let name = format!("test{}", line!());
110        $crate::Test::new(&name, $source, $in_debug_mode)
111    }};
112    ($in_debug_mode:expr, $source:expr, $stack_inputs:expr) => {{
113        use ::assembly::SourceManager;
114
115        let stack_inputs: Vec<u64> = $stack_inputs.to_vec();
116        let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap();
117        let advice_inputs = $crate::AdviceInputs::default();
118        let name = format!("test{}", line!());
119        let source_manager = ::alloc::sync::Arc::new(::assembly::DefaultSourceManager::default());
120        let source = source_manager.load(&name, ::alloc::string::String::from($source));
121
122        $crate::Test {
123            source_manager,
124            source,
125            kernel_source: None,
126            stack_inputs,
127            advice_inputs,
128            in_debug_mode: $in_debug_mode,
129            libraries: Vec::default(),
130            add_modules: Vec::default(),
131        }
132    }};
133    ($in_debug_mode:expr, $source:expr, $stack_inputs:expr, $advice_stack:expr) => {{
134        use ::assembly::SourceManager;
135
136        let stack_inputs: Vec<u64> = $stack_inputs.to_vec();
137        let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap();
138        let stack_values: Vec<u64> = $advice_stack.to_vec();
139        let store = $crate::crypto::MerkleStore::new();
140        let advice_inputs = $crate::AdviceInputs::default()
141            .with_stack_values(stack_values)
142            .unwrap()
143            .with_merkle_store(store);
144        let name = format!("test{}", line!());
145        let source_manager = ::alloc::sync::Arc::new(::assembly::DefaultSourceManager::default());
146        let source = source_manager.load(&name, ::alloc::string::String::from($source));
147
148        $crate::Test {
149            source_manager,
150            source,
151            kernel_source: None,
152            stack_inputs,
153            advice_inputs,
154            in_debug_mode: $in_debug_mode,
155            libraries: Vec::default(),
156            add_modules: Vec::default(),
157        }
158    }};
159    (
160        $in_debug_mode:expr,
161        $source:expr,
162        $stack_inputs:expr,
163        $advice_stack:expr,
164        $advice_merkle_store:expr
165    ) => {{
166        use ::assembly::SourceManager;
167
168        let stack_inputs: Vec<u64> = $stack_inputs.to_vec();
169        let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap();
170        let stack_values: Vec<u64> = $advice_stack.to_vec();
171        let advice_inputs = $crate::AdviceInputs::default()
172            .with_stack_values(stack_values)
173            .unwrap()
174            .with_merkle_store($advice_merkle_store);
175        let name = format!("test{}", line!());
176        let source_manager = ::alloc::sync::Arc::new(::assembly::DefaultSourceManager::default());
177        let source = source_manager.load(&name, ::alloc::string::String::from($source));
178
179        $crate::Test {
180            source_manager,
181            source,
182            kernel_source: None,
183            stack_inputs,
184            advice_inputs,
185            in_debug_mode: $in_debug_mode,
186            libraries: Vec::default(),
187            add_modules: Vec::default(),
188        }
189    }};
190    (
191        $in_debug_mode:expr,
192        $source:expr,
193        $stack_inputs:expr,
194        $advice_stack:expr,
195        $advice_merkle_store:expr,
196        $advice_map:expr
197    ) => {{
198        use ::assembly::SourceManager;
199
200        let stack_inputs: Vec<u64> = $stack_inputs.to_vec();
201        let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap();
202        let stack_values: Vec<u64> = $advice_stack.to_vec();
203        let advice_inputs = $crate::AdviceInputs::default()
204            .with_stack_values(stack_values)
205            .unwrap()
206            .with_merkle_store($advice_merkle_store)
207            .with_map($advice_map);
208        let name = format!("test{}", line!());
209        let source_manager = ::alloc::sync::Arc::new(::assembly::DefaultSourceManager::default());
210        let source = source_manager.load(&name, ::alloc::string::String::from($source));
211
212        $crate::Test {
213            source_manager,
214            source,
215            kernel_source: None,
216            stack_inputs,
217            advice_inputs,
218            in_debug_mode: $in_debug_mode,
219            libraries: Vec::default(),
220            add_modules: Vec::default(),
221        }
222    }};
223}