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
// Copyright (c) The propfuzz Contributors
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Runtime support.

use crate::traits::StructuredTarget;
use proptest::test_runner::{TestError, TestRunner};
use std::fmt;

/// Executes a propfuzz target as a standard property-based test.
pub fn execute_as_proptest(fuzz_target: impl StructuredTarget) {
    let mut config = fuzz_target.proptest_config();
    config.test_name = Some(fuzz_target.name());

    let mut test_runner = TestRunner::new(config);
    match fuzz_target.execute(&mut test_runner) {
        Ok(()) => (),
        Err(err) => panic!(
            "{}{}",
            TestErrorDisplay::new(&fuzz_target, err),
            test_runner
        ),
    }
}

struct TestErrorDisplay<'a, PF, T> {
    fuzz_target: &'a PF,
    err: TestError<T>,
}

impl<'a, PF, T> TestErrorDisplay<'a, PF, T> {
    fn new(fuzz_target: &'a PF, err: TestError<T>) -> Self {
        Self { fuzz_target, err }
    }
}

impl<'a, PF, T> fmt::Display for TestErrorDisplay<'a, PF, T>
where
    PF: StructuredTarget<Value = T>,
    T: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match &self.err {
            TestError::Abort(why) => write!(f, "Test aborted: {}", why),
            TestError::Fail(why, what) => {
                writeln!(f, "Test failed: {}\nminimal failing input:", why)?;
                self.fuzz_target.fmt_value(&what, f)
            }
        }
    }
}