{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Protocol.Binary.RoundTrip (roundTripBlockSpec) where

import Cardano.Ledger.Binary (Annotator, DecCBOR, EncCBOR)
import Cardano.Ledger.Block (Block)
import Cardano.Ledger.Core
import Data.Typeable
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Core.Binary.RoundTrip
import Test.Cardano.Protocol.TPraos.Arbitrary ()

roundTripBlockSpec ::
  forall h era.
  ( Eq h
  , Show h
  , DecCBOR h
  , DecCBOR (Annotator h)
  , EncCBOR h
  , EraSegWits era
  , DecCBOR (TxSeq era)
  , Arbitrary (Block h era)
  ) =>
  Spec
roundTripBlockSpec :: forall h era.
(Eq h, Show h, DecCBOR h, DecCBOR (Annotator h), EncCBOR h,
 EraSegWits era, DecCBOR (TxSeq era), Arbitrary (Block h era)) =>
Spec
roundTripBlockSpec =
  forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop (forall a. Show a => a -> String
show (forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep forall a b. (a -> b) -> a -> b
$ forall {k} (t :: k). Proxy t
Proxy @(Block h era))) forall a b. (a -> b) -> a -> b
$ do
    forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
3 forall a b. (a -> b) -> a -> b
$ do
      forall prop. Testable prop => [prop] -> Property
conjoin
        [ forall era t.
(Era era, Show t, Eq t, EncCBOR t, DecCBOR t, HasCallStack) =>
t -> Expectation
roundTripEraExpectation @era @(Block h era)
        , forall era t.
(Era era, Show t, Eq t, ToCBOR t, DecCBOR (Annotator t),
 HasCallStack) =>
t -> Expectation
roundTripAnnEraExpectation @era @(Block h era)
        ]