{- | Generators for test data types.
-}
module Test.Gen
( Property
, genValidation
, genValidationList
, genFunction
, genFunction2
, genInt
, genSmallInt
, genSmallText
, genSmallList
, genEither
) where
import Data.Text (Text)
import Hedgehog (Gen, MonadGen, PropertyT)
import Validation (Validation (..))
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
-- | Helper alias for tests.
type Property = PropertyT IO ()
-- | Generate a simple unary function from the list.
genFunction :: Gen (Int -> Int)
genFunction = genInt >>= \n -> Gen.element
[ id
, (+ n)
, (* n)
, const n
, (n -)
, subtract n
]
-- | Generate a simple binary function from the list.
genFunction2 :: Gen (Int -> Int -> Int)
genFunction2 = Gen.element
[ const
, (+)
, (*)
, (-)
, subtract
]
-- | Generate an 'Int'.
genInt :: Gen Int
genInt = Gen.enumBounded
-- | Generate a positive 'Int' within the range of @1-6@.
genSmallInt :: Gen Int
genSmallInt = Gen.int (Range.linear 1 6)
-- | Generate a 'Text' of length @0-10@.
genSmallText :: Gen Text
genSmallText = Gen.text (Range.linear 0 10) Gen.unicode
-- | Generate a small list of the given generated elements.
genSmallList :: Gen a -> Gen [a]
genSmallList = Gen.list (Range.linear 0 6)
-- | Generate a 'Validation'.
genValidation :: Gen a -> Gen (Validation [Text] a)
genValidation gen = Gen.choice
[ Success <$> gen
, Failure <$> genSmallList genSmallText
]
-- | Generate 'Either' with more frequent 'Right's.
genEither :: MonadGen m => m e -> m a -> m (Either e a)
genEither genE genA = Gen.sized $ \n -> Gen.frequency
[ (2, Left <$> genE)
, (1 + fromIntegral n, Right <$> genA)
]
-- | Generate a list of 'Validation's.
genValidationList :: Gen a -> Gen [Validation [Text] a]
genValidationList = Gen.list (Range.linear 0 200) . genValidation