{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.CanonicalState.Spec (spec) where

import Cardano.Ledger.CanonicalState.Conway ()
import qualified Cardano.Ledger.CanonicalState.Namespace.Blocks.V0 as Blocks.V0
import qualified Cardano.Ledger.CanonicalState.Namespace.GovCommittee.V0 as Committee.V0
import qualified Cardano.Ledger.CanonicalState.Namespace.GovConstitution.V0 as GovConstitution.V0
import qualified Cardano.Ledger.CanonicalState.Namespace.UTxO.V0 as UTxO.V0
import Cardano.Ledger.Conway (ConwayEra)
import Cardano.SCLS.CBOR.Canonical.Encoder (ToCanonicalCBOR (..))
import Cardano.SCLS.Testlib
import Data.Typeable
import GHC.TypeLits
import Test.Cardano.Ledger.CanonicalState.Arbitrary ()
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Conway.CanonicalState.Arbitrary ()

spec :: Spec
spec :: Spec
spec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"types" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"blocks/v0" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical @"blocks/v0" @Blocks.V0.BlockOut
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Arbitrary a, Show a,
 Typeable a) =>
Text -> Spec
validateType @"blocks/v0" @Blocks.V0.BlockOut Text
"record_entry"
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"utxo/v0" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical @"utxo/v0" @(UTxO.V0.UtxoOut ConwayEra)
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Arbitrary a, Show a,
 Typeable a) =>
Text -> Spec
validateType @"utxo/v0" @(UTxO.V0.UtxoOut ConwayEra) Text
"record_entry"
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"gov/committee/v0" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical @"gov/committee/v0" @Committee.V0.CanonicalCommitteeState
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Arbitrary a, Show a,
 Typeable a) =>
Text -> Spec
validateType @"gov/committee/v0" @Committee.V0.CanonicalCommitteeState Text
"committee"
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical @"gov/committee/v0" @Committee.V0.CanonicalCommitteeAuthorization
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Arbitrary a, Show a,
 Typeable a) =>
Text -> Spec
validateType @"gov/committee/v0" @Committee.V0.CanonicalCommitteeAuthorization
        Text
"committee_authorization"
    String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"gov/constitution/v0" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical @"gov/constitution/v0" @GovConstitution.V0.CanonicalConstitution
      forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Arbitrary a, Show a,
 Typeable a) =>
Text -> Spec
validateType @"gov/constitution/v0" @GovConstitution.V0.CanonicalConstitution Text
"record_entry"
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"namespaces" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    forall (ns :: Symbol).
(KnownSymbol ns, KnownNamespace ns, Arbitrary (NamespaceEntry ns),
 Eq (NamespaceEntry ns), Show (NamespaceEntry ns)) =>
Spec
testNS @"blocks/v0"
    forall (ns :: Symbol).
(KnownSymbol ns, KnownNamespace ns, Arbitrary (NamespaceEntry ns),
 Eq (NamespaceEntry ns), Show (NamespaceEntry ns)) =>
Spec
testNS @"utxo/v0"
    forall (ns :: Symbol).
(KnownSymbol ns, KnownNamespace ns, Arbitrary (NamespaceEntry ns),
 Eq (NamespaceEntry ns), Show (NamespaceEntry ns)) =>
Spec
testNS @"gov/constitution/v0"
    forall (ns :: Symbol).
(KnownSymbol ns, KnownNamespace ns, Arbitrary (NamespaceEntry ns),
 Eq (NamespaceEntry ns), Show (NamespaceEntry ns)) =>
Spec
testNS @"gov/committee/v0"

isCanonical ::
  forall ns a. (KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a, Show a) => Spec
isCanonical :: forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a, Typeable a, Arbitrary a,
 Show a) =>
Spec
isCanonical = String -> (a -> IO ()) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
propName ((a -> IO ()) -> Spec) -> (a -> IO ()) -> Spec
forall a b. (a -> b) -> a -> b
$ forall (ns :: Symbol) a.
(KnownSymbol ns, ToCanonicalCBOR ns a) =>
a -> IO ()
propTypeIsCanonical @ns @a
  where
    propName :: String
propName = TypeRep -> ShowS
showsTypeRep (Proxy a -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)) String
" is canonical"