{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Serokell.Arbitrary
( VariantNoBytes (..)
, VariantOnlyBytes (..)
) where
import Universum
import Data.ByteString as BS hiding (zip)
import Data.Vector (fromList)
import Test.QuickCheck (Arbitrary (..), Gen, choose, frequency, genericShrink, oneof, sized)
import Test.QuickCheck.Instances ()
import Serokell.Data.Variant.Variant (Variant (..))
import qualified Data.HashMap.Lazy as H (fromList)
import qualified Serokell.Util.Base64 as S
import qualified Serokell.Util.Verify as V
instance Arbitrary S.JsonByteString where
arbitrary = S.JsonByteString <$> (arbitrary :: Gen BS.ByteString)
newtype VariantNoBytes = NoBytes
{ getVariant :: Variant
} deriving (Show, Eq, Generic)
newtype VariantOnlyBytes = OnlyBytes
{ getVarBytes :: Variant
} deriving (Show, Eq, Generic)
instance Arbitrary VariantOnlyBytes where
arbitrary = OnlyBytes . VarBytes <$> arbitrary
shrink = genericShrink
instance Arbitrary VariantNoBytes where
arbitrary = NoBytes <$> (sized $ \n -> genVariant (n*50 + 1))
shrink = genericShrink
instance Arbitrary Variant where
arbitrary = sized $ \n -> genVariant (n*50 + 1)
shrink = genericShrink
genVariant :: Int -> Gen Variant
genVariant 1 = genFlatVariant
genVariant n = do
frequency
[ (3, genFlatVariant)
, (truncate (logBase 2 (fromIntegral n) :: Double),
oneof [genListVariant n, genMapVariant n])
]
genFlatVariant :: Gen Variant
genFlatVariant = oneof $
[ pure VarNone
, VarBool <$> arbitrary
, VarInt <$> arbitrary
, VarUInt <$> arbitrary
, VarFloat <$> arbitrary
, VarString <$> arbitrary
]
genBoundedVariants :: Int -> Gen [Variant]
genBoundedVariants 0 = return []
genBoundedVariants n = do
v_cons <- choose (1, n)
(:) <$> genVariant v_cons
<*> genBoundedVariants (n-v_cons)
genListVariant :: Int -> Gen Variant
genListVariant n = VarList . fromList <$> genBoundedVariants (n-1)
genMapVariant :: Int -> Gen Variant
genMapVariant n = do
varKeys <- genBoundedVariants ((n-1) `div` 2)
varVals <- genBoundedVariants ((n-1) `div` 2)
return $ VarMap $ H.fromList $ zip varKeys varVals
instance Arbitrary V.VerificationRes where
arbitrary = oneof $
[ pure V.VerSuccess
, V.VerFailure <$> arbitrary
]