propfuzz 0.0.1

Combine property-based testing and fuzzing.
Documentation
// Copyright (c) The propfuzz Contributors
// SPDX-License-Identifier: MIT OR Apache-2.0

//! The core traits powering `propfuzz`.
//!
//! `propfuzz` relies on separating out a standard property-based test into its components:
//! * constructing a configuration
//! * executing the test, given a test runner
//! * formatting failing values

use proptest::prelude::*;
use proptest::test_runner::{TestError, TestRunner};
use std::fmt;

/// Represents a structured fuzz target.
///
/// Functions written with the `propfuzz` macro are converted to implementations of this trait.
///
/// A trait that implements `Propfuzz` can be used both as a standard property-based test, and
/// as a target for structured, mutation-based fuzzing.
///
/// Structured, mutation-based fuzzers use random byte sequences as a pass-through RNG. In other
/// words, the random byte sequences act as something like a DNA for random values.
pub trait StructuredTarget: Send + Sync + fmt::Debug {
    /// The type of values generated by the proptest.
    type Value: fmt::Debug;

    /// Returns the name of this structured fuzz target.
    fn name(&self) -> &'static str;

    /// Returns an optional description for this structured fuzz target.
    fn description(&self) -> Option<&'static str>;

    /// Returns the proptest config for this fuzz target.
    ///
    /// The default implementation for the `#[propfuzz]` macro uses the default `proptest` config,
    /// and sets `source_file` to the file the macro is invoked from. The config can be altered
    /// through passing arguments to `#[propfuzz]`.
    fn proptest_config(&self) -> ProptestConfig {
        ProptestConfig::default()
    }

    /// Executes this test using the given test runner.
    ///
    /// This is where the main body of the test goes.
    fn execute(&self, test_runner: &mut TestRunner) -> Result<(), TestError<Self::Value>>;

    /// Formats a failing test case for displaying to the user.
    ///
    /// The default implementation calls the `fmt::Debug` implementation on the value.
    ///
    /// The default implementation for the `#[propfuzz]` macro prints out variable names and values.
    fn fmt_value(&self, value: &Self::Value, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", value)
    }
}