{-# LANGUAGE ScopedTypeVariables #-}

-- | Test `NodeToNodeVersion` and `NodeToClientVersion` codecs.
--
module Test.Ouroboros.Network.Version (tests) where

import Ouroboros.Network.CodecCBORTerm
import Ouroboros.Network.NodeToClient (NodeToClientVersion (..),
           nodeToClientVersionCodec)
import Ouroboros.Network.NodeToNode (NodeToNodeVersion (..),
           nodeToNodeVersionCodec)

import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit


tests :: TestTree
tests :: TestTree
tests =
  TestName -> [TestTree] -> TestTree
testGroup TestName
"Ouroboros.Network.Protocol.Handshake.Version"
    [ TestName -> [TestTree] -> TestTree
testGroup TestName
"NodeToClientVersion"
      [ TestName -> Assertion -> TestTree
testCase TestName
"NodeToClientVersion round-trip codec property"
                 (CodecCBORTerm (Text, Maybe Int) NodeToClientVersion -> Assertion
forall failure a.
(Eq a, Enum a, Bounded a, Show a, Eq failure, Show failure) =>
CodecCBORTerm failure a -> Assertion
roundTripPropAll CodecCBORTerm (Text, Maybe Int) NodeToClientVersion
nodeToClientVersionCodec)
      , TestName -> Assertion -> TestTree
testCase TestName
"NodeToClientVersion should not deserialise as NodeToNode"
                 (CodecCBORTerm (Text, Maybe Int) NodeToClientVersion
-> CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
-> [NodeToClientVersion]
-> Assertion
forall failure a b.
(Show a, Show b, Eq failure, Show failure) =>
CodecCBORTerm failure a
-> CodecCBORTerm failure b -> [a] -> Assertion
crossFailurePropAll
                   CodecCBORTerm (Text, Maybe Int) NodeToClientVersion
nodeToClientVersionCodec
                   CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
nodeToNodeVersionCodec
                   ([NodeToClientVersion
forall a. Bounded a => a
minBound .. NodeToClientVersion
forall a. Bounded a => a
maxBound] :: [NodeToClientVersion]))
      ]
    , TestName -> [TestTree] -> TestTree
testGroup TestName
"NodeToNodeVersion"
      [ TestName -> Assertion -> TestTree
testCase TestName
"NodeToNodeVersion round-trip codec property"
                 (CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion -> Assertion
forall failure a.
(Eq a, Enum a, Bounded a, Show a, Eq failure, Show failure) =>
CodecCBORTerm failure a -> Assertion
roundTripPropAll CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
nodeToNodeVersionCodec)
      , TestName -> Assertion -> TestTree
testCase TestName
"NodeToNodeVersion should not deserialise as NodeToClient"
                 (CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
-> CodecCBORTerm (Text, Maybe Int) NodeToClientVersion
-> [NodeToNodeVersion]
-> Assertion
forall failure a b.
(Show a, Show b, Eq failure, Show failure) =>
CodecCBORTerm failure a
-> CodecCBORTerm failure b -> [a] -> Assertion
crossFailurePropAll
                   CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
nodeToNodeVersionCodec
                   CodecCBORTerm (Text, Maybe Int) NodeToClientVersion
nodeToClientVersionCodec
                   ([NodeToNodeVersion
forall a. Bounded a => a
minBound .. NodeToNodeVersion
forall a. Bounded a => a
maxBound] :: [NodeToNodeVersion]))
      ]
    ]


roundTripProp :: ( Eq a
                 , Show a
                 , Eq failure
                 , Show failure
                 )
              => CodecCBORTerm failure a
              -> a -> Assertion
roundTripProp :: forall a failure.
(Eq a, Show a, Eq failure, Show failure) =>
CodecCBORTerm failure a -> a -> Assertion
roundTripProp CodecCBORTerm failure a
codec a
a =
    a -> Either failure a
forall a b. b -> Either a b
Right a
a Either failure a -> Either failure a -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@=? CodecCBORTerm failure a -> Term -> Either failure a
forall fail a. CodecCBORTerm fail a -> Term -> Either fail a
decodeTerm CodecCBORTerm failure a
codec (CodecCBORTerm failure a -> a -> Term
forall fail a. CodecCBORTerm fail a -> a -> Term
encodeTerm CodecCBORTerm failure a
codec a
a)


-- Using `Monoid` instance of `IO ()`
roundTripPropAll
    :: forall failure a.
       ( Eq a
       , Enum a
       , Bounded a
       , Show a
       , Eq failure
       , Show failure
       )
    => CodecCBORTerm failure a -> Assertion
roundTripPropAll :: forall failure a.
(Eq a, Enum a, Bounded a, Show a, Eq failure, Show failure) =>
CodecCBORTerm failure a -> Assertion
roundTripPropAll CodecCBORTerm failure a
codec =
    (a -> Assertion) -> [a] -> Assertion
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (CodecCBORTerm failure a -> a -> Assertion
forall a failure.
(Eq a, Show a, Eq failure, Show failure) =>
CodecCBORTerm failure a -> a -> Assertion
roundTripProp CodecCBORTerm failure a
codec) ([a
forall a. Bounded a => a
minBound..a
forall a. Bounded a => a
maxBound] :: [a])


crossFailureProp
    :: forall failure a b.
       ( Show a
       , Show b
       , Eq failure
       , Show failure
       )
    => CodecCBORTerm failure a
    -> CodecCBORTerm failure b
    -> a
    -> Assertion
crossFailureProp :: forall failure a b.
(Show a, Show b, Eq failure, Show failure) =>
CodecCBORTerm failure a
-> CodecCBORTerm failure b -> a -> Assertion
crossFailureProp CodecCBORTerm failure a
codecA CodecCBORTerm failure b
codecB a
a =
    case CodecCBORTerm failure b -> Term -> Either failure b
forall fail a. CodecCBORTerm fail a -> Term -> Either fail a
decodeTerm CodecCBORTerm failure b
codecB (CodecCBORTerm failure a -> a -> Term
forall fail a. CodecCBORTerm fail a -> a -> Term
encodeTerm CodecCBORTerm failure a
codecA a
a) of
      Right b
b -> TestName -> Assertion
forall a. HasCallStack => TestName -> IO a
assertFailure (a -> TestName
forall a. Show a => a -> TestName
show a
a TestName -> TestName -> TestName
forall a. [a] -> [a] -> [a]
++ TestName
"should not deserialise as " TestName -> TestName -> TestName
forall a. [a] -> [a] -> [a]
++ b -> TestName
forall a. Show a => a -> TestName
show b
b)
      Left  failure
_ -> () -> Assertion
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()


crossFailurePropAll
    :: forall failure a b.
       ( Show a
       , Show b
       , Eq failure
       , Show failure
       )
    => CodecCBORTerm failure a
    -> CodecCBORTerm failure b
    -> [a]
    -> Assertion
crossFailurePropAll :: forall failure a b.
(Show a, Show b, Eq failure, Show failure) =>
CodecCBORTerm failure a
-> CodecCBORTerm failure b -> [a] -> Assertion
crossFailurePropAll CodecCBORTerm failure a
codecA CodecCBORTerm failure b
codecB = (a -> Assertion) -> [a] -> Assertion
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (CodecCBORTerm failure a
-> CodecCBORTerm failure b -> a -> Assertion
forall failure a b.
(Show a, Show b, Eq failure, Show failure) =>
CodecCBORTerm failure a
-> CodecCBORTerm failure b -> a -> Assertion
crossFailureProp CodecCBORTerm failure a
codecA CodecCBORTerm failure b
codecB)