serdoc-core-0.1.0.0: test/Data/SerDoc/Test/Info.hs
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.SerDoc.Test.Info
where
import Test.Tasty
import Test.Tasty.QuickCheck
import Data.SerDoc.Info
tests :: TestTree
tests = testGroup "Info"
[ testGroup "FieldSize"
[ testProperty "KnownFieldSize" pKnownFieldSizeKnown
, testProperty "FieldSizeWithinExpectedLimits" pFieldSizeWithinExpectedLimits
]
]
pKnownFieldSizeKnown :: KnownFieldSize -> Property
pKnownFieldSizeKnown (KnownFieldSize _ s) =
knownSize s =/= Nothing
pFieldSizeWithinExpectedLimits :: AnyFieldSize -> Property
pFieldSizeWithinExpectedLimits (AnyFieldSize size s) =
let actual = knownSize s
in
case actual of
Nothing -> label "unknown size" $ property True
Just actualSize -> do
label "known size" . property $ actualSize <= size
-- * Helpers
data KnownFieldSize = KnownFieldSize Int FieldSize
deriving (Show, Eq)
data AnyFieldSize = AnyFieldSize Int FieldSize
deriving (Show, Eq)
instance Arbitrary KnownFieldSize where
arbitrary = getSize >>= genKnownFieldSize
shrink (KnownFieldSize size s) = KnownFieldSize size <$> shrinkFieldSize s
instance Arbitrary AnyFieldSize where
arbitrary = do
size <- getSize
AnyFieldSize size <$> genFieldSize False size
shrink (AnyFieldSize size s) = AnyFieldSize size <$> shrinkFieldSize s
shrinkFieldSize :: FieldSize -> [FieldSize]
shrinkFieldSize UnknownSize =
[]
shrinkFieldSize (VarSize name) =
VarSize <$> shrink name
shrinkFieldSize (FixedSize n) =
FixedSize <$> shrink n
shrinkFieldSize (RangeSize a b) =
fmap (\b' -> RangeSize a b') (shrinkFieldSize b) ++
fmap (\a' -> RangeSize a' b) (shrinkFieldSize a) ++
[ a, b ]
shrinkFieldSize (BinopSize op a b) =
fmap (\b' -> BinopSize op a b') (shrinkFieldSize b) ++
fmap (\a' -> BinopSize op a' b) (shrinkFieldSize a) ++
[ a, b ]
shrinkFieldSize EnumSize =
[]
genFieldSize :: Bool -> Int -> Gen FieldSize
genFieldSize onlyKnown n
= oneof $
[ return $ FixedSize n ] ++
[ VarSize <$> arbitrary
| not onlyKnown
] ++
[ pure UnknownSize
| not onlyKnown
] ++
[ do
a <- chooseInt (1, n - 1)
RangeSize
<$> genFieldSize onlyKnown a
<*> genFieldSize onlyKnown (n - 1)
| n > 1
, not onlyKnown
] ++
[ do
a <- chooseInt (1, n - 1)
BinopSize FSPlus
<$> genFieldSize onlyKnown a
<*> genFieldSize onlyKnown (n - a)
| n >= 1
] ++
[ do
a <- chooseInt (2, n - 1)
BinopSize FSMul
<$> genFieldSize onlyKnown a
<*> genFieldSize onlyKnown (n `div` a)
| n >= 2
] ++
[ do
a <- chooseInt (1, n - 1)
BinopSize FSMax
<$> genFieldSize onlyKnown a
<*> genFieldSize onlyKnown (n - 1)
| n >= 1
] ++
[ do
a <- chooseInt (1, n - 1)
BinopSize FSMax
<$> genFieldSize onlyKnown (n - 1)
<*> genFieldSize onlyKnown a
| n >= 1
] ++
[ do
a <- chooseInt (1, n - 1)
BinopSize FSMin
<$> genFieldSize onlyKnown (n - 1)
<*> genFieldSize onlyKnown a
| n >= 1
] ++
[ do
a <- chooseInt (1, n - 1)
BinopSize FSMin
<$> genFieldSize onlyKnown a
<*> genFieldSize onlyKnown (n - 1)
| n >= 1
]
genKnownFieldSize :: Int -> Gen KnownFieldSize
genKnownFieldSize size = KnownFieldSize size <$> genFieldSize True size
genField :: Int -> Gen (FieldInfo codec)
genField 0 = genConstBasicField
genField fuel =
oneof
[ genConstBasicField
, genAnnField fuel
]
genConstBasicField :: Gen (FieldInfo codec)
genConstBasicField =
basicField <$> arbitrary <*> (FixedSize <$> arbitrarySizedNatural)
genAnnField :: Int -> Gen (FieldInfo codec)
genAnnField fuel =
annField <$> arbitrary <*> genField (fuel - 1)