Safe Haskell | None |
---|---|
Language | Haskell2010 |
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)
but this is tedious and inefficient.suchThat
isValid
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
- module Data.Validity
- class GenUnchecked a where
- class (Validity a, GenUnchecked a) => GenValid a where
- class (Validity a, GenUnchecked a) => GenInvalid a where
- upTo :: Int -> Gen Int
- genSplit :: Int -> Gen (Int, Int)
- genSplit3 :: Int -> Gen (Int, Int, Int)
- arbPartition :: Int -> Gen [Int]
- genListOf :: Gen a -> Gen [a]
- class GGenUnchecked f where
Documentation
module Data.Validity
class GenUnchecked a where #
A class of types for which truly arbitrary values can be generated.
Instances
GenUnchecked Bool # | |
GenUnchecked Char # | |
GenUnchecked Double # | |
GenUnchecked Float # | |
GenUnchecked Int # | |
GenUnchecked Integer # | |
GenUnchecked Ordering # | |
GenUnchecked Word # | |
GenUnchecked Word8 # | |
GenUnchecked Word16 # | |
GenUnchecked () # | |
GenUnchecked a => GenUnchecked [a] # | |
GenUnchecked a => GenUnchecked (Maybe a) # | |
GenUnchecked (Ratio Integer) # | |
HasResolution a => GenUnchecked (Fixed a) # | |
(GenUnchecked a, GenUnchecked b) => GenUnchecked (Either a b) # | |
(GenUnchecked a, GenUnchecked b) => GenUnchecked (a, b) # | |
(GenUnchecked a, GenUnchecked b, GenUnchecked c) => GenUnchecked (a, b, c) # | |
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
.
Instances
GenValid Bool # | |
GenValid Char # | |
GenValid Double # | |
GenValid Float # | |
GenValid Int # | |
GenValid Integer # | |
GenValid Ordering # | |
GenValid Word # | |
GenValid Word8 # | |
GenValid Word16 # | |
GenValid () # | |
GenValid a => GenValid [a] # | If we can generate values of a certain type, we can also generate lists of them. |
GenValid a => GenValid (Maybe a) # | |
GenValid (Ratio Integer) # | |
HasResolution a => GenValid (Fixed a) # | |
(GenValid a, GenValid b) => GenValid (Either a b) # | |
(GenValid a, GenValid b) => GenValid (a, b) # | |
(GenValid a, GenValid b, GenValid c) => GenValid (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 |
GenInvalid Float # | Either |
GenInvalid a => GenInvalid [a] # | This instance ensures that the generated list contains at least one element
that satisfies |
GenInvalid a => GenInvalid (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. |
(GenInvalid a, GenInvalid b) => GenInvalid (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. |
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
.
class GGenUnchecked f where #
Minimal complete definition
Methods
gGenUnchecked :: Gen (f a) #
Instances
GGenUnchecked U1 # | |
GenUnchecked a => GGenUnchecked (K1 i a) # | |
(GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:+:) a b) # | |
(GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:*:) a b) # | |
GGenUnchecked a => GGenUnchecked (M1 i c a) # | |