{-# 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 =
  String -> (x -> Expectation) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop (TypeRep x -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @x)) ((x -> Expectation) -> Spec) -> (x -> Expectation) -> Spec
forall a b. (a -> b) -> a -> b
$ \x
y ->
    Data -> Maybe x
forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData (x -> Data
forall x. ToPlutusData x => x -> Data
toPlutusData x
y) Maybe x -> Maybe x -> Expectation
forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` x -> Maybe x
forall a. a -> Maybe a
Just (x
y :: x)