packages feed

morley-1.4.0: test/Test/ValConversion.hs

-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

-- | Testing of toVal / fromVal conversions

module Test.ValConversion
  ( test_Roundtrip
  , unit_toVal
  ) where

import Hedgehog (Gen)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Test.HUnit (Assertion, (@?))
import Test.Tasty (TestTree)

import Michelson.Test.Util (genEither, genTuple2)
import Michelson.Text
import Michelson.Typed (IsoValue(..), ToT, Value, Value'(..))

import Test.Util.Hedgehog (roundtripTree)

-- | TestTrees to test toVal / fromVal conversions (roundtrip)
test_Roundtrip :: [TestTree]
test_Roundtrip =
  [ roundtrip @Integer genInteger
  , roundtrip @Bool Gen.bool
  , roundtrip @[Bool] $ Gen.list (Range.linear 0 100) Gen.bool
  , roundtrip @(Maybe Integer) $ Gen.maybe genInteger
  , roundtrip @(Maybe (Maybe Integer)) $ Gen.maybe (Gen.maybe genInteger)
  , roundtrip @(Either Bool Integer) $ genEither Gen.bool genInteger
  , roundtrip @(Set Integer) $ Gen.set (Range.linear 0 100) genInteger
  , roundtrip @(Set Bool) $ Gen.set (Range.linear 0 2) Gen.bool
  , roundtrip @(Map Integer Integer) $ Gen.map (Range.linear 0 100) (genTuple2 genInteger genInteger)
  , roundtrip @(Map Integer Bool) $ Gen.map (Range.linear 0 100) (genTuple2 genInteger Gen.bool)
  , roundtrip @(Map Integer (Maybe (Either Bool Bool))) $
      Gen.map (Range.linear 0 100) $
        genTuple2
          genInteger
          (Gen.maybe (genEither Gen.bool Gen.bool))
  ]
  where
    genInteger = Gen.integral (Range.linearFrom 0 (fromIntegral $ minBound @Int64) (fromIntegral $ maxBound @Word64))

    roundtrip :: forall a.
      (Show a, Eq a, Typeable a, IsoValue a) => Gen a -> TestTree
    roundtrip genA = roundtripTree @a @_ @Void genA toVal (Right . fromVal)

unit_toVal :: Assertion
unit_toVal = do
  check () $ (\case VUnit -> True;)
  check (10 :: Integer) $ (\case (VInt 10) -> True; _ -> False)
  check ("abc" :: ByteString) $ (\case (VBytes "abc") -> True; _ -> False)
  check (Just "abc" :: Maybe ByteString)
    $ (\case (VOption (Just (VBytes "abc"))) -> True; _ -> False)
  check (Left "abc" :: Either ByteString ByteString)
    $ (\case (VOr (Left (VBytes "abc"))) -> True; _ -> False)
  check (Left "abc" :: Either ByteString Integer)
    $ (\case (VOr (Left (VBytes "abc"))) -> True; _ -> False)
  check ((10, "abc") :: (Integer, ByteString))
    $ (\case (VPair ((VInt 10), VBytes "abc")) -> True; _ -> False)
  check (["abc", "cde"] :: [ByteString])
    $ (\case (VList [ VBytes "abc"
                    , VBytes "cde"]) -> True; _ -> False)
  check @Integer 10 (\case (VInt 10) -> True; _ -> False)
  check @Integer (-10) (\case (VInt (-10)) -> True; _ -> False)
  check @Natural 10 (\case (VNat 10) -> True; _ -> False)
  check [mt|abc|] (\case (VString [mt|abc|]) -> True; _ -> False)
  check True (\case (VBool True) -> True; _ -> False)
  where
    check :: IsoValue a => a -> (Value (ToT a) -> Bool) -> Assertion
    check v p = p (toVal v) @? "toVal returned unexpected result"