proptest/
sugar.rs

1//-
2// Copyright 2017, 2019 The proptest developers
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10use crate::std_facade::fmt;
11
12/// Easily define `proptest` tests.
13///
14/// Within `proptest!`, define one or more functions without return type
15/// normally, except instead of putting `: type` after each parameter, write
16/// `in strategy`, where `strategy` is an expression evaluating to some
17/// `Strategy`.
18///
19/// Each function will be wrapped in a function which sets up a `TestRunner`,
20/// and then invokes the function body with inputs generated according to the
21/// strategies.
22///
23/// ### Example
24///
25/// ```
26/// use proptest::prelude::*;
27///
28/// proptest! {
29///   # /*
30///   #[test]
31///   # */
32///   fn test_addition(a in 0..10, b in 0..10) {
33///     prop_assert!(a + b <= 18);
34///   }
35///
36///   # /*
37///   #[test]
38///   # */
39///   fn test_string_concat(a in ".*", b in ".*") {
40///     let cat = format!("{}{}", a, b);
41///     prop_assert_eq!(a.len() + b.len(), cat.len());
42///   }
43/// }
44/// #
45/// # fn main() { test_addition(); test_string_concat(); }
46/// ```
47///
48/// You can also use the normal argument syntax `pattern: type` as in:
49///
50/// ```rust
51/// use proptest::prelude::*;
52///
53/// proptest! {
54///   # /*
55///   #[test]
56///   # */
57///   fn addition_is_commutative(a: u8, b: u8) {
58///     prop_assert_eq!(a as u16 + b as u16, b as u16 + a as u16);
59///   }
60///
61///   # /*
62///   #[test]
63///   # */
64///   fn test_string_concat(a in ".*", b: String) {
65///     let cat = format!("{}{}", a, b);
66///     prop_assert_eq!(a.len() + b.len(), cat.len());
67///   }
68/// }
69/// #
70/// # fn main() { addition_is_commutative(); test_string_concat(); }
71/// ```
72///
73/// As you can see, you can mix `pattern: type` and `pattern in expr`.
74/// Due to limitations in `macro_rules!`, `pattern: type` does not work in
75/// all circumstances. In such a case, use `(pattern): type` instead.
76///
77/// To override the default configuration, you can start the `proptest!` block
78/// with `#![proptest_config(expr)]`, where `expr` is an expression that
79/// evaluates to a `proptest::test_runner::Config` (or a reference to one).
80///
81/// ```
82/// use proptest::prelude::*;
83///
84/// proptest! {
85///   #![proptest_config(ProptestConfig {
86///     cases: 99, .. ProptestConfig::default()
87///   })]
88///   # /*
89///   #[test]
90///   # */
91///   fn test_addition(a in 0..10, b in 0..10) {
92///     prop_assert!(a + b <= 18);
93///   }
94/// }
95/// #
96/// # fn main() { test_addition(); }
97/// ```
98///
99/// ## Closure-Style Invocation
100///
101/// As of proptest 0.8.1, an alternative, "closure-style" invocation is
102/// supported. In this form, `proptest!` is a function-like macro taking a
103/// closure-esque argument. This makes it possible to run multiple tests that
104/// require some expensive setup process. Note that the "fork" and "timeout"
105/// features are _not_ supported in closure style.
106///
107/// To use a custom configuration, pass the `Config` object as a first
108/// argument.
109///
110/// ### Example
111///
112/// ```
113/// use proptest::prelude::*;
114///
115/// #[derive(Debug)]
116/// struct BigStruct { /* Lots of fields ... */ }
117///
118/// fn very_expensive_function() -> BigStruct {
119///   // Lots of code...
120///   BigStruct { /* fields */ }
121/// }
122///
123/// # /*
124/// #[test]
125/// # */
126/// fn my_test() {
127///   // We create just one `BigStruct`
128///   let big_struct = very_expensive_function();
129///
130///   // But now can run multiple tests without needing to build it every time.
131///   // Note the extra parentheses around the arguments are currently
132///   // required.
133///   proptest!(|(x in 0u32..42u32, y in 1000u32..100000u32)| {
134///     // Test stuff
135///   });
136///
137///   // `move` closures are also supported
138///   proptest!(move |(x in 0u32..42u32)| {
139///     // Test other stuff
140///   });
141///
142///   // You can pass a custom configuration as the first argument
143///   proptest!(ProptestConfig::with_cases(1000), |(x: i32)| {
144///     // Test more stuff
145///   });
146/// }
147/// #
148/// # fn main() { my_test(); }
149/// ```
150#[macro_export]
151macro_rules! proptest {
152    (#![proptest_config($config:expr)]
153     $(
154        $(#[$meta:meta])*
155       fn $test_name:ident($($parm:pat in $strategy:expr),+ $(,)?) $body:block
156    )*) => {
157        $(
158            $(#[$meta])*
159            fn $test_name() {
160                let mut config = $crate::test_runner::contextualize_config($config.clone());
161                config.test_name = ::core::option::Option::Some(
162                    ::core::concat!(::core::module_path!(), "::", ::core::stringify!($test_name)));
163                $crate::proptest_helper!(@_BODY config ($($parm in $strategy),+) [] $body);
164            }
165        )*
166    };
167    (#![proptest_config($config:expr)]
168     $(
169        $(#[$meta:meta])*
170        fn $test_name:ident($($arg:tt)+) $body:block
171    )*) => {
172        $(
173            $(#[$meta])*
174            fn $test_name() {
175                let mut config = $crate::test_runner::contextualize_config($config.clone());
176                config.test_name = ::core::option::Option::Some(
177                    ::core::concat!(::core::module_path!(), "::", ::core::stringify!($test_name)));
178                $crate::proptest_helper!(@_BODY2 config ($($arg)+) [] $body);
179            }
180        )*
181    };
182
183    ($(
184        $(#[$meta:meta])*
185        fn $test_name:ident($($parm:pat in $strategy:expr),+ $(,)?) $body:block
186    )*) => { $crate::proptest! {
187        #![proptest_config($crate::test_runner::Config::default())]
188        $($(#[$meta])*
189          fn $test_name($($parm in $strategy),+) $body)*
190    } };
191
192    ($(
193        $(#[$meta:meta])*
194        fn $test_name:ident($($arg:tt)+) $body:block
195    )*) => { $crate::proptest! {
196        #![proptest_config($crate::test_runner::Config::default())]
197        $($(#[$meta])*
198          fn $test_name($($arg)+) $body)*
199    } };
200
201    (|($($parm:pat in $strategy:expr),+ $(,)?)| $body:expr) => {
202        $crate::proptest!(
203            $crate::test_runner::Config::default(),
204            |($($parm in $strategy),+)| $body)
205    };
206
207    (move |($($parm:pat in $strategy:expr),+ $(,)?)| $body:expr) => {
208        $crate::proptest!(
209            $crate::test_runner::Config::default(),
210            move |($($parm in $strategy),+)| $body)
211    };
212
213    (|($($arg:tt)+)| $body:expr) => {
214        $crate::proptest!(
215            $crate::test_runner::Config::default(),
216            |($($arg)+)| $body)
217    };
218
219    (move |($($arg:tt)+)| $body:expr) => {
220        $crate::proptest!(
221            $crate::test_runner::Config::default(),
222            move |($($arg)+)| $body)
223    };
224
225    ($config:expr, |($($parm:pat in $strategy:expr),+ $(,)?)| $body:expr) => { {
226        let mut config = $crate::test_runner::contextualize_config($config.__sugar_to_owned());
227        $crate::sugar::force_no_fork(&mut config);
228        $crate::proptest_helper!(@_BODY config ($($parm in $strategy),+) [] $body)
229    } };
230
231    ($config:expr, move |($($parm:pat in $strategy:expr),+ $(,)?)| $body:expr) => { {
232        let mut config = $crate::test_runner::contextualize_config($config.__sugar_to_owned());
233        $crate::sugar::force_no_fork(&mut config);
234        $crate::proptest_helper!(@_BODY config ($($parm in $strategy),+) [move] $body)
235    } };
236
237    ($config:expr, |($($arg:tt)+)| $body:expr) => { {
238        let mut config = $crate::test_runner::contextualize_config($config.__sugar_to_owned());
239        $crate::sugar::force_no_fork(&mut config);
240        $crate::proptest_helper!(@_BODY2 config ($($arg)+) [] $body);
241    } };
242
243    ($config:expr, move |($($arg:tt)+)| $body:expr) => { {
244        let mut config = $crate::test_runner::contextualize_config($config.__sugar_to_owned());
245        $crate::sugar::force_no_fork(&mut config);
246        $crate::proptest_helper!(@_BODY2 config ($($arg)+) [move] $body);
247    } };
248}
249
250/// Rejects the test input if assumptions are not met.
251///
252/// Used directly within a function defined with `proptest!` or in any function
253/// returning `Result<_, TestCaseError>`.
254///
255/// This is invoked as `prop_assume!(condition, format, args...)`. `condition`
256/// is evaluated; if it is false, `Err(TestCaseError::Reject)` is returned. The
257/// message includes the point of invocation and the format message. `format`
258/// and `args` may be omitted to simply use the condition itself as the
259/// message.
260#[macro_export]
261macro_rules! prop_assume {
262    ($expr:expr) => {
263        $crate::prop_assume!($expr, "{}", ::core::stringify!($expr))
264    };
265
266    ($expr:expr, $fmt:tt $(, $fmt_arg:expr),* $(,)?) => {
267        if !$expr {
268            extern crate alloc;
269            return ::core::result::Result::Err(
270                $crate::test_runner::TestCaseError::reject(
271                    alloc::format!(::core::concat!("{}:{}:{}: ", $fmt),
272                            ::core::file!(), ::core::line!(), ::core::column!()
273                            $(, $fmt_arg)*)));
274        }
275    };
276}
277
278/// Produce a strategy which picks one of the listed choices.
279///
280/// This is conceptually equivalent to calling `prop_union` on the first two
281/// elements and then chaining `.or()` onto the rest after implicitly boxing
282/// all of them. As with `Union`, values shrink across elements on the
283/// assumption that earlier ones are "simpler", so they should be listed in
284/// order of ascending complexity when possible.
285///
286/// The macro invocation has two forms. The first is to simply list the
287/// strategies separated by commas; this will cause value generation to pick
288/// from the strategies uniformly. The other form is to provide a weight in the
289/// form of a `u32` before each strategy, separated from the strategy with
290/// `=>`.
291///
292/// Note that the exact type returned by the macro varies depending on how many
293/// inputs there are. In particular, if given exactly one option, it will
294/// return it unmodified. It is not recommended to depend on the particular
295/// type produced by this macro.
296///
297/// ## Example
298///
299/// ```rust,no_run
300/// use proptest::prelude::*;
301///
302/// #[derive(Clone, Copy, Debug)]
303/// enum MyEnum {
304///   Big(u64),
305///   Medium(u32),
306///   Little(i16),
307/// }
308///
309/// # #[allow(unused_variables)]
310/// # fn main() {
311/// let my_enum_strategy = prop_oneof![
312///   prop::num::i16::ANY.prop_map(MyEnum::Little),
313///   prop::num::u32::ANY.prop_map(MyEnum::Medium),
314///   prop::num::u64::ANY.prop_map(MyEnum::Big),
315/// ];
316///
317/// let my_weighted_strategy = prop_oneof![
318///   1 => prop::num::i16::ANY.prop_map(MyEnum::Little),
319///   // Chose `Medium` twice as frequently as either `Little` or `Big`; i.e.,
320///   // around 50% of values will be `Medium`, and 25% for each of `Little`
321///   // and `Big`.
322///   2 => prop::num::u32::ANY.prop_map(MyEnum::Medium),
323///   1 => prop::num::u64::ANY.prop_map(MyEnum::Big),
324/// ];
325/// # }
326/// ```
327#[macro_export]
328macro_rules! prop_oneof {
329    ($($item:expr),+ $(,)?) => {
330        $crate::prop_oneof![
331            $(1 => $item),*
332        ]
333    };
334
335    ($_weight0:expr => $item0:expr $(,)?) => { $item0 };
336
337    // NOTE: The clippy::arc_with_non_send_sync lint is disabled here because
338    // the strategies passed into prop_oneof! are often not Send or Sync, such
339    // as BoxedStrategy.
340    //
341    // The double-curly-braces are not strictly required, but allow the expression
342    // to be annotated with an attribute.
343
344    ($weight0:expr => $item0:expr,
345     $weight1:expr => $item1:expr $(,)?) => {{
346        #[allow(clippy::arc_with_non_send_sync)]
347        $crate::strategy::TupleUnion::new(
348            (($weight0, $crate::std_facade::Arc::new($item0)),
349             ($weight1, $crate::std_facade::Arc::new($item1))))
350    }};
351
352    ($weight0:expr => $item0:expr,
353     $weight1:expr => $item1:expr,
354     $weight2:expr => $item2:expr $(,)?) => {{
355        #[allow(clippy::arc_with_non_send_sync)]
356        $crate::strategy::TupleUnion::new(
357            (($weight0, $crate::std_facade::Arc::new($item0)),
358             ($weight1, $crate::std_facade::Arc::new($item1)),
359             ($weight2, $crate::std_facade::Arc::new($item2))))
360    }};
361
362    ($weight0:expr => $item0:expr,
363     $weight1:expr => $item1:expr,
364     $weight2:expr => $item2:expr,
365     $weight3:expr => $item3:expr $(,)?) => {{
366        #[allow(clippy::arc_with_non_send_sync)]
367        $crate::strategy::TupleUnion::new(
368            (($weight0, $crate::std_facade::Arc::new($item0)),
369             ($weight1, $crate::std_facade::Arc::new($item1)),
370             ($weight2, $crate::std_facade::Arc::new($item2)),
371             ($weight3, $crate::std_facade::Arc::new($item3))))
372    }};
373
374    ($weight0:expr => $item0:expr,
375     $weight1:expr => $item1:expr,
376     $weight2:expr => $item2:expr,
377     $weight3:expr => $item3:expr,
378     $weight4:expr => $item4:expr $(,)?) => {{
379        #[allow(clippy::arc_with_non_send_sync)]
380        $crate::strategy::TupleUnion::new(
381            (($weight0, $crate::std_facade::Arc::new($item0)),
382             ($weight1, $crate::std_facade::Arc::new($item1)),
383             ($weight2, $crate::std_facade::Arc::new($item2)),
384             ($weight3, $crate::std_facade::Arc::new($item3)),
385             ($weight4, $crate::std_facade::Arc::new($item4))))
386    }};
387
388    ($weight0:expr => $item0:expr,
389     $weight1:expr => $item1:expr,
390     $weight2:expr => $item2:expr,
391     $weight3:expr => $item3:expr,
392     $weight4:expr => $item4:expr,
393     $weight5:expr => $item5:expr $(,)?) => {{
394        #[allow(clippy::arc_with_non_send_sync)]
395        $crate::strategy::TupleUnion::new(
396            (($weight0, $crate::std_facade::Arc::new($item0)),
397             ($weight1, $crate::std_facade::Arc::new($item1)),
398             ($weight2, $crate::std_facade::Arc::new($item2)),
399             ($weight3, $crate::std_facade::Arc::new($item3)),
400             ($weight4, $crate::std_facade::Arc::new($item4)),
401             ($weight5, $crate::std_facade::Arc::new($item5))))
402    }};
403
404    ($weight0:expr => $item0:expr,
405     $weight1:expr => $item1:expr,
406     $weight2:expr => $item2:expr,
407     $weight3:expr => $item3:expr,
408     $weight4:expr => $item4:expr,
409     $weight5:expr => $item5:expr,
410     $weight6:expr => $item6:expr $(,)?) => {{
411        #[allow(clippy::arc_with_non_send_sync)]
412        $crate::strategy::TupleUnion::new(
413            (($weight0, $crate::std_facade::Arc::new($item0)),
414             ($weight1, $crate::std_facade::Arc::new($item1)),
415             ($weight2, $crate::std_facade::Arc::new($item2)),
416             ($weight3, $crate::std_facade::Arc::new($item3)),
417             ($weight4, $crate::std_facade::Arc::new($item4)),
418             ($weight5, $crate::std_facade::Arc::new($item5)),
419             ($weight6, $crate::std_facade::Arc::new($item6))))
420    }};
421
422    ($weight0:expr => $item0:expr,
423     $weight1:expr => $item1:expr,
424     $weight2:expr => $item2:expr,
425     $weight3:expr => $item3:expr,
426     $weight4:expr => $item4:expr,
427     $weight5:expr => $item5:expr,
428     $weight6:expr => $item6:expr,
429     $weight7:expr => $item7:expr $(,)?) => {{
430        #[allow(clippy::arc_with_non_send_sync)]
431        $crate::strategy::TupleUnion::new(
432            (($weight0, $crate::std_facade::Arc::new($item0)),
433             ($weight1, $crate::std_facade::Arc::new($item1)),
434             ($weight2, $crate::std_facade::Arc::new($item2)),
435             ($weight3, $crate::std_facade::Arc::new($item3)),
436             ($weight4, $crate::std_facade::Arc::new($item4)),
437             ($weight5, $crate::std_facade::Arc::new($item5)),
438             ($weight6, $crate::std_facade::Arc::new($item6)),
439             ($weight7, $crate::std_facade::Arc::new($item7))))
440    }};
441
442    ($weight0:expr => $item0:expr,
443     $weight1:expr => $item1:expr,
444     $weight2:expr => $item2:expr,
445     $weight3:expr => $item3:expr,
446     $weight4:expr => $item4:expr,
447     $weight5:expr => $item5:expr,
448     $weight6:expr => $item6:expr,
449     $weight7:expr => $item7:expr,
450     $weight8:expr => $item8:expr $(,)?) => {{
451        #[allow(clippy::arc_with_non_send_sync)]
452        $crate::strategy::TupleUnion::new(
453            (($weight0, $crate::std_facade::Arc::new($item0)),
454             ($weight1, $crate::std_facade::Arc::new($item1)),
455             ($weight2, $crate::std_facade::Arc::new($item2)),
456             ($weight3, $crate::std_facade::Arc::new($item3)),
457             ($weight4, $crate::std_facade::Arc::new($item4)),
458             ($weight5, $crate::std_facade::Arc::new($item5)),
459             ($weight6, $crate::std_facade::Arc::new($item6)),
460             ($weight7, $crate::std_facade::Arc::new($item7)),
461             ($weight8, $crate::std_facade::Arc::new($item8))))
462    }};
463
464    ($weight0:expr => $item0:expr,
465     $weight1:expr => $item1:expr,
466     $weight2:expr => $item2:expr,
467     $weight3:expr => $item3:expr,
468     $weight4:expr => $item4:expr,
469     $weight5:expr => $item5:expr,
470     $weight6:expr => $item6:expr,
471     $weight7:expr => $item7:expr,
472     $weight8:expr => $item8:expr,
473     $weight9:expr => $item9:expr $(,)?) => {{
474        #[allow(clippy::arc_with_non_send_sync)]
475        $crate::strategy::TupleUnion::new(
476            (($weight0, $crate::std_facade::Arc::new($item0)),
477             ($weight1, $crate::std_facade::Arc::new($item1)),
478             ($weight2, $crate::std_facade::Arc::new($item2)),
479             ($weight3, $crate::std_facade::Arc::new($item3)),
480             ($weight4, $crate::std_facade::Arc::new($item4)),
481             ($weight5, $crate::std_facade::Arc::new($item5)),
482             ($weight6, $crate::std_facade::Arc::new($item6)),
483             ($weight7, $crate::std_facade::Arc::new($item7)),
484             ($weight8, $crate::std_facade::Arc::new($item8)),
485             ($weight9, $crate::std_facade::Arc::new($item9))))
486    }};
487
488    ($($weight:expr => $item:expr),+ $(,)?) => {
489        $crate::strategy::Union::new_weighted(vec![
490            $(($weight, $crate::strategy::Strategy::boxed($item))),*
491        ])
492    };
493}
494
495/// Convenience to define functions which produce new strategies.
496///
497/// The macro has two general forms. In the first, you define a function with
498/// two argument lists. The first argument list uses the usual syntax and
499/// becomes exactly the argument list of the defined function. The second
500/// argument list uses the `in strategy` syntax as with `proptest!`, and is
501/// used to generate the other inputs for the function. The second argument
502/// list has access to all arguments in the first. The return type indicates
503/// the type of value being generated; the final return type of the function is
504/// `impl Strategy<Value = $type>`.
505///
506/// ```rust,no_run
507/// # #![allow(dead_code)]
508/// use proptest::prelude::*;
509///
510/// #[derive(Clone, Debug)]
511/// struct MyStruct {
512///   integer: u32,
513///   string: String,
514/// }
515///
516/// prop_compose! {
517///   fn my_struct_strategy(max_integer: u32)
518///                        (integer in 0..max_integer, string in ".*")
519///                        -> MyStruct {
520///     MyStruct { integer, string }
521///   }
522/// }
523/// #
524/// # fn main() { }
525/// ```
526///
527/// This form is simply sugar around making a tuple and then calling `prop_map`
528/// on it. You can also use `arg: type` as in `proptest! { .. }`:
529///
530/// ```rust,no_run
531/// # #![allow(dead_code)]
532/// # use proptest::prelude::*;
533/// #
534/// # #[derive(Clone, Debug)]
535/// # struct MyStruct {
536/// #  integer: u32,
537/// #  string: String,
538/// # }
539///
540/// prop_compose! {
541///   fn my_struct_strategy(max_integer: u32)
542///                        (integer in 0..max_integer, string: String)
543///                        -> MyStruct {
544///     MyStruct { integer, string }
545///   }
546/// }
547/// #
548/// # fn main() { }
549/// ```
550///
551/// The second form is mostly the same, except that it takes _three_ argument
552/// lists. The third argument list can see all values in both prior, which
553/// permits producing strategies based on other strategies.
554///
555/// ```rust,no_run
556/// # #![allow(dead_code)]
557/// use proptest::prelude::*;
558///
559/// prop_compose! {
560///   fn nearby_numbers()(centre in -1000..1000)
561///                    (a in centre-10..centre+10,
562///                     b in centre-10..centre+10)
563///                    -> (i32, i32) {
564///     (a, b)
565///   }
566/// }
567/// #
568/// # fn main() { }
569/// ```
570///
571/// However, the body of the function does _not_ have access to the second
572/// argument list. If the body needs access to those values, they must be
573/// passed through explicitly.
574///
575/// ```rust,no_run
576/// # #![allow(dead_code)]
577/// use proptest::prelude::*;
578///
579/// prop_compose! {
580///   fn vec_and_index
581///     (max_length: usize)
582///     (vec in prop::collection::vec(1..10, 1..max_length))
583///     (index in 0..vec.len(), vec in Just(vec))
584///     -> (Vec<i32>, usize)
585///   {
586///     (vec, index)
587///   }
588/// }
589/// # fn main() { }
590/// ```
591///
592/// The second form is sugar around making a strategy tuple, calling
593/// `prop_flat_map()`, then `prop_map()`.
594///
595/// To give the function any modifier which isn't a visibility modifier, put it
596/// in brackets before the `fn` token but after any visibility modifier.
597///
598/// ```rust,no_run
599/// # #![allow(dead_code)]
600/// use proptest::prelude::*;
601///
602/// prop_compose! {
603///   pub(crate) [unsafe] fn pointer()(v in prop::num::usize::ANY)
604///                                 -> *const () {
605///     v as *const ()
606///   }
607/// }
608/// # fn main() { }
609/// ```
610///
611/// ## Comparison with Hypothesis' `@composite`
612///
613/// `prop_compose!` makes it easy to do a lot of things you can do with
614/// [Hypothesis' `@composite`](https://hypothesis.readthedocs.io/en/latest/data.html#composite-strategies),
615/// but not everything.
616///
617/// - You can't filter via this macro. For filtering, you need to make the
618/// strategy the "normal" way and use `prop_filter()`.
619///
620/// - More than two layers of strategies or arbitrary logic between the two
621/// layers. If you need either of these, you can achieve them by calling
622/// `prop_flat_map()` by hand.
623#[macro_export]
624macro_rules! prop_compose {
625    ($(#[$meta:meta])*
626     $vis:vis
627     $([$($modi:tt)*])? fn $name:ident $params:tt
628     ($($var:pat in $strategy:expr),+ $(,)?)
629       -> $return_type:ty $body:block) =>
630    {
631        #[must_use = "strategies do nothing unless used"]
632        $(#[$meta])*
633        $vis
634        $($($modi)*)? fn $name $params
635                 -> impl $crate::strategy::Strategy<Value = $return_type> {
636            let strat = $crate::proptest_helper!(@_WRAP ($($strategy)*));
637            $crate::strategy::Strategy::prop_map(strat,
638                move |$crate::proptest_helper!(@_WRAPPAT ($($var),*))| $body)
639        }
640    };
641
642    ($(#[$meta:meta])*
643     $vis:vis
644     $([$($modi:tt)*])? fn $name:ident $params:tt
645     ($($var:pat in $strategy:expr),+ $(,)?)
646     ($($var2:pat in $strategy2:expr),+ $(,)?)
647       -> $return_type:ty $body:block) =>
648    {
649        #[must_use = "strategies do nothing unless used"]
650        $(#[$meta])*
651        $vis
652        $($($modi)*)? fn $name $params
653                 -> impl $crate::strategy::Strategy<Value = $return_type> {
654            let strat = $crate::proptest_helper!(@_WRAP ($($strategy)*));
655            let strat = $crate::strategy::Strategy::prop_flat_map(
656                strat,
657                move |$crate::proptest_helper!(@_WRAPPAT ($($var),*))|
658                $crate::proptest_helper!(@_WRAP ($($strategy2)*)));
659            $crate::strategy::Strategy::prop_map(strat,
660                move |$crate::proptest_helper!(@_WRAPPAT ($($var2),*))| $body)
661        }
662    };
663
664    ($(#[$meta:meta])*
665     $vis:vis
666     $([$($modi:tt)*])? fn $name:ident $params:tt
667     ($($arg:tt)+)
668       -> $return_type:ty $body:block) =>
669    {
670        #[must_use = "strategies do nothing unless used"]
671        $(#[$meta])*
672        $vis
673        $($($modi)*)? fn $name $params
674                 -> impl $crate::strategy::Strategy<Value = $return_type> {
675            let strat = $crate::proptest_helper!(@_EXT _STRAT ($($arg)+));
676            $crate::strategy::Strategy::prop_map(strat,
677                move |$crate::proptest_helper!(@_EXT _PAT ($($arg)+))| $body)
678        }
679    };
680
681    ($(#[$meta:meta])*
682     $vis:vis
683     $([$($modi:tt)*])? fn $name:ident $params:tt
684     ($($arg:tt)+ $(,)?)
685     ($($arg2:tt)+ $(,)?)
686       -> $return_type:ty $body:block) =>
687    {
688        #[must_use = "strategies do nothing unless used"]
689        $(#[$meta])*
690        $vis
691        $($($modi)*)? fn $name $params
692                 -> impl $crate::strategy::Strategy<Value = $return_type> {
693            let strat = $crate::proptest_helper!(@_WRAP ($($strategy)*));
694            let strat = $crate::strategy::Strategy::prop_flat_map(
695                strat,
696                move |$crate::proptest_helper!(@_EXT _PAT ($($arg)+))|
697                $crate::proptest_helper!(@_EXT _STRAT ($($arg2)*)));
698            $crate::strategy::Strategy::prop_map(strat,
699                move |$crate::proptest_helper!(@_EXT _PAT ($($arg2)*))| $body)
700        }
701    };
702}
703
704/// Similar to `assert!` from std, but returns a test failure instead of
705/// panicking if the condition fails.
706///
707/// This can be used in any function that returns a `Result<_, TestCaseError>`,
708/// including the top-level function inside `proptest!`.
709///
710/// Both panicking via `assert!` and returning a test case failure have the
711/// same effect as far as proptest is concerned; however, the Rust runtime
712/// implicitly prints every panic to stderr by default (including a backtrace
713/// if enabled), which can make test failures unnecessarily noisy. By using
714/// `prop_assert!` instead, the only output on a failing test case is the final
715/// panic including the minimal test case.
716///
717/// ## Example
718///
719/// ```
720/// use proptest::prelude::*;
721///
722/// proptest! {
723///   # /*
724///   #[test]
725///   # */
726///   fn triangle_inequality(a in 0.0f64..10.0, b in 0.0f64..10.0) {
727///     // Called with just a condition will print the condition on failure
728///     prop_assert!((a*a + b*b).sqrt() <= a + b);
729///     // You can also provide a custom failure message
730///     prop_assert!((a*a + b*b).sqrt() <= a + b,
731///                  "Triangle inequality didn't hold for ({}, {})", a, b);
732///     // If calling another function that can return failure, don't forget
733///     // the `?` to propagate the failure.
734///     assert_from_other_function(a, b)?;
735///   }
736/// }
737///
738/// // The macro can be used from another function provided it has a compatible
739/// // return type.
740/// fn assert_from_other_function(a: f64, b: f64) -> Result<(), TestCaseError> {
741///   prop_assert!((a*a + b*b).sqrt() <= a + b);
742///   Ok(())
743/// }
744/// #
745/// # fn main() { triangle_inequality(); }
746/// ```
747#[macro_export]
748macro_rules! prop_assert {
749    ($cond:expr $(,) ?) => {
750        $crate::prop_assert!($cond, ::core::concat!("assertion failed: ", ::core::stringify!($cond)))
751    };
752
753    ($cond:expr, $($fmt:tt)*) => {
754        if !$cond {
755            extern crate alloc;
756            let message = alloc::format!($($fmt)*);
757            let message = alloc::format!("{} at {}:{}", message, ::core::file!(), ::core::line!());
758            return ::core::result::Result::Err(
759                $crate::test_runner::TestCaseError::fail(message));
760        }
761    };
762}
763
764/// Similar to `assert_eq!` from std, but returns a test failure instead of
765/// panicking if the condition fails.
766///
767/// See `prop_assert!` for a more in-depth discussion.
768///
769/// ## Example
770///
771/// ```
772/// use proptest::prelude::*;
773///
774/// proptest! {
775///   # /*
776///   #[test]
777///   # */
778///   fn concat_string_length(ref a in ".*", ref b in ".*") {
779///     let cat = format!("{}{}", a, b);
780///     // Use with default message
781///     prop_assert_eq!(a.len() + b.len(), cat.len());
782///     // Can also provide custom message (added after the normal
783///     // assertion message)
784///     prop_assert_eq!(a.len() + b.len(), cat.len(),
785///                     "a = {:?}, b = {:?}", a, b);
786///   }
787/// }
788/// #
789/// # fn main() { concat_string_length(); }
790/// ```
791#[macro_export]
792macro_rules! prop_assert_eq {
793    ($left:expr, $right:expr $(,) ?) => {{
794        let left = $left;
795        let right = $right;
796        $crate::prop_assert!(
797            left == right,
798            "assertion failed: `(left == right)` \
799             \n  left: `{:?}`,\n right: `{:?}`",
800            left, right);
801    }};
802
803    ($left:expr, $right:expr, $fmt:tt $($args:tt)*) => {{
804        let left = $left;
805        let right = $right;
806        $crate::prop_assert!(
807            left == right,
808            concat!(
809                "assertion failed: `(left == right)` \
810                 \n  left: `{:?}`, \n right: `{:?}`: ", $fmt),
811            left, right $($args)*);
812    }};
813}
814
815/// Similar to `assert_ne!` from std, but returns a test failure instead of
816/// panicking if the condition fails.
817///
818/// See `prop_assert!` for a more in-depth discussion.
819///
820/// ## Example
821///
822/// ```
823/// use proptest::prelude::*;
824///
825/// proptest! {
826///   # /*
827///   #[test]
828///   # */
829///   fn test_addition(a in 0i32..100i32, b in 1i32..100i32) {
830///     // Use with default message
831///     prop_assert_ne!(a, a + b);
832///     // Can also provide custom message added after the common message
833///     prop_assert_ne!(a, a + b, "a = {}, b = {}", a, b);
834///   }
835/// }
836/// #
837/// # fn main() { test_addition(); }
838/// ```
839#[macro_export]
840macro_rules! prop_assert_ne {
841    ($left:expr, $right:expr $(,) ?) => {{
842        let left = $left;
843        let right = $right;
844        $crate::prop_assert!(
845            left != right,
846            "assertion failed: `(left != right)`\
847             \n  left: `{:?}`,\n right: `{:?}`",
848            left, right);
849    }};
850
851    ($left:expr, $right:expr, $fmt:tt $($args:tt)*) => {{
852        let left = $left;
853        let right = $right;
854        $crate::prop_assert!(left != right, concat!(
855                "assertion failed: `(left != right)`\
856                 \n  left: `{:?}`,\n right: `{:?}`: ", $fmt),
857            left, right $($args)*);
858    }};
859}
860
861#[doc(hidden)]
862#[macro_export]
863macro_rules! proptest_helper {
864    (@_WRAP ($a:tt)) => { $a };
865    (@_WRAP ($a0:tt $a1:tt)) => { ($a0, $a1) };
866    (@_WRAP ($a0:tt $a1:tt $a2:tt)) => { ($a0, $a1, $a2) };
867    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt)) => { ($a0, $a1, $a2, $a3) };
868    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt $a4:tt)) => {
869        ($a0, $a1, $a2, $a3, $a4)
870    };
871    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt $a4:tt $a5:tt)) => {
872        ($a0, $a1, $a2, $a3, $a4, $a5)
873    };
874    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt $a4:tt $a5:tt $a6:tt)) => {
875        ($a0, $a1, $a2, $a3, $a4, $a5, $a6)
876    };
877    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt
878             $a4:tt $a5:tt $a6:tt $a7:tt)) => {
879        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7)
880    };
881    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt $a4:tt
882             $a5:tt $a6:tt $a7:tt $a8:tt)) => {
883        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8)
884    };
885    (@_WRAP ($a0:tt $a1:tt $a2:tt $a3:tt $a4:tt
886             $a5:tt $a6:tt $a7:tt $a8:tt $a9:tt)) => {
887        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8, $a9)
888    };
889    (@_WRAP ($a:tt $($rest:tt)*)) => {
890        ($a, $crate::proptest_helper!(@_WRAP ($($rest)*)))
891    };
892    (@_WRAPPAT ($item:pat)) => { $item };
893    (@_WRAPPAT ($a0:pat, $a1:pat)) => { ($a0, $a1) };
894    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat)) => { ($a0, $a1, $a2) };
895    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat)) => {
896        ($a0, $a1, $a2, $a3)
897    };
898    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat)) => {
899        ($a0, $a1, $a2, $a3, $a4)
900    };
901    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat, $a5:pat)) => {
902        ($a0, $a1, $a2, $a3, $a4, $a5)
903    };
904    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat,
905                $a4:pat, $a5:pat, $a6:pat)) => {
906        ($a0, $a1, $a2, $a3, $a4, $a5, $a6)
907    };
908    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat,
909                $a4:pat, $a5:pat, $a6:pat, $a7:pat)) => {
910        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7)
911    };
912    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat,
913                $a5:pat, $a6:pat, $a7:pat, $a8:pat)) => {
914        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8)
915    };
916    (@_WRAPPAT ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat,
917                $a5:pat, $a6:pat, $a7:pat, $a8:pat, $a9:pat)) => {
918        ($a0, $a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8, $a9)
919    };
920    (@_WRAPPAT ($a:pat, $($rest:pat),*)) => {
921        ($a, $crate::proptest_helper!(@_WRAPPAT ($($rest),*)))
922    };
923    (@_WRAPSTR ($item:pat)) => { ::core::stringify!($item) };
924    (@_WRAPSTR ($a0:pat, $a1:pat)) => { (::core::stringify!($a0), ::core::stringify!($a1)) };
925    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat)) => {
926        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2))
927    };
928    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat)) => {
929        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3))
930    };
931    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat)) => {
932        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2),
933         ::core::stringify!($a3), ::core::stringify!($a4))
934    };
935    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat, $a5:pat)) => {
936        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3),
937         ::core::stringify!($a4), ::core::stringify!($a5))
938    };
939    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat,
940                $a4:pat, $a5:pat, $a6:pat)) => {
941        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3),
942         ::core::stringify!($a4), ::core::stringify!($a5), ::core::stringify!($a6))
943    };
944    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat,
945                $a4:pat, $a5:pat, $a6:pat, $a7:pat)) => {
946        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3),
947         ::core::stringify!($a4), ::core::stringify!($a5), ::core::stringify!($a6), ::core::stringify!($a7))
948    };
949    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat,
950                $a5:pat, $a6:pat, $a7:pat, $a8:pat)) => {
951        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3),
952         ::core::stringify!($a4), ::core::stringify!($a5), ::core::stringify!($a6), ::core::stringify!($a7),
953         ::core::stringify!($a8))
954    };
955    (@_WRAPSTR ($a0:pat, $a1:pat, $a2:pat, $a3:pat, $a4:pat,
956                $a5:pat, $a6:pat, $a7:pat, $a8:pat, $a9:pat)) => {
957        (::core::stringify!($a0), ::core::stringify!($a1), ::core::stringify!($a2), ::core::stringify!($a3),
958         ::core::stringify!($a4), ::core::stringify!($a5), ::core::stringify!($a6), ::core::stringify!($a7),
959         ::core::stringify!($a8), ::core::stringify!($a9))
960    };
961    (@_WRAPSTR ($a:pat, $($rest:pat),*)) => {
962        (::core::stringify!($a), $crate::proptest_helper!(@_WRAPSTR ($($rest),*)))
963    };
964    // build a property testing block that when executed, executes the full property test.
965    (@_BODY $config:ident ($($parm:pat in $strategy:expr),+) [$($mod:tt)*] $body:expr) => {{
966        $config.source_file = Some(file!());
967        let mut runner = $crate::test_runner::TestRunner::new($config);
968        let names = $crate::proptest_helper!(@_WRAPSTR ($($parm),*));
969        match runner.run(
970            &$crate::strategy::Strategy::prop_map(
971                $crate::proptest_helper!(@_WRAP ($($strategy)*)),
972                |values| $crate::sugar::NamedArguments(names, values)),
973            $($mod)* |$crate::sugar::NamedArguments(
974                _, $crate::proptest_helper!(@_WRAPPAT ($($parm),*)))|
975            {
976                let (): () = $body;
977                ::core::result::Result::Ok(())
978            })
979        {
980            ::core::result::Result::Ok(()) => (),
981            ::core::result::Result::Err(e) => ::core::panic!("{}\n{}", e, runner),
982        }
983    }};
984    // build a property testing block that when executed, executes the full property test.
985    (@_BODY2 $config:ident ($($arg:tt)+) [$($mod:tt)*] $body:expr) => {{
986        $config.source_file = Some(::core::file!());
987        let mut runner = $crate::test_runner::TestRunner::new($config);
988        let names = $crate::proptest_helper!(@_EXT _STR ($($arg)*));
989        match runner.run(
990            &$crate::strategy::Strategy::prop_map(
991                $crate::proptest_helper!(@_EXT _STRAT ($($arg)*)),
992                |values| $crate::sugar::NamedArguments(names, values)),
993            $($mod)* |$crate::sugar::NamedArguments(
994                _, $crate::proptest_helper!(@_EXT _PAT ($($arg)*)))|
995            {
996                let (): () = $body;
997                ::core::result::Result::Ok(())
998            })
999        {
1000            ::core::result::Result::Ok(()) => (),
1001            ::core::result::Result::Err(e) => ::core::panic!("{}\n{}", e, runner),
1002        }
1003    }};
1004
1005    // The logic below helps support `pat: type` in the proptest! macro.
1006
1007    // These matchers define the actual logic:
1008    (@_STRAT [$s:ty] [$p:pat]) => { $crate::arbitrary::any::<$s>()  };
1009    (@_PAT [$s:ty] [$p:pat]) => { $p };
1010    (@_STR [$s:ty] [$p:pat]) => { ::core::stringify!($p) };
1011    (@_STRAT in [$s:expr] [$p:pat]) => { $s };
1012    (@_PAT in [$s:expr] [$p:pat]) => { $p };
1013    (@_STR in [$s:expr] [$p:pat]) => { ::core::stringify!($p) };
1014
1015    // These matchers rewrite into the above extractors.
1016    // We have to do this because `:` can't FOLLOW(pat).
1017    // Note that this is not the full `pat` grammar...
1018    // See https://docs.rs/syn/0.14.2/syn/enum.Pat.html for that.
1019    (@_EXT $cmd:ident ($p:pat in $s:expr $(,)?)) => {
1020        $crate::proptest_helper!(@$cmd in [$s] [$p])
1021    };
1022    (@_EXT $cmd:ident (($p:pat) : $s:ty $(,)?)) => {
1023        // Users can wrap in parens as a last resort.
1024        $crate::proptest_helper!(@$cmd [$s] [$p])
1025    };
1026    (@_EXT $cmd:ident (_ : $s:ty $(,)?)) => {
1027        $crate::proptest_helper!(@$cmd [$s] [_])
1028    };
1029    (@_EXT $cmd:ident (ref mut $p:ident : $s:ty $(,)?)) => {
1030        $crate::proptest_helper!(@$cmd [$s] [ref mut $p])
1031    };
1032    (@_EXT $cmd:ident (ref $p:ident : $s:ty $(,)?)) => {
1033        $crate::proptest_helper!(@$cmd [$s] [ref $p])
1034    };
1035    (@_EXT $cmd:ident (mut $p:ident : $s:ty $(,)?)) => {
1036        $crate::proptest_helper!(@$cmd [$s] [mut $p])
1037    };
1038    (@_EXT $cmd:ident ($p:ident : $s:ty $(,)?)) => {
1039        $crate::proptest_helper!(@$cmd [$s] [$p])
1040    };
1041    (@_EXT $cmd:ident ([$($p:tt)*] : $s:ty $(,)?)) => {
1042        $crate::proptest_helper!(@$cmd [$s] [[$($p)*]])
1043    };
1044
1045    // Rewrite, Inductive case:
1046    (@_EXT $cmd:ident ($p:pat in $s:expr, $($r:tt)*)) => {
1047        ($crate::proptest_helper!(@$cmd in [$s] [$p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1048    };
1049    (@_EXT $cmd:ident (($p:pat) : $s:ty, $($r:tt)*)) => {
1050        ($crate::proptest_helper!(@$cmd [$s] [$p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1051    };
1052    (@_EXT $cmd:ident (_ : $s:ty, $($r:tt)*)) => {
1053        ($crate::proptest_helper!(@$cmd [$s] [_]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1054    };
1055    (@_EXT $cmd:ident (ref mut $p:ident : $s:ty, $($r:tt)*)) => {
1056        ($crate::proptest_helper!(@$cmd [$s] [ref mut $p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1057    };
1058    (@_EXT $cmd:ident (ref $p:ident : $s:ty, $($r:tt)*)) => {
1059        ($crate::proptest_helper!(@$cmd [$s] [ref $p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1060    };
1061    (@_EXT $cmd:ident (mut $p:ident : $s:ty, $($r:tt)*)) => {
1062        ($crate::proptest_helper!(@$cmd [$s] [mut $p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1063    };
1064    (@_EXT $cmd:ident ($p:ident : $s:ty, $($r:tt)*)) => {
1065        ($crate::proptest_helper!(@$cmd [$s] [$p]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1066    };
1067    (@_EXT $cmd:ident ([$($p:tt)*] : $s:ty, $($r:tt)*)) => {
1068        ($crate::proptest_helper!(@$cmd [$s] [[$($p)*]]), $crate::proptest_helper!(@_EXT $cmd ($($r)*)))
1069    };
1070}
1071
1072#[doc(hidden)]
1073#[derive(Clone, Copy)]
1074pub struct NamedArguments<N, V>(#[doc(hidden)] pub N, #[doc(hidden)] pub V);
1075
1076impl<V: fmt::Debug> fmt::Debug for NamedArguments<&'static str, V> {
1077    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1078        write!(f, "{} = ", self.0)?;
1079        self.1.fmt(f)
1080    }
1081}
1082
1083macro_rules! named_arguments_tuple {
1084    ($($ix:tt $argn:ident $argv:ident)*) => {
1085        impl<'a, $($argn : Copy),*, $($argv),*> fmt::Debug
1086        for NamedArguments<($($argn,)*),&'a ($($argv,)*)>
1087        where $(NamedArguments<$argn, &'a $argv> : fmt::Debug),*,
1088              $($argv : 'a),*
1089        {
1090            #[allow(unused_assignments)]
1091            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1092                let mut first = true;
1093                $(
1094                    if !first {
1095                        write!(f, ", ")?;
1096                    }
1097                    first = false;
1098                    fmt::Debug::fmt(
1099                        &NamedArguments((self.0).$ix, &(self.1).$ix), f)?;
1100                )*
1101                Ok(())
1102            }
1103        }
1104
1105        impl<$($argn : Copy),*, $($argv),*> fmt::Debug
1106        for NamedArguments<($($argn,)*), ($($argv,)*)>
1107        where $(for<'a> NamedArguments<$argn, &'a $argv> : fmt::Debug),*
1108        {
1109            #[allow(unused_assignments)]
1110            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1111                let mut first = true;
1112                $(
1113                    if !first {
1114                        write!(f, ", ")?;
1115                    }
1116                    first = false;
1117                    fmt::Debug::fmt(
1118                        &NamedArguments((self.0).$ix, &(self.1).$ix), f)?;
1119                )*
1120                Ok(())
1121            }
1122        }
1123    }
1124}
1125
1126named_arguments_tuple!(0 AN AV);
1127named_arguments_tuple!(0 AN AV 1 BN BV);
1128named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV);
1129named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV);
1130named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV);
1131named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV
1132                       5 FN FV);
1133named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV
1134                       5 FN FV 6 GN GV);
1135named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV
1136                       5 FN FV 6 GN GV 7 HN HV);
1137named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV
1138                       5 FN FV 6 GN GV 7 HN HV 8 IN IV);
1139named_arguments_tuple!(0 AN AV 1 BN BV 2 CN CV 3 DN DV 4 EN EV
1140                       5 FN FV 6 GN GV 7 HN HV 8 IN IV 9 JN JV);
1141
1142#[cfg(feature = "std")]
1143#[doc(hidden)]
1144pub fn force_no_fork(config: &mut crate::test_runner::Config) {
1145    if config.fork() {
1146        eprintln!(
1147            "proptest: Forking/timeout not supported in closure-style \
1148             invocations; ignoring"
1149        );
1150
1151        #[cfg(feature = "fork")]
1152        {
1153            config.fork = false;
1154        }
1155        #[cfg(feature = "timeout")]
1156        {
1157            config.timeout = 0;
1158        }
1159        assert!(!config.fork());
1160    }
1161}
1162
1163#[cfg(not(feature = "std"))]
1164pub fn force_no_fork(_: &mut crate::test_runner::Config) {}
1165
1166#[cfg(test)]
1167mod test {
1168    use crate::strategy::Just;
1169
1170    prop_compose! {
1171        /// These are docs!
1172        #[allow(dead_code)]
1173        fn two_ints(relative: i32)(a in 0..relative, b in relative..)
1174                   -> (i32, i32) {
1175            (a, b)
1176        }
1177    }
1178
1179    prop_compose! {
1180        /// These are docs!
1181        #[allow(dead_code)]
1182        pub fn two_ints_pub(relative: i32)(a in 0..relative, b in relative..)
1183                           -> (i32, i32) {
1184            (a, b)
1185        }
1186    }
1187
1188    prop_compose! {
1189        /// These are docs!
1190        #[allow(dead_code, improper_ctypes_definitions)]
1191        pub [extern "C"] fn two_ints_pub_with_attrs
1192            (relative: i32)(a in 0..relative, b in relative..)
1193            -> (i32, i32)
1194        {
1195            (a, b)
1196        }
1197    }
1198
1199    prop_compose! {
1200        // The only modifier we can usefully put here is "unsafe", but we want
1201        // to keep this crate unsafe-free, even nominally. "const" may
1202        // eventually work, but is not allowed right now since the generated
1203        // code contains local variables. `extern "C"` is accepted, even though
1204        // the result is useless since the return type isn't C-compatible.
1205        #[allow(dead_code, improper_ctypes_definitions)]
1206        [extern "C"] fn with_modifier(relative: i32)(a in 0..relative) -> i32 {
1207            a
1208        }
1209    }
1210
1211    prop_compose! {
1212        #[allow(dead_code)]
1213        fn a_less_than_b()(b in 0..1000)(a in 0..b, b in Just(b))
1214                        -> (i32, i32) {
1215            (a, b)
1216        }
1217    }
1218
1219    proptest! {
1220        #[test]
1221        fn test_something(a in 0u32..42u32, b in 1u32..10u32) {
1222            prop_assume!(a != 41 || b != 9);
1223            assert!(a + b < 50);
1224        }
1225    }
1226
1227    prop_compose! {
1228        #[allow(dead_code)]
1229        fn single_closure_is_move(base: u64)(off in 0..10u64) -> u64 {
1230            base + off
1231        }
1232    }
1233
1234    prop_compose! {
1235        #[allow(dead_code)]
1236        fn double_closure_is_move
1237            (base: u64)
1238            (off1 in 0..10u64)
1239            (off2 in off1..off1+10)
1240            -> u64
1241        {
1242            base + off2
1243        }
1244    }
1245
1246    #[allow(unused_variables)]
1247    mod test_arg_counts {
1248        use crate::strategy::Just;
1249
1250        proptest! {
1251            #[test]
1252            fn test_1_arg(a in Just(0)) { }
1253            #[test]
1254            fn test_2_arg(a in Just(0), b in Just(0)) { }
1255            #[test]
1256            fn test_3_arg(a in Just(0), b in Just(0), c in Just(0)) { }
1257            #[test]
1258            fn test_4_arg(a in Just(0), b in Just(0), c in Just(0),
1259                          d in Just(0)) { }
1260            #[test]
1261            fn test_5_arg(a in Just(0), b in Just(0), c in Just(0),
1262                          d in Just(0), e in Just(0)) { }
1263            #[test]
1264            fn test_6_arg(a in Just(0), b in Just(0), c in Just(0),
1265                          d in Just(0), e in Just(0), f in Just(0)) { }
1266            #[test]
1267            fn test_7_arg(a in Just(0), b in Just(0), c in Just(0),
1268                          d in Just(0), e in Just(0), f in Just(0),
1269                          g in Just(0)) { }
1270            #[test]
1271            fn test_8_arg(a in Just(0), b in Just(0), c in Just(0),
1272                          d in Just(0), e in Just(0), f in Just(0),
1273                          g in Just(0), h in Just(0)) { }
1274            #[test]
1275            fn test_9_arg(a in Just(0), b in Just(0), c in Just(0),
1276                          d in Just(0), e in Just(0), f in Just(0),
1277                          g in Just(0), h in Just(0), i in Just(0)) { }
1278            #[test]
1279            fn test_a_arg(a in Just(0), b in Just(0), c in Just(0),
1280                          d in Just(0), e in Just(0), f in Just(0),
1281                          g in Just(0), h in Just(0), i in Just(0),
1282                          j in Just(0)) { }
1283            #[test]
1284            fn test_b_arg(a in Just(0), b in Just(0), c in Just(0),
1285                          d in Just(0), e in Just(0), f in Just(0),
1286                          g in Just(0), h in Just(0), i in Just(0),
1287                          j in Just(0), k in Just(0)) { }
1288            #[test]
1289            fn test_c_arg(a in Just(0), b in Just(0), c in Just(0),
1290                          d in Just(0), e in Just(0), f in Just(0),
1291                          g in Just(0), h in Just(0), i in Just(0),
1292                          j in Just(0), k in Just(0), l in Just(0)) { }
1293        }
1294    }
1295
1296    #[test]
1297    fn named_arguments_is_debug_for_needed_cases() {
1298        use super::NamedArguments;
1299
1300        println!("{:?}", NamedArguments("foo", &"bar"));
1301        println!("{:?}", NamedArguments(("foo",), &(1,)));
1302        println!("{:?}", NamedArguments(("foo", "bar"), &(1, 2)));
1303        println!("{:?}", NamedArguments(("a", "b", "c"), &(1, 2, 3)));
1304        println!("{:?}", NamedArguments(("a", "b", "c", "d"), &(1, 2, 3, 4)));
1305        println!(
1306            "{:?}",
1307            NamedArguments(("a", "b", "c", "d", "e"), &(1, 2, 3, 4, 5))
1308        );
1309        println!(
1310            "{:?}",
1311            NamedArguments(("a", "b", "c", "d", "e", "f"), &(1, 2, 3, 4, 5, 6))
1312        );
1313        println!(
1314            "{:?}",
1315            NamedArguments(
1316                ("a", "b", "c", "d", "e", "f", "g"),
1317                &(1, 2, 3, 4, 5, 6, 7)
1318            )
1319        );
1320        println!(
1321            "{:?}",
1322            NamedArguments(
1323                ("a", "b", "c", "d", "e", "f", "g", "h"),
1324                &(1, 2, 3, 4, 5, 6, 7, 8)
1325            )
1326        );
1327        println!(
1328            "{:?}",
1329            NamedArguments(
1330                ("a", "b", "c", "d", "e", "f", "g", "h", "i"),
1331                &(1, 2, 3, 4, 5, 6, 7, 8, 9)
1332            )
1333        );
1334        println!(
1335            "{:?}",
1336            NamedArguments(
1337                ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
1338                &(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
1339            )
1340        );
1341        println!(
1342            "{:?}",
1343            NamedArguments((("a", "b"), "c", "d"), &((1, 2), 3, 4))
1344        );
1345    }
1346
1347    #[test]
1348    fn oneof_all_counts() {
1349        use crate::strategy::{Just as J, Strategy, TupleUnion, Union};
1350
1351        fn expect_count(n: usize, s: impl Strategy<Value = i32>) {
1352            use crate::strategy::*;
1353            use crate::test_runner::*;
1354            use std::collections::HashSet;
1355
1356            let mut runner = TestRunner::default();
1357            let mut seen = HashSet::new();
1358            for _ in 0..1024 {
1359                seen.insert(s.new_tree(&mut runner).unwrap().current());
1360            }
1361
1362            assert_eq!(n, seen.len());
1363        }
1364
1365        fn assert_static<T>(v: TupleUnion<T>) -> TupleUnion<T> {
1366            v
1367        }
1368        fn assert_dynamic<T: Strategy>(v: Union<T>) -> Union<T> {
1369            v
1370        }
1371
1372        expect_count(1, prop_oneof![J(0i32)]);
1373        expect_count(2, assert_static(prop_oneof![J(0i32), J(1i32),]));
1374        expect_count(3, assert_static(prop_oneof![J(0i32), J(1i32), J(2i32),]));
1375        expect_count(
1376            4,
1377            assert_static(prop_oneof![J(0i32), J(1i32), J(2i32), J(3i32),]),
1378        );
1379        expect_count(
1380            5,
1381            assert_static(prop_oneof![
1382                J(0i32),
1383                J(1i32),
1384                J(2i32),
1385                J(3i32),
1386                J(4i32),
1387            ]),
1388        );
1389        expect_count(
1390            6,
1391            assert_static(prop_oneof![
1392                J(0i32),
1393                J(1i32),
1394                J(2i32),
1395                J(3i32),
1396                J(4i32),
1397                J(5i32),
1398            ]),
1399        );
1400        expect_count(
1401            7,
1402            assert_static(prop_oneof![
1403                J(0i32),
1404                J(1i32),
1405                J(2i32),
1406                J(3i32),
1407                J(4i32),
1408                J(5i32),
1409                J(6i32),
1410            ]),
1411        );
1412        expect_count(
1413            8,
1414            assert_static(prop_oneof![
1415                J(0i32),
1416                J(1i32),
1417                J(2i32),
1418                J(3i32),
1419                J(4i32),
1420                J(5i32),
1421                J(6i32),
1422                J(7i32),
1423            ]),
1424        );
1425        expect_count(
1426            9,
1427            assert_static(prop_oneof![
1428                J(0i32),
1429                J(1i32),
1430                J(2i32),
1431                J(3i32),
1432                J(4i32),
1433                J(5i32),
1434                J(6i32),
1435                J(7i32),
1436                J(8i32),
1437            ]),
1438        );
1439        expect_count(
1440            10,
1441            assert_static(prop_oneof![
1442                J(0i32),
1443                J(1i32),
1444                J(2i32),
1445                J(3i32),
1446                J(4i32),
1447                J(5i32),
1448                J(6i32),
1449                J(7i32),
1450                J(8i32),
1451                J(9i32),
1452            ]),
1453        );
1454        expect_count(
1455            11,
1456            assert_dynamic(prop_oneof![
1457                J(0i32),
1458                J(1i32),
1459                J(2i32),
1460                J(3i32),
1461                J(4i32),
1462                J(5i32),
1463                J(6i32),
1464                J(7i32),
1465                J(8i32),
1466                J(9i32),
1467                J(10i32),
1468            ]),
1469        );
1470    }
1471}
1472
1473#[cfg(all(test, feature = "timeout"))]
1474mod test_timeout {
1475    proptest! {
1476        #![proptest_config(crate::test_runner::Config {
1477            fork: true,
1478            .. crate::test_runner::Config::default()
1479        })]
1480
1481        // Ensure that the macro sets the test name properly. If it doesn't,
1482        // this test will fail to run correctly.
1483        #[test]
1484        fn test_name_set_correctly_for_fork(_ in 0u32..1u32) { }
1485    }
1486}
1487
1488#[cfg(test)]
1489mod another_test {
1490    use crate::sugar;
1491
1492    // Ensure that we can access the `[pub]` composed function above.
1493    #[allow(dead_code)]
1494    fn can_access_pub_compose() {
1495        let _ = sugar::test::two_ints_pub(42);
1496        let _ = sugar::test::two_ints_pub_with_attrs(42);
1497    }
1498}
1499
1500#[cfg(test)]
1501mod ownership_tests {
1502    #[cfg(feature = "std")]
1503    proptest! {
1504        #[test]
1505        fn accept_ref_arg(ref s in "[0-9]") {
1506            use crate::std_facade::String;
1507            fn assert_string(_s: &String) {}
1508            assert_string(s);
1509        }
1510
1511        #[test]
1512        fn accept_move_arg(s in "[0-9]") {
1513            use crate::std_facade::String;
1514            fn assert_string(_s: String) {}
1515            assert_string(s);
1516        }
1517    }
1518
1519    #[derive(Debug)]
1520    struct NotClone();
1521    const MK: fn() -> NotClone = NotClone;
1522
1523    proptest! {
1524        #[test]
1525        fn accept_noclone_arg(nc in MK) {
1526            let _nc2: NotClone = nc;
1527        }
1528
1529        #[test]
1530        fn accept_noclone_ref_arg(ref nc in MK) {
1531            let _nc2: &NotClone = nc;
1532        }
1533    }
1534}
1535
1536#[cfg(test)]
1537mod closure_tests {
1538    #[test]
1539    fn test_simple() {
1540        let x = 420;
1541
1542        proptest!(|(y: i32)| {
1543            assert!(x != y);
1544        });
1545
1546        proptest!(|(y in 0..100)| {
1547            println!("{}", y);
1548            assert!(x != y);
1549        });
1550
1551        proptest!(|(y: i32,)| {
1552            assert!(x != y);
1553        });
1554
1555        proptest!(|(y in 0..100,)| {
1556            println!("{}", y);
1557            assert!(x != y);
1558        });
1559    }
1560
1561    #[test]
1562    fn test_move() {
1563        let foo = Foo;
1564
1565        proptest!(move |(x in 1..100, y in 0..100)| {
1566            assert!(x + y > 0, "foo: {:?}", foo);
1567        });
1568
1569        let foo = Foo;
1570        proptest!(move |(x: (), y: ())| {
1571            assert!(x == y, "foo: {:?}", foo);
1572        });
1573
1574        #[derive(Debug)]
1575        struct Foo;
1576    }
1577
1578    #[test]
1579    #[should_panic]
1580    #[allow(unreachable_code)]
1581    fn fails_if_closure_panics() {
1582        proptest!(|(_ in 0..1)| {
1583            panic!()
1584        });
1585    }
1586
1587    #[test]
1588    fn accepts_unblocked_syntax() {
1589        proptest!(|(x in 0u32..10, y in 10u32..20)| assert!(x < y));
1590        proptest!(|(x in 0u32..10, y in 10u32..20,)| assert!(x < y));
1591    }
1592
1593    #[test]
1594    fn accepts_custom_config() {
1595        let conf = crate::test_runner::Config::default();
1596
1597        proptest!(conf, |(x in 0u32..10, y in 10u32..20)| assert!(x < y));
1598        proptest!(&conf, |(x in 0u32..10, y in 10u32..20)| assert!(x < y));
1599        proptest!(conf, move |(x in 0u32..10, y in 10u32..20)| assert!(x < y));
1600        proptest!(conf, |(_x: u32, _y: u32)| { });
1601        proptest!(conf, move |(_x: u32, _y: u32)| { });
1602
1603        // Same as above, but with extra trailing comma
1604        proptest!(conf, |(x in 0u32..10, y in 10u32..20,)| assert!(x < y));
1605        proptest!(&conf, |(x in 0u32..10, y in 10u32..20,)| assert!(x < y));
1606        proptest!(conf, move |(x in 0u32..10, y in 10u32..20,)| assert!(x < y));
1607        proptest!(conf, |(_x: u32, _y: u32,)| { });
1608        proptest!(conf, move |(_x: u32, _y: u32,)| { });
1609    }
1610}
1611
1612#[cfg(test)]
1613mod any_tests {
1614    proptest! {
1615        #[test]
1616        fn test_something
1617            (
1618                a: bool,
1619                b in 25u8..,
1620                c in 25u8..,
1621                _d: (),
1622                mut _e: (),
1623                ref _f: (),
1624                ref mut _g: (),
1625                [_, _]: [(); 2],
1626            ) {
1627            if a {} // Assert bool.
1628            assert!(b as usize + c as usize >= 50);
1629        }
1630    }
1631
1632    // Test that the macro accepts some of the inputs we expect it to:
1633    #[test]
1634    fn proptest_ext_test() {
1635        struct Y(pub u8);
1636
1637        let _ = proptest_helper!(@_EXT _STRAT( _ : u8 ));
1638        let _ = proptest_helper!(@_EXT _STRAT( x : u8 ));
1639        let _ = proptest_helper!(@_EXT _STRAT( ref x : u8 ));
1640        let _ = proptest_helper!(@_EXT _STRAT( mut x : u8 ));
1641        let _ = proptest_helper!(@_EXT _STRAT( ref mut x : u8 ));
1642        let _ = proptest_helper!(@_EXT _STRAT( [_, _] : u8 ));
1643        let _ = proptest_helper!(@_EXT _STRAT( (&mut &Y(ref x)) : u8 ));
1644        let _ = proptest_helper!(@_EXT _STRAT( x in 1..2 ));
1645
1646        let proptest_helper!(@_EXT _PAT( _ : u8 )) = 1;
1647        let proptest_helper!(@_EXT _PAT( _x : u8 )) = 1;
1648        let proptest_helper!(@_EXT _PAT( mut _x : u8 )) = 1;
1649        let proptest_helper!(@_EXT _PAT( ref _x : u8 )) = 1;
1650        let proptest_helper!(@_EXT _PAT( ref mut _x : u8 )) = 1;
1651        let proptest_helper!(@_EXT _PAT( [_, _] : u8 )) = [1, 2];
1652        let proptest_helper!(@_EXT _PAT( (&mut &Y(ref _x)) : u8 )) = &mut &Y(1);
1653        let proptest_helper!(@_EXT _PAT( _x in 1..2 )) = 1;
1654    }
1655}