{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.Plutus.ToPlutusData (
  roundTripPlutusDataSpec,
) where

import Cardano.Ledger.Plutus.ToPlutusData
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Core.Arbitrary ()
import Type.Reflection (Typeable, typeRep)

-- ==================================================================================

-- | Test the roundtrip property via 'fromPlutusData' and 'toPlutusData' for any type
--   meeting all the constraints below.
roundTripPlutusDataSpec ::
  forall x. (HasCallStack, Typeable x, Show x, Eq x, Arbitrary x, ToPlutusData x) => Spec
roundTripPlutusDataSpec :: forall x.
(HasCallStack, Typeable x, Show x, Eq x, Arbitrary x,
 ToPlutusData x) =>
Spec
roundTripPlutusDataSpec =
  forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop (forall a. Show a => a -> String
show (forall {k} (a :: k). Typeable a => TypeRep a
typeRep @x)) forall a b. (a -> b) -> a -> b
$ \x
y ->
    forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData (forall x. ToPlutusData x => x -> Data
toPlutusData x
y) forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` forall a. a -> Maybe a
Just (x
y :: x)