{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Test.Cardano.Ledger.Shelley.Imp (spec, shelleyEraSpecificSpec) where

import Cardano.Ledger.Core
import Cardano.Ledger.Shelley (ShelleyEra)
import Cardano.Ledger.Shelley.Rules (
  ShelleyPoolPredFailure,
  ShelleyUtxoPredFailure,
  ShelleyUtxowPredFailure,
 )
import Cardano.Ledger.Shelley.TxCert (ShelleyEraTxCert)
import Test.Cardano.Ledger.Imp.Common
import qualified Test.Cardano.Ledger.Shelley.Imp.EpochSpec as Epoch
import qualified Test.Cardano.Ledger.Shelley.Imp.LedgerSpec as Ledger
import qualified Test.Cardano.Ledger.Shelley.Imp.PoolSpec as Pool
import qualified Test.Cardano.Ledger.Shelley.Imp.UtxoSpec as Utxo
import qualified Test.Cardano.Ledger.Shelley.Imp.UtxowSpec as Utxow
import Test.Cardano.Ledger.Shelley.ImpTest
import qualified Test.Cardano.Ledger.Shelley.UnitTests.InstantStakeTest as Instant

spec ::
  forall era.
  ( ShelleyEraImp era
  , EraSpecificSpec era
  , InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
  , InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
  , InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
  ) =>
  Spec
spec :: forall era.
(ShelleyEraImp era, EraSpecificSpec era,
 InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era,
 InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era,
 InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era) =>
Spec
spec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Era specific tests" (Spec -> Spec)
-> (SpecWith (ImpInit (LedgerSpec era)) -> Spec)
-> SpecWith (ImpInit (LedgerSpec era))
-> Spec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era.
ShelleyEraImp era =>
SpecWith (ImpInit (LedgerSpec era)) -> Spec
withEachEraVersion @era (SpecWith (ImpInit (LedgerSpec era)) -> Spec)
-> SpecWith (ImpInit (LedgerSpec era)) -> Spec
forall a b. (a -> b) -> a -> b
$ SpecWith (ImpInit (LedgerSpec era))
forall era.
EraSpecificSpec era =>
SpecWith (ImpInit (LedgerSpec era))
eraSpecificSpec
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"ShelleyImpSpec" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ forall era.
ShelleyEraImp era =>
SpecWith (ImpInit (LedgerSpec era)) -> Spec
withEachEraVersion @era (SpecWith (ImpInit (LedgerSpec era)) -> Spec)
-> SpecWith (ImpInit (LedgerSpec era)) -> Spec
forall a b. (a -> b) -> a -> b
$ do
    SpecWith (ImpInit (LedgerSpec era))
forall era.
ShelleyEraImp era =>
SpecWith (ImpInit (LedgerSpec era))
Epoch.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
ShelleyEraImp era =>
SpecWith (ImpInit (LedgerSpec era))
Ledger.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(ShelleyEraImp era,
 InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
Pool.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(ShelleyEraImp era,
 InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
Utxow.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(ShelleyEraImp era,
 InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
Utxo.spec
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"ShelleyPureTests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    forall era. ShelleyEraImp era => Spec
Instant.spec @era

shelleyEraSpecificSpec ::
  ( ShelleyEraImp era
  , ShelleyEraTxCert era
  , InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
  ) =>
  SpecWith (ImpInit (LedgerSpec era))
shelleyEraSpecificSpec :: forall era.
(ShelleyEraImp era, ShelleyEraTxCert era,
 InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
shelleyEraSpecificSpec = do
  String
-> SpecWith (ImpInit (LedgerSpec era))
-> SpecWith (ImpInit (LedgerSpec era))
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Shelley era specific Imp spec" (SpecWith (ImpInit (LedgerSpec era))
 -> SpecWith (ImpInit (LedgerSpec era)))
-> SpecWith (ImpInit (LedgerSpec era))
-> SpecWith (ImpInit (LedgerSpec era))
forall a b. (a -> b) -> a -> b
$
    String
-> SpecWith (ImpInit (LedgerSpec era))
-> SpecWith (ImpInit (LedgerSpec era))
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Certificates without deposits" (SpecWith (ImpInit (LedgerSpec era))
 -> SpecWith (ImpInit (LedgerSpec era)))
-> SpecWith (ImpInit (LedgerSpec era))
-> SpecWith (ImpInit (LedgerSpec era))
forall a b. (a -> b) -> a -> b
$ do
      String
-> SpecWith (ImpInit (LedgerSpec era))
-> SpecWith (ImpInit (LedgerSpec era))
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"POOL" SpecWith (ImpInit (LedgerSpec era))
forall era.
(ShelleyEraImp era, ShelleyEraTxCert era,
 InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
Pool.shelleyEraSpecificSpec

instance EraSpecificSpec ShelleyEra where
  eraSpecificSpec :: SpecWith (ImpInit (LedgerSpec ShelleyEra))
eraSpecificSpec = SpecWith (ImpInit (LedgerSpec ShelleyEra))
forall era.
(ShelleyEraImp era, ShelleyEraTxCert era,
 InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era) =>
SpecWith (ImpInit (LedgerSpec era))
shelleyEraSpecificSpec