{-| Module : Test.Aeson.Internal.RandomSamples Description : Types and functions to faciliate sampling Copyright : (c) Plow Technologies, 2016 License : BSD3 Maintainer : mchaver@gmail.com Stability : Beta Internal module, use at your own risk. -} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE ScopedTypeVariables #-} module Test.Aeson.Internal.RandomSamples where import Control.Exception import Data.Aeson import Data.ByteString.Lazy (ByteString) import GHC.Generics import Test.QuickCheck import Test.QuickCheck.Gen import Test.QuickCheck.Random -- | RandomSamples, using a seed allows you to replicate an arbitrary. By -- storing the seed and the samples (previously produced arbitraries), we can -- try to reproduce the same samples by generating the arbitraries with a seed. data RandomSamples a = RandomSamples { seed :: Int , samples :: [a] } deriving (Eq, Ord, Show, Generic) instance FromJSON a => FromJSON (RandomSamples a) instance ToJSON a => ToJSON (RandomSamples a) -- | Apply the seed. setSeed :: Int -> Gen a -> Gen a setSeed rSeed (MkGen g) = MkGen $ \ _randomSeed size -> g (mkQCGen rSeed) size -- | Reads the seed without looking at the samples. readSeed :: ByteString -> IO Int readSeed s = case eitherDecode s :: Either String (RandomSamples Value) of Right rSamples -> return $ seed rSamples Left err -> throwIO $ ErrorCall err -- | Read the sample size. readSampleSize :: ByteString -> IO Int readSampleSize s = case eitherDecode s :: Either String (RandomSamples Value) of Right rSamples -> return . length . samples $ rSamples Left err -> throwIO $ ErrorCall err