{-# 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.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

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
"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"

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"