{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.Binary.Vintage.SizeBounds (tests) where

import Cardano.Ledger.Binary
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Map as M
import Data.Proxy (Proxy (Proxy))
import Data.Tagged (Tagged (..))
import qualified Data.Text as T
import Data.Typeable (typeRep)
import Data.Word (Word32, Word8)
import Hedgehog (Gen, Group (..), checkParallel)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Test.Cardano.Ledger.Binary.Vintage.Helpers

tests :: IO Bool
tests :: IO Bool
tests =
  let listOf :: Gen a -> Gen [a]
      listOf :: forall a. Gen a -> Gen [a]
listOf = Range Int -> GenT Identity a -> GenT Identity [a]
forall (m :: * -> *) a. MonadGen m => Range Int -> m a -> m [a]
Gen.list (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
0 Int
300)
   in Group -> IO Bool
forall (m :: * -> *). MonadIO m => Group -> m Bool
checkParallel (Group -> IO Bool) -> Group -> IO Bool
forall a b. (a -> b) -> a -> b
$
        GroupName -> [(PropertyName, Property)] -> Group
Group
          GroupName
"Encoded size bounds for core types."
          [ (PropertyName
"()", SizeTestConfig () -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig () -> Property) -> SizeTestConfig () -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig ()
forall a. Show a => SizeTestConfig a
scfg {gen = pure (), precise = True})
          , (PropertyName
"Bool", SizeTestConfig Bool -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Bool -> Property)
-> SizeTestConfig Bool -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Bool
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.bool, precise = True})
          , (PropertyName
"Word", SizeTestConfig Word -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Word -> Property)
-> SizeTestConfig Word -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Word
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.word Range.exponentialBounded})
          , (PropertyName
"Word8", SizeTestConfig Word8 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Word8 -> Property)
-> SizeTestConfig Word8 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Word8
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.word8 Range.exponentialBounded})
          , (PropertyName
"Word16", SizeTestConfig Word16 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Word16 -> Property)
-> SizeTestConfig Word16 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Word16
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.word16 Range.exponentialBounded})
          , (PropertyName
"Word32", SizeTestConfig Word32 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Word32 -> Property)
-> SizeTestConfig Word32 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Word32
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.word32 Range.exponentialBounded})
          , (PropertyName
"Word64", SizeTestConfig Word64 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Word64 -> Property)
-> SizeTestConfig Word64 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Word64
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.word64 Range.exponentialBounded})
          , (PropertyName
"Int", SizeTestConfig Int -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Int -> Property) -> SizeTestConfig Int -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Int
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.int Range.exponentialBounded})
          ,
            ( PropertyName
"Int (precision)"
            , SizeTestConfig Int -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Int -> Property) -> SizeTestConfig Int -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig Int
forall a. Buildable a => SizeTestConfig a
cfg
                  { gen = Gen.int Range.exponentialBounded
                  , computedCtx = \Int
x ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy Int -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Int)
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Integer -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer
forall s a. (Integral s, Integral a) => s -> a
withWordSize Int
x :: Integer)
                          )
                        ]
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"Float"
            , SizeTestConfig Float -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Float -> Property)
-> SizeTestConfig Float -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig Float
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.float (Range.exponentialFloat (-1000000) 1000000)}
            )
          , (PropertyName
"Int32", SizeTestConfig Int32 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Int32 -> Property)
-> SizeTestConfig Int32 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Int32
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.int32 Range.exponentialBounded})
          , (PropertyName
"Int64", SizeTestConfig Int64 -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Int64 -> Property)
-> SizeTestConfig Int64 -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Int64
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.int64 Range.exponentialBounded})
          ,
            ( PropertyName
"Tagged () Word32"
            , SizeTestConfig (Tagged () Word32) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Tagged () Word32) -> Property)
-> SizeTestConfig (Tagged () Word32) -> Property
forall a b. (a -> b) -> a -> b
$
                (forall a. Show a => SizeTestConfig a
scfg @(Tagged () Word32))
                  { gen = Tagged <$> Gen.word32 Range.exponentialBounded
                  }
            )
          ,
            ( PropertyName
"(Bool, Bool)"
            , SizeTestConfig (Bool, Bool) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Bool, Bool) -> Property)
-> SizeTestConfig (Bool, Bool) -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig (Bool, Bool)
forall a. Show a => SizeTestConfig a
scfg {gen = (,) <$> Gen.bool <*> Gen.bool, precise = True}
            )
          ,
            ( PropertyName
"(Bool, Bool, Bool)"
            , SizeTestConfig (Bool, Bool, Bool) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Bool, Bool, Bool) -> Property)
-> SizeTestConfig (Bool, Bool, Bool) -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig (Bool, Bool, Bool)
forall a. Show a => SizeTestConfig a
scfg
                  { gen = (,,) <$> Gen.bool <*> Gen.bool <*> Gen.bool
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"(Bool, Bool, Bool, Bool)"
            , SizeTestConfig (Bool, Bool, Bool, Bool) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Bool, Bool, Bool, Bool) -> Property)
-> SizeTestConfig (Bool, Bool, Bool, Bool) -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig (Bool, Bool, Bool, Bool)
forall a. Show a => SizeTestConfig a
scfg
                  { gen = (,,,) <$> Gen.bool <*> Gen.bool <*> Gen.bool <*> Gen.bool
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"ByteString"
            , SizeTestConfig ByteString -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig ByteString -> Property)
-> SizeTestConfig ByteString -> Property
forall a b. (a -> b) -> a -> b
$
                (forall a. Show a => SizeTestConfig a
scfg @BS.ByteString)
                  { debug = show . (BS.unpack :: BS.ByteString -> [Word8])
                  , gen = Gen.bytes (Range.linear 0 1000)
                  , computedCtx = \ByteString
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf ByteString) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf BS.ByteString))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length ByteString
bs
                          )
                        ]
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"Lazy.ByteString"
            , SizeTestConfig ByteString -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig ByteString -> Property)
-> SizeTestConfig ByteString -> Property
forall a b. (a -> b) -> a -> b
$
                (forall a. Show a => SizeTestConfig a
scfg @LBS.ByteString)
                  { debug = show . (LBS.unpack :: LBS.ByteString -> [Word8])
                  , computedCtx = \ByteString
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf ByteString) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf LBS.ByteString))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int64 -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Size) -> Int64 -> Size
forall a b. (a -> b) -> a -> b
$ ByteString -> Int64
LBS.length ByteString
bs
                          )
                        ]
                  , gen = LBS.fromStrict <$> Gen.bytes (Range.linear 0 1000)
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"Text"
            , SizeTestConfig Text -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Text -> Property)
-> SizeTestConfig Text -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig Text
forall a. Buildable a => SizeTestConfig a
cfg
                  { gen = Gen.text (Range.linear 0 1000) Gen.latin1
                  , computedCtx = \Text
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf Text) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf T.Text))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
bs
                          )
                        ]
                  }
            )
          ,
            ( PropertyName
"Text 2"
            , SizeTestConfig Text -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Text -> Property)
-> SizeTestConfig Text -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig Text
forall a. Buildable a => SizeTestConfig a
cfg
                  { gen = Gen.text (Range.linear 0 1000) Gen.unicode
                  , computedCtx = \Text
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf Text) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf T.Text))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
bs
                          )
                        ]
                  }
            )
          ,
            ( PropertyName
"[Bool]"
            , SizeTestConfig [Bool] -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig [Bool] -> Property)
-> SizeTestConfig [Bool] -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig [Bool]
forall a. Show a => SizeTestConfig a
scfg
                  { gen = listOf Gen.bool
                  , computedCtx = \[Bool]
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf [Bool]) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf [Bool]))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ [Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
bs
                          )
                        ]
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"NonEmpty Bool"
            , SizeTestConfig [Bool] -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig [Bool] -> Property)
-> SizeTestConfig [Bool] -> Property
forall a b. (a -> b) -> a -> b
$
                SizeTestConfig [Bool]
forall a. Show a => SizeTestConfig a
scfg
                  { gen = listOf Gen.bool
                  , computedCtx = \[Bool]
bs ->
                      [(TypeRep, SizeOverride)] -> Map TypeRep SizeOverride
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                        [
                          ( Proxy (LengthOf [Bool]) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(LengthOf [Bool]))
                          , Size -> SizeOverride
SizeConstant (Size -> SizeOverride) -> Size -> SizeOverride
forall a b. (a -> b) -> a -> b
$ Int -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Size) -> Int -> Size
forall a b. (a -> b) -> a -> b
$ [Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
bs
                          )
                        ]
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"Either Bool Bool"
            , SizeTestConfig (Either Bool Bool) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Either Bool Bool) -> Property)
-> SizeTestConfig (Either Bool Bool) -> Property
forall a b. (a -> b) -> a -> b
$
                (forall a. Show a => SizeTestConfig a
scfg @(Either Bool Bool))
                  { gen = Left <$> Gen.bool
                  , precise = True
                  }
            )
          ,
            ( PropertyName
"Either Bool Bool"
            , SizeTestConfig (Either Bool Bool) -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig (Either Bool Bool) -> Property)
-> SizeTestConfig (Either Bool Bool) -> Property
forall a b. (a -> b) -> a -> b
$
                (forall a. Show a => SizeTestConfig a
scfg @(Either Bool Bool))
                  { gen = Right <$> Gen.bool
                  , precise = True
                  }
            )
          , (PropertyName
"Maybe Bool", SizeTestConfig Bool -> Property
forall a. EncCBOR a => SizeTestConfig a -> Property
sizeTest (SizeTestConfig Bool -> Property)
-> SizeTestConfig Bool -> Property
forall a b. (a -> b) -> a -> b
$ SizeTestConfig Bool
forall a. Buildable a => SizeTestConfig a
cfg {gen = Gen.bool, precise = True})
          ]