analyze-0.1.0.0: test/Generation.hs
module Generation where
import Analyze.Common (Data, makeLookup)
import Analyze.RFrame (RFrame (..))
import Analyze.Values
import Data.HashSet (HashSet)
import qualified Data.HashSet as HS
import Data.Text (Text)
import qualified Data.Text as T
import Data.Vector (Vector)
import qualified Data.Vector as V
import Test.QuickCheck
distinctGenSized :: Data k => Gen k -> Int -> Gen (HashSet k)
distinctGenSized = go HS.empty
where
go s g i | i <= 0 = pure s
| otherwise = do
k <- g `suchThat` \k' -> not (HS.member k' s)
go (HS.insert k s) g (i - 1)
distinctGen :: Data k => Gen k -> Gen (HashSet k)
distinctGen = sized . distinctGenSized
declGenSized :: Data k => Gen k -> Gen t -> Int -> Gen (Vector (k, t))
declGenSized kg tg i = do
nameSet <- distinctGen kg
let nameVec = V.fromList (HS.toList nameSet)
valueTypeVec <- V.replicateM i tg
pure (V.zip nameVec valueTypeVec)
declGen :: Data k => Gen k -> Gen t -> Gen (Vector (k, t))
declGen kg tg = sized (declGenSized kg tg)
rframeGenSized :: Data k => (t -> Gen v) -> Vector (k, t) -> Int -> Gen (RFrame k v)
rframeGenSized prod decl numRows = gen
where
rowGen = sequenceA (prod . snd <$> decl)
allRowsGen = V.replicateM numRows rowGen
keys = fst <$> decl
gen = RFrame keys (makeLookup keys) <$> allRowsGen
rframeGen :: Data k => (t -> Gen v) -> Vector (k, t) -> Gen (RFrame k v)
rframeGen prod decl = sized (rframeGenSized prod decl)
-- Specifics
nameGen :: Gen Text
nameGen = T.pack <$> listOf (choose ('a', 'z'))
valueGen :: ValueType -> Gen Value
valueGen ValueTypeText = ValueText <$> nameGen
valueGen ValueTypeInteger = ValueInteger <$> arbitrary
valueGen ValueTypeDouble = ValueDouble <$> arbitrary
valueTypeGen :: Gen ValueType
valueTypeGen = arbitraryBoundedEnum
valueDeclGen :: Gen (Vector (Text, ValueType))
valueDeclGen = declGen nameGen valueTypeGen
valueRFrameGen :: Gen (RFrame Text Value)
valueRFrameGen = valueDeclGen >>= rframeGen valueGen