hschema-quickcheck-0.0.1.0: src/Test/Schema/QuickCheck/Internal/Gen.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Test.Schema.QuickCheck.Internal.Gen
( ToGen (..)
) where
import Control.Applicative (liftA2)
import Control.Applicative.Free
import Control.Functor.HigherOrder
import Control.Lens
import Control.Monad (liftM)
import Control.Natural
import Data.Functor.Sum
import qualified Data.HashMap.Strict as Map
import qualified Data.List.NonEmpty as NEL
import Data.Schema.Internal.Types
import qualified Data.Vector as Vector
import Test.QuickCheck (Gen)
import qualified Test.QuickCheck as Gen
optGen :: Gen a -> Gen (Maybe a)
optGen base = Gen.frequency [(1, return Nothing), (3, liftM Just base)]
class ToGen a where
toGen :: a ~> Gen
instance (ToGen p, ToGen q) => ToGen (Sum p q) where
toGen (InL l) = toGen l
toGen (InR r) = toGen r
genAlg :: ToGen p => HAlgebra (SchemaF p) Gen
genAlg = wrapNT $ \case
PrimitiveSchema p -> toGen p
RecordSchema (Field flds) -> runAp genField flds
where genField :: FieldDef o Gen a -> Gen a
genField (RequiredField _ g _) = g
genField (OptionalField _ g _) = optGen g
UnionSchema alts -> Gen.oneof . NEL.toList $ fmap genAlt alts
where genAlt :: AltDef Gen a -> Gen a
genAlt (AltDef _ genSingle pr) = (view $ re pr) <$> genSingle
AliasSchema base iso -> view iso <$> base
instance ToGen s => ToGen (Schema s) where
toGen schema = (cataNT genAlg) (unwrapSchema schema)