{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE MonoLocalBinds      #-}
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- Generic tests for hash.

module Tests.Digest
       ( digestsTo
       , incrementalVsFull
       ) where

import Implementation
import Interface

import Tests.Core



digestsTo :: ByteString
          -> Prim
          -> Spec
digestsTo :: ByteString -> Prim -> Spec
digestsTo ByteString
str Prim
h = String -> Expectation -> SpecWith (Arg Expectation)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
msg (ByteString -> Prim
forall src. PureByteSource src => src -> Prim
digest ByteString
str Prim -> Prim -> Expectation
forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` Prim
h)
  where msg :: String
msg   = [String] -> String
unwords [ String
"hashes"
                        , String -> String
shortened (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ ByteString -> String
forall a. Show a => a -> String
show ByteString
str
                        , String
"to"
                        , String -> String
shortened (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Prim -> String
forall a. Show a => a -> String
show Prim
h
                        ]

incrDigest :: ByteString
           -> IO Prim
incrDigest :: ByteString -> IO Prim
incrDigest ByteString
bs = (DigestCxt 1 -> IO Prim) -> IO Prim
forall mem a. Memory mem => (mem -> IO a) -> IO a
withMemory ((DigestCxt 1 -> IO Prim) -> IO Prim)
-> (DigestCxt 1 -> IO Prim) -> IO Prim
forall a b. (a -> b) -> a -> b
$ \ (DigestCxt 1
cxt :: DigestCxt 1) ->
  do DigestCxt 1 -> Expectation
forall (n :: Nat). KnownNat n => Cxt n -> Expectation
startDigest DigestCxt 1
cxt
     ByteString -> DigestCxt 1 -> Expectation
forall (n :: Nat) src.
(KnownNat n, ByteSource src) =>
src -> Cxt n -> Expectation
updateDigest ByteString
bs DigestCxt 1
cxt
     DigestCxt 1 -> IO Prim
forall (n :: Nat). KnownNat n => Cxt n -> IO Prim
finaliseDigest DigestCxt 1
cxt

incrDigestList :: [ByteString]
               -> IO Prim
incrDigestList :: [ByteString] -> IO Prim
incrDigestList [ByteString]
bsL = (DigestCxt 1 -> IO Prim) -> IO Prim
forall mem a. Memory mem => (mem -> IO a) -> IO a
withMemory ((DigestCxt 1 -> IO Prim) -> IO Prim)
-> (DigestCxt 1 -> IO Prim) -> IO Prim
forall a b. (a -> b) -> a -> b
$ \ (DigestCxt 1
cxt :: DigestCxt 1) ->
  do DigestCxt 1 -> Expectation
forall (n :: Nat). KnownNat n => Cxt n -> Expectation
startDigest DigestCxt 1
cxt
     (ByteString -> Expectation) -> [ByteString] -> Expectation
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (ByteString -> DigestCxt 1 -> Expectation
forall (n :: Nat) src.
(KnownNat n, ByteSource src) =>
src -> Cxt n -> Expectation
`updateDigest` DigestCxt 1
cxt) [ByteString]
bsL
     DigestCxt 1 -> IO Prim
forall (n :: Nat). KnownNat n => Cxt n -> IO Prim
finaliseDigest DigestCxt 1
cxt

incrementalVsFull :: Spec
incrementalVsFull :: Spec
incrementalVsFull = String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Incremental vs Full digest" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
  String -> (ByteString -> Expectation) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"for single source" ((ByteString -> Expectation) -> Spec)
-> (ByteString -> Expectation) -> Spec
forall a b. (a -> b) -> a -> b
$
    \ ByteString
bs -> ByteString -> IO Prim
incrDigest ByteString
bs IO Prim -> Prim -> Expectation
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
`shouldReturn` ByteString -> Prim
forall src. PureByteSource src => src -> Prim
digest ByteString
bs

  String -> ([ByteString] -> Expectation) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"for multiple source" (([ByteString] -> Expectation) -> Spec)
-> ([ByteString] -> Expectation) -> Spec
forall a b. (a -> b) -> a -> b
$
    \ [ByteString]
bsL -> [ByteString] -> IO Prim
incrDigestList [ByteString]
bsL IO Prim -> Prim -> Expectation
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
`shouldReturn` [ByteString] -> Prim
forall src. PureByteSource src => src -> Prim
digest [ByteString]
bsL