genvalidity-0.3.2.0: Testing utilities for the validity library

Safe HaskellNone
LanguageHaskell2010

Data.GenValidity

Description

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) suchThat isValid but this is tedious and inefficient.

The GenValid type class allows you to specify how to (efficiently) generate valid data of the given type to allow for easier and quicker testing. Just instantiating GenUnchecked already gives you access to a default instance of 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 GenUnchecked Prime where
    genUnchecked = Prime <$> arbitrary
instance GenValid Prime where
    genValid = Prime <$>
       (oneof
         [ pure 2
         , ((\y -> 2 * abs y + 1) <$> arbitrary) `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

Synopsis

Documentation

class GenUnchecked a where #

A class of types for which truly arbitrary values can be generated.

class (Validity a, GenUnchecked a) => GenValid a where #

A class of types for which valid values can be generated.

If you also write Arbitrary instances for GenValid types, it may be best to simply write arbitrary = genValid.

Methods

genValid :: Gen a #

Instances

GenValid Bool # 

Methods

genValid :: Gen Bool #

GenValid Char # 

Methods

genValid :: Gen Char #

GenValid Double # 

Methods

genValid :: Gen Double #

GenValid Float # 

Methods

genValid :: Gen Float #

GenValid Int # 

Methods

genValid :: Gen Int #

GenValid Integer # 

Methods

genValid :: Gen Integer #

GenValid Ordering # 
GenValid Word # 

Methods

genValid :: Gen Word #

GenValid Word8 # 

Methods

genValid :: Gen Word8 #

GenValid Word16 # 

Methods

genValid :: Gen Word16 #

GenValid () # 

Methods

genValid :: Gen () #

GenValid a => GenValid [a] #

If we can generate values of a certain type, we can also generate lists of them.

Methods

genValid :: Gen [a] #

GenValid a => GenValid (Maybe a) # 

Methods

genValid :: Gen (Maybe a) #

GenValid (Ratio Integer) # 

Methods

genValid :: Gen (Ratio Integer) #

HasResolution a => GenValid (Fixed a) # 

Methods

genValid :: Gen (Fixed a) #

(GenValid a, GenValid b) => GenValid (Either a b) # 

Methods

genValid :: Gen (Either a b) #

(GenValid a, GenValid b) => GenValid (a, b) # 

Methods

genValid :: Gen (a, b) #

(GenValid a, GenValid b, GenValid c) => GenValid (a, b, c) # 

Methods

genValid :: Gen (a, b, c) #

class (Validity a, GenUnchecked a) => GenInvalid a where #

A class of types for which invalid values can be generated.

Methods

genInvalid :: Gen a #

Instances

GenInvalid Double #

Either NaN or Infinity.

GenInvalid Float #

Either NaN or Infinity.

Methods

genInvalid :: Gen Float #

GenInvalid a => GenInvalid [a] #

This instance ensures that the generated list contains at least one element that satisfies isInvalid. The rest is unchecked.

Methods

genInvalid :: Gen [a] #

GenInvalid a => GenInvalid (Maybe a) # 

Methods

genInvalid :: Gen (Maybe a) #

(GenInvalid a, GenInvalid b) => GenInvalid (Either a b) #

This instance ensures that the generated tupse contains at least one invalid element. The other element is unchecked.

Methods

genInvalid :: Gen (Either a b) #

(GenInvalid a, GenInvalid b) => GenInvalid (a, b) # 

Methods

genInvalid :: Gen (a, b) #

(GenInvalid a, GenInvalid b, GenInvalid c) => GenInvalid (a, b, c) #

This instance ensures that the generated triple contains at least one invalid element. The other two are unchecked.

Methods

genInvalid :: Gen (a, b, c) #

upTo :: Int -> Gen Int #

upTo generates an integer between 0 (inclusive) and n.

genSplit :: Int -> Gen (Int, Int) #

'genSplit a' generates a tuple '(b, c)' such that 'b + c' equals a.

genSplit3 :: Int -> Gen (Int, Int, Int) #

'genSplit a' generates a triple '(b, c, d)' such that 'b + c + d' equals a.

arbPartition :: Int -> Gen [Int] #

'arbPartition n' generates a list ls such that 'sum ls' equals n.

genListOf :: Gen a -> Gen [a] #

A version of listOf that takes size into account more accurately.

class GGenUnchecked f where #

Minimal complete definition

gGenUnchecked

Methods

gGenUnchecked :: Gen (f a) #

Instances

GGenUnchecked U1 # 

Methods

gGenUnchecked :: Gen (U1 a) #

GenUnchecked a => GGenUnchecked (K1 i a) # 

Methods

gGenUnchecked :: Gen (K1 i a a) #

(GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:+:) a b) # 

Methods

gGenUnchecked :: Gen ((a :+: b) a) #

(GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:*:) a b) # 

Methods

gGenUnchecked :: Gen ((a :*: b) a) #

GGenUnchecked a => GGenUnchecked (M1 i c a) # 

Methods

gGenUnchecked :: Gen (M1 i c a a) #