{-# LANGUAGE TemplateHaskell #-}

module Test.Cardano.Chain.Epoch.File (
  tests,
) where

import Cardano.Chain.Epoch.File (ParseError, mainnetEpochSlots, parseEpochFilesWithBoundary)
import Cardano.Prelude
import Control.Monad.Trans.Resource (ResIO, runResourceT)
import Hedgehog (Group, Property, discover, (===))
import qualified Hedgehog as H
import Streaming (Of ((:>)))
import qualified Streaming as S
import System.Environment (lookupEnv)
import Test.Cardano.Mirror (mainnetEpochFiles)

tests :: Group
tests :: Group
tests = $$String
[(PropertyName, Property)]
Property
String -> GroupName
String -> PropertyName
GroupName -> [(PropertyName, Property)] -> Group
discover

prop_deserializeEpochs :: Property
prop_deserializeEpochs :: Property
prop_deserializeEpochs = TestLimit -> Property -> Property
H.withTests TestLimit
1
  (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ HasCallStack => PropertyT IO () -> Property
PropertyT IO () -> Property
H.property
  (PropertyT IO () -> Property) -> PropertyT IO () -> Property
forall a b. (a -> b) -> a -> b
$ do
    menv <- IO (Maybe String) -> PropertyT IO (Maybe String)
forall a. IO a -> PropertyT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe String) -> PropertyT IO (Maybe String))
-> IO (Maybe String) -> PropertyT IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ String -> IO (Maybe String)
lookupEnv String
"CARDANO_MAINNET_MIRROR"
    H.assert $ isJust menv

    files <- take 10 <$> liftIO mainnetEpochFiles
    H.assert $ not (null files)
    -- TODO: the property cannot take any parameters (if we want discoverPrefix
    -- to work). Now the question is whether it is OK to use an hardcoded value
    -- for the number of slots per epoch, and if so in which module should we
    -- store this constant?
    let stream = EpochSlots
-> [String]
-> Stream
     (Of (ABlockOrBoundary ByteString)) (ExceptT ParseError ResIO) ()
parseEpochFilesWithBoundary EpochSlots
mainnetEpochSlots [String]
files
    result <- (liftIO . runResourceT . runExceptT . S.run) (S.maps discard stream)
    result === Right ()
  where
    discard :: Of a m -> ExceptT ParseError ResIO m
    discard :: forall a m. Of a m -> ExceptT ParseError ResIO m
discard (a
_ :> m
rest) = m -> ExceptT ParseError ResIO m
forall a. a -> ExceptT ParseError ResIO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure m
rest