module Test.Cardano.Crypto.PackedBytes.Spec (
  spec,
) where

import Cardano.Crypto.PackedBytes
import qualified Data.ByteString as BS
import Foreign.Storable
import Test.Cardano.Base.Properties (expectStorable)
import Test.Crypto.PackedBytes
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck

spec :: Spec
spec :: Spec
spec = String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"PackedBytes" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
  String
-> ((AnyPackedBytes, NonNegative Int, NonNegative Int) -> Property)
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"Storable" (((AnyPackedBytes, NonNegative Int, NonNegative Int) -> Property)
 -> Spec)
-> ((AnyPackedBytes, NonNegative Int, NonNegative Int) -> Property)
-> Spec
forall a b. (a -> b) -> a -> b
$ \(AnyPackedBytes PackedBytes n
pb, NonNegative Int
offset, NonNegative Int
slack) -> do
    let
      size :: Int
size = PackedBytes n -> Int
forall a. Storable a => a -> Int
sizeOf PackedBytes n
pb
      sizeStr :: String
sizeStr
        | Int
size Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int
0, Int
8, Int
28, Int
32] = Int -> String
forall a. Show a => a -> String
show Int
size String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" bytes"
        | Bool
otherwise = String
"Other size"
    String -> IO () -> Property
forall prop. Testable prop => String -> prop -> Property
label String
sizeStr (IO () -> Property) -> IO () -> Property
forall a b. (a -> b) -> a -> b
$ do
      Int
size Int -> Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` ByteString -> Int
BS.length (PackedBytes n -> ByteString
forall (n :: Nat). PackedBytes n -> ByteString
unpackPinnedBytes PackedBytes n
pb)
      PackedBytes n -> NonNegative Int -> NonNegative Int -> IO ()
forall a.
(Storable a, Show a, Eq a) =>
a -> NonNegative Int -> NonNegative Int -> IO ()
expectStorable PackedBytes n
pb NonNegative Int
offset NonNegative Int
slack