nri-prelude-0.6.0.6: A Prelude inspired by the Elm programming language
Safe HaskellNone
LanguageHaskell2010

Fuzz

Description

This is a library of fuzzers you can use to supply values to your fuzz tests. You can typically pick out which ones you need according to their types.

A Fuzzer a knows how to create values of type a in two different ways. It can create them randomly, so that your test's expectations are run against many values. Fuzzers will often generate edge cases likely to find bugs. If the fuzzer can make your test fail, it also knows how to "shrink" that failing input into more minimal examples, some of which might also cause the tests to fail. In this way, fuzzers can usually find the smallest or simplest input that reproduces a bug.

Synopsis

Common Fuzzers

int :: Fuzzer Int Source #

A fuzzer for int values. It will never produce NaN, Infinity, or -Infinity. It's possible for this fuzzer to generate any 64-bit integer, signed or unsigned, but it favors smaller numbers.

intRange :: Int -> Int -> Fuzzer Int Source #

A fuzzer for int values between a given minimum and maximum value, inclusive.

float :: Fuzzer Float Source #

A fuzzer for float values. It will never produce NaN, Infinity, or -Infinity.

It's possible for this fuzzer to generate other floating-point value, but it favors smaller numbers.

floatRange :: Float -> Float -> Fuzzer Float Source #

A fuzzer for float values within between a given minimum and maximum value, inclusive.

percentage :: Fuzzer Float Source #

A fuzzer for percentage values. Generates random floats between 0.0 and 1.0.

text :: Fuzzer Text Source #

Generates random printable ASCII strings of up to 1000 characters.

Shorter strings are more common, especially the empty string.

bool :: Fuzzer Bool Source #

A fuzzer for boolean values. It's useful when building up fuzzers of complex types that contain a boolean somewhere.

maybe :: Fuzzer a -> Fuzzer (Maybe a) Source #

Given a fuzzer of a type, create a fuzzer of a maybe for that type.

result :: Fuzzer error -> Fuzzer value -> Fuzzer (Result error value) Source #

Given fuzzers for an error type and a success type, create a fuzzer for a result.

list :: Fuzzer a -> Fuzzer (List a) Source #

Given a fuzzer of a type, create a fuzzer of a list of that type. Generates random lists of varying length, favoring shorter lists.

array :: Fuzzer a -> Fuzzer (Array a) Source #

Given a fuzzer of a type, create a fuzzer of an array of that type. Generates random arrays of varying length, favoring shorter arrays.

Working with Fuzzers

data Fuzzer a Source #

A Fuzzer a knows how to produce random values of a and how to "shrink" a value of a, that is turn a value into another that is slightly simpler.

Instances

Instances details
Functor Fuzzer Source # 
Instance details

Defined in Test.Internal

Methods

fmap :: (a -> b) -> Fuzzer a -> Fuzzer b #

(<$) :: a -> Fuzzer b -> Fuzzer a #

Applicative Fuzzer Source # 
Instance details

Defined in Test.Internal

Methods

pure :: a -> Fuzzer a #

(<*>) :: Fuzzer (a -> b) -> Fuzzer a -> Fuzzer b #

liftA2 :: (a -> b -> c) -> Fuzzer a -> Fuzzer b -> Fuzzer c #

(*>) :: Fuzzer a -> Fuzzer b -> Fuzzer b #

(<*) :: Fuzzer a -> Fuzzer b -> Fuzzer a #

oneOf :: List (Fuzzer a) -> Fuzzer a Source #

Choose one of the given fuzzers at random. Each fuzzer has an equal chance of being chosen; to customize the probabilities, use frequency.

constant :: a -> Fuzzer a Source #

Create a fuzzer that only and always returns the value provided, and performs no shrinking. This is hardly random, and so this function is best used as a helper when creating more complicated fuzzers.

frequency :: List (Float, Fuzzer a) -> Fuzzer a Source #

Create a new Fuzzer by providing a list of probabilistic weights to use with other fuzzers. For example, to create a Fuzzer that has a 1/4 chance of generating an int between -1 and -100, and a 3/4 chance of generating one between 1 and 100, you could do this:

Fuzz.frequency
    [ ( 1, Fuzz.intRange -100 -1 )
    , ( 3, Fuzz.intRange 1 100 )
    ]

There are a few circumstances in which this function will return an invalid fuzzer, which causes it to fail any test that uses it:

  • If you provide an empty list of frequencies
  • If any of the weights are less than 0
  • If the weights sum to 0
  • Be careful recursively using this fuzzer in its arguments. Often using map is a better way to do what you want. If you are fuzzing a tree-like data structure, you should include a depth limit so to avoid infinite recursion, like so:
data Tree
      = Leaf
      | Branch Tree Tree

tree :: Int -> Fuzzer Tree
tree i =
    if i <= 0 then
        Fuzz.constant Leaf

    else
        Fuzz.frequency
            [ ( 1, Fuzz.constant Leaf )
            , ( 2, Fuzz.map2 Branch (tree (i - 1)) (tree (i - 1)) )
            ]

Tuple Fuzzers

tuple :: (Fuzzer a, Fuzzer b) -> Fuzzer (a, b) Source #

Turn a tuple of fuzzers into a fuzzer of tuples.

tuple3 :: (Fuzzer a, Fuzzer b, Fuzzer c) -> Fuzzer (a, b, c) Source #

Turn a 3-tuple of fuzzers into a fuzzer of 3-tuples.

Uncommon Fuzzers

char :: Fuzzer Char Source #

A fuzzer for char values. Generates random ascii chars disregarding the control characters and the extended character set.

unit :: Fuzzer () Source #

A fuzzer for the unit value. Unit is a type with only one value, commonly used as a placeholder.

order :: Fuzzer Ordering Source #

A fuzzer for order values.