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

module Test.Cardano.Ledger.Shelley.Serialisation.Tripping.JSON (
  tests,
)
where

import Cardano.Ledger.Address (Addr)
import Cardano.Ledger.Coin (Coin)
import Cardano.Ledger.Crypto (StandardCrypto)
import Cardano.Ledger.Keys (GenDelegPair (..), KeyHash, KeyRole (Genesis))
import Cardano.Ledger.Shelley.API.Types (ShelleyGenesis)
import Data.Aeson (FromJSON, ToJSON (toJSON), decode, encode, fromJSON)
import Test.Cardano.Ledger.Shelley.Serialisation.EraIndepGenerators ()
import Test.Cardano.Ledger.Shelley.Serialisation.Generators ()
import Test.QuickCheck (Property, (.&&.), (===))
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (testProperty)

propRoundTripJSON :: (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON :: forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON a
a =
  (forall a. FromJSON a => Value -> Result a
fromJSON (forall a. ToJSON a => a -> Value
toJSON a
a) forall a. (Eq a, Show a) => a -> a -> Property
=== forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)
    forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (forall a. FromJSON a => ByteString -> Maybe a
decode (forall a. ToJSON a => a -> ByteString
encode a
a) forall a. (Eq a, Show a) => a -> a -> Property
=== forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)

tests :: TestTree
tests :: TestTree
tests =
  TestName -> [TestTree] -> TestTree
testGroup
    TestName
"Shelley Genesis"
    [ forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Genesis roundtrip" forall a b. (a -> b) -> a -> b
$
        forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON @(ShelleyGenesis StandardCrypto)
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Coin roundtrip" forall a b. (a -> b) -> a -> b
$
        forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON @Coin
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Address roundtrip" forall a b. (a -> b) -> a -> b
$
        forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON @(Addr StandardCrypto)
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Genesis KeyHash " forall a b. (a -> b) -> a -> b
$
        forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON @(KeyHash 'Genesis StandardCrypto)
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"GenDelegPair roundtrip" forall a b. (a -> b) -> a -> b
$
        forall a. (ToJSON a, FromJSON a, Show a, Eq a) => a -> Property
propRoundTripJSON @(GenDelegPair StandardCrypto)
    ]