Safe Haskell | Safe |
---|---|

Language | Haskell2010 |

`GenValidity`

exists to make tests involving `Validity`

types easier and speed
up the generation of data for them.

Let's use the example from `Data.Validity`

again: A datatype that represents
primes.
To implement tests for this datatype, we would have to be able to generate
both primes and non-primes. We could do this with
`(Prime $ arbitrary) `

but this is tedious and inefficient.`suchThat`

isValid

The `GenValidity`

type class allows you to specify how to (efficiently)
generate data of the given type to allow for easier and quicker testing.
Just implementing `genUnchecked`

already gives you access to `genValid`

and
`genInvalid`

but writing custom implementations of these functions may speed
up the generation of data.

For example, to generate primes, we don't have to consider even numbers other than 2. A more efficient implementation could then look as follows:

instance GenValidity Prime where genUnchecked = Prime <$> arbitrary genValid = Prime <$> (oneof [ pure 2 , (\y -> 2 * y + 1) <$> (arbitrary `suchThat` (> 0) `suchThat` isPrime) ])

Typical examples of tests involving validity could look as follows:

it "succeeds when given valid input" $ do forAll genValid $ \input -> myFunction input `shouldSatisfy` isRight

it "produces valid output when it succeeds" $ do forAll genUnchecked $ \input -> case myFunction input of Nothing -> return () -- Can happen Just output -> output `shouldSatisfy` isValid

# Documentation

module Data.Validity

class Validity a => GenValidity a where Source #

A class of types for which `Validity`

-related values can be generated.

If you also write `Arbitrary`

instances for `GenValidity`

types, it may be
best to simply write `arbitrary = genValid`

.

genUnchecked :: Gen a Source #

Generate a truly arbitrary datum, this should cover all possible values in the type

Generate a valid datum, this should cover all possible valid values in the type

The default implementation is as follows:

genValid = genUnchecked `suchThat` isValid

To speed up testing, it may be a good idea to implement this yourself. If you do, make sure that it is possible to generate all possible valid data, otherwise your testing may not cover all cases.

genInvalid :: Gen a Source #

Generate an invalid datum, this should cover all possible invalid values

genInvalid = genUnchecked `suchThat` (not . isValid)

To speed up testing, it may be a good idea to implement this yourself. If you do, make sure that it is possible to generate all possible invalid data, otherwise your testing may not cover all cases.

GenValidity a => GenValidity [a] Source # | If we can generate values of a certain type, we can also generate lists of
them.
This instance ensures that |

GenValidity a => GenValidity (Maybe a) Source # | |

(GenValidity a, GenValidity b) => GenValidity (a, b) Source # | |

(GenValidity a, GenValidity b, GenValidity c) => GenValidity (a, b, c) Source # | |