| 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 <$> arbitraryinstance 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
forAllValid $ \input ->
myFunction input `shouldSatisfy` isRightit "produces valid output when it succeeds" $ do
forAllUnchecked $ \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
- shrinkT2 :: (a -> [a]) -> (a, a) -> [(a, a)]
- shrinkT3 :: (a -> [a]) -> (a, a, a) -> [(a, a, a)]
- upTo :: Int -> Gen Int
- genSplit :: Int -> Gen (Int, Int)
- genSplit3 :: Int -> Gen (Int, Int, Int)
- genSplit4 :: Int -> Gen (Int, Int, Int, Int)
- arbPartition :: Int -> Gen [Int]
- genListOf :: Gen a -> Gen [a]
- class GGenUnchecked f where
- gShrinkUnchecked :: (Generic a, GUncheckedRecursivelyShrink (Rep a), GUncheckedSubterms (Rep a) a) => a -> [a]
- uncheckedRecursivelyShrink :: (Generic a, GUncheckedRecursivelyShrink (Rep a)) => a -> [a]
- class GUncheckedRecursivelyShrink f where
- uncheckedSubterms :: (Generic a, GUncheckedSubterms (Rep a) a) => a -> [a]
- class GUncheckedSubterms f a where
- class GUncheckedSubtermsIncl f a where
Documentation
module Data.Validity
class GenUnchecked a where Source #
A class of types for which truly arbitrary values can be generated.
Automatic instances with Generic
An instance of this class can be made automatically if the type in question
has a Generic instance. This instance will try to use genUnchecked to
generate all structural sub-parts of the value that is being generated.
Example:
{-# LANGUAGE DeriveGeneric #-}
data MyType = MyType Double String
deriving (Show, Eq, Generic)
instance GenUnchecked MyTypegenerates something like:
instance GenUnchecked MyType where
genUnchecked = MyType <$> genUnchecked <*> genUncheckedMethods
genUnchecked :: Gen a Source #
genUnchecked :: (Generic a, GGenUnchecked (Rep a)) => Gen a Source #
shrinkUnchecked :: a -> [a] Source #
shrinkUnchecked :: (Generic a, GUncheckedRecursivelyShrink (Rep a), GUncheckedSubterms (Rep a) a) => a -> [a] Source #
Instances
class (Validity a, GenUnchecked a) => GenValid a where Source #
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 Source # | |
| GenValid Char Source # | |
| GenValid Double Source # | |
| GenValid Float Source # | |
| GenValid Int Source # | |
| GenValid Int8 Source # | |
| GenValid Int16 Source # | |
| GenValid Int32 Source # | |
| GenValid Int64 Source # | |
| GenValid Integer Source # | |
| GenValid Ordering Source # | |
| GenValid Word Source # | |
| GenValid Word8 Source # | |
| GenValid Word16 Source # | |
| GenValid Word32 Source # | |
| GenValid Word64 Source # | |
| GenValid () Source # | |
| GenValid a => GenValid [a] Source # | If we can generate values of a certain type, we can also generate lists of them. |
| GenValid a => GenValid (Maybe a) Source # | |
| (Integral a, Num a, Ord a, GenValid a) => GenValid (Ratio a) Source # | |
| HasResolution a => GenValid (Fixed a) Source # | |
| GenValid a => GenValid (NonEmpty a) Source # | |
| (GenValid a, GenValid b) => GenValid (Either a b) Source # | |
| (GenValid a, GenValid b) => GenValid (a, b) Source # | |
| (GenValid a, GenValid b, GenValid c) => GenValid (a, b, c) Source # | |
| (GenValid a, GenValid b, GenValid c, GenValid d) => GenValid (a, b, c, d) Source # | |
class (Validity a, GenUnchecked a) => GenInvalid a where Source #
A class of types for which invalid values can be generated.
Instances
| GenInvalid Double Source # | Either |
| GenInvalid Float Source # | Either |
| GenInvalid a => GenInvalid [a] Source # | This instance ensures that the generated list contains at least one element
that satisfies |
| GenInvalid a => GenInvalid (Maybe a) Source # | |
| (Integral a, Num a, Ord a, GenValid a) => GenInvalid (Ratio a) Source # | |
| GenInvalid a => GenInvalid (NonEmpty a) Source # | |
| (GenInvalid a, GenInvalid b) => GenInvalid (Either a b) Source # | 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) Source # | |
| (GenInvalid a, GenInvalid b, GenInvalid c) => GenInvalid (a, b, c) Source # | This instance ensures that the generated triple contains at least one invalid element. The other two are unchecked. |
| (GenInvalid a, GenInvalid b, GenInvalid c, GenInvalid d) => GenInvalid (a, b, c, d) Source # | This instance ensures that the generated triple contains at least one invalid element. The other two are unchecked. |
genSplit :: Int -> Gen (Int, Int) Source #
'genSplit a' generates a tuple '(b, c)' such that 'b + c' equals a.
genSplit3 :: Int -> Gen (Int, Int, Int) Source #
'genSplit3 a' generates a triple '(b, c, d)' such that 'b + c + d' equals a.
genSplit4 :: Int -> Gen (Int, Int, Int, Int) Source #
'genSplit4 a' generates a quadruple '(b, c, d, e)' such that 'b + c + d + e' equals a.
arbPartition :: Int -> Gen [Int] Source #
'arbPartition n' generates a list ls such that 'sum ls' equals n.
genListOf :: Gen a -> Gen [a] Source #
A version of listOf that takes size into account more accurately.
class GGenUnchecked f where Source #
Minimal complete definition
Methods
gGenUnchecked :: Gen (f a) Source #
Instances
| GGenUnchecked (U1 *) Source # | |
| GenUnchecked a => GGenUnchecked (K1 * i a) Source # | |
| (GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:+:) * a b) Source # | |
| (GGenUnchecked a, GGenUnchecked b) => GGenUnchecked ((:*:) * a b) Source # | |
| GGenUnchecked a => GGenUnchecked (M1 * i c a) Source # | |
gShrinkUnchecked :: (Generic a, GUncheckedRecursivelyShrink (Rep a), GUncheckedSubterms (Rep a) a) => a -> [a] Source #
Shrink a term to any of its immediate subterms, and also recursively shrink all subterms.
uncheckedRecursivelyShrink :: (Generic a, GUncheckedRecursivelyShrink (Rep a)) => a -> [a] Source #
Recursively shrink all immediate uncheckedSubterms.
class GUncheckedRecursivelyShrink f where Source #
Minimal complete definition
Methods
gUncheckedRecursivelyShrink :: f a -> [f a] Source #
Instances
| GUncheckedRecursivelyShrink (V1 *) Source # | |
| GUncheckedRecursivelyShrink (U1 *) Source # | |
| GenUnchecked a => GUncheckedRecursivelyShrink (K1 * i a) Source # | |
| (GUncheckedRecursivelyShrink f, GUncheckedRecursivelyShrink g) => GUncheckedRecursivelyShrink ((:+:) * f g) Source # | |
| (GUncheckedRecursivelyShrink f, GUncheckedRecursivelyShrink g) => GUncheckedRecursivelyShrink ((:*:) * f g) Source # | |
| GUncheckedRecursivelyShrink f => GUncheckedRecursivelyShrink (M1 * i c f) Source # | |
uncheckedSubterms :: (Generic a, GUncheckedSubterms (Rep a) a) => a -> [a] Source #
All immediate uncheckedSubterms of a term.
class GUncheckedSubterms f a where Source #
Minimal complete definition
Methods
gUncheckedSubterms :: f a -> [a] Source #
Instances
| GUncheckedSubterms (V1 *) a Source # | |
| GUncheckedSubterms (U1 *) a Source # | |
| GUncheckedSubterms (K1 * i a) b Source # | |
| (GUncheckedSubtermsIncl f a, GUncheckedSubtermsIncl g a) => GUncheckedSubterms ((:+:) * f g) a Source # | |
| (GUncheckedSubtermsIncl f a, GUncheckedSubtermsIncl g a) => GUncheckedSubterms ((:*:) * f g) a Source # | |
| GUncheckedSubterms f a => GUncheckedSubterms (M1 * i c f) a Source # | |
class GUncheckedSubtermsIncl f a where Source #
Minimal complete definition
Methods
gUncheckedSubtermsIncl :: f a -> [a] Source #
Instances
| GUncheckedSubtermsIncl (V1 *) a Source # | |
| GUncheckedSubtermsIncl (U1 *) a Source # | |
| GUncheckedSubtermsIncl (K1 * i a) b Source # | |
| GUncheckedSubtermsIncl (K1 * i a) a Source # | |
| (GUncheckedSubtermsIncl f a, GUncheckedSubtermsIncl g a) => GUncheckedSubtermsIncl ((:+:) * f g) a Source # | |
| (GUncheckedSubtermsIncl f a, GUncheckedSubtermsIncl g a) => GUncheckedSubtermsIncl ((:*:) * f g) a Source # | |
| GUncheckedSubtermsIncl f a => GUncheckedSubtermsIncl (M1 * i c f) a Source # | |