{-# 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, EncCBORGroup)
import Cardano.Ledger.Block (Block)
import Cardano.Ledger.Core
import Data.Typeable
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Core.Binary.Annotator ()
import Test.Cardano.Ledger.Core.Binary.RoundTrip
import Test.Cardano.Protocol.Binary.Annotator ()
import Test.Cardano.Protocol.TPraos.Arbitrary ()

roundTripBlockSpec ::
  forall h era.
  ( Eq h
  , Show h
  , DecCBOR h
  , DecCBOR (Annotator h)
  , EncCBOR h
  , EraBlockBody era
  , Arbitrary (Block h era)
  , DecCBOR (BlockBody era)
  , EncCBORGroup (BlockBody era)
  ) =>
  Spec
roundTripBlockSpec :: forall h era.
(Eq h, Show h, DecCBOR h, DecCBOR (Annotator h), EncCBOR h,
 EraBlockBody era, Arbitrary (Block h era), DecCBOR (BlockBody era),
 EncCBORGroup (BlockBody era)) =>
Spec
roundTripBlockSpec =
  String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop (TypeRep -> String
forall a. Show a => a -> String
show (Proxy (Block h era) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy (Block h era) -> TypeRep) -> Proxy (Block h era) -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Block h era))) (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ do
    Int -> Property -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
3 (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ do
      [Block h era -> Expectation] -> Property
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)
        ]