{-# LANGUAGE NamedFieldPuns #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Test.Ouroboros.Network.NodeToNode.Version (tests) where

import Ouroboros.Network.CodecCBORTerm
import Ouroboros.Network.Magic
import Ouroboros.Network.NodeToNode.Version

import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..))
import Test.QuickCheck
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (testProperty)


tests :: TestTree
tests :: TestTree
tests = TestName -> [TestTree] -> TestTree
testGroup TestName
"Ouroboros.Network.NodeToNode.Version"
    [ TestName
-> (NodeToNodeVersion -> NodeToNodeVersionData -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"nodeToNodeCodecCBORTerm" NodeToNodeVersion -> NodeToNodeVersionData -> Bool
prop_nodeToNodeCodec
    ]

instance Arbitrary NodeToNodeVersion where
    arbitrary :: Gen NodeToNodeVersion
arbitrary = Gen NodeToNodeVersion
forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

    shrink :: NodeToNodeVersion -> [NodeToNodeVersion]
shrink NodeToNodeVersion
v
      | NodeToNodeVersion
v NodeToNodeVersion -> NodeToNodeVersion -> Bool
forall a. Eq a => a -> a -> Bool
== NodeToNodeVersion
forall a. Bounded a => a
minBound = []
      | Bool
otherwise     = [NodeToNodeVersion -> NodeToNodeVersion
forall a. Enum a => a -> a
pred NodeToNodeVersion
v]

instance Arbitrary NodeToNodeVersionData where
    arbitrary :: Gen NodeToNodeVersionData
arbitrary =
      NetworkMagic
-> DiffusionMode -> PeerSharing -> Bool -> NodeToNodeVersionData
NodeToNodeVersionData
        (NetworkMagic
 -> DiffusionMode -> PeerSharing -> Bool -> NodeToNodeVersionData)
-> Gen NetworkMagic
-> Gen
     (DiffusionMode -> PeerSharing -> Bool -> NodeToNodeVersionData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word32 -> NetworkMagic
NetworkMagic (Word32 -> NetworkMagic) -> Gen Word32 -> Gen NetworkMagic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word32
forall a. Arbitrary a => Gen a
arbitrary)
        Gen (DiffusionMode -> PeerSharing -> Bool -> NodeToNodeVersionData)
-> Gen DiffusionMode
-> Gen (PeerSharing -> Bool -> NodeToNodeVersionData)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Gen DiffusionMode] -> Gen DiffusionMode
forall a. [Gen a] -> Gen a
oneof [ DiffusionMode -> Gen DiffusionMode
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DiffusionMode
InitiatorOnlyDiffusionMode
                  , DiffusionMode -> Gen DiffusionMode
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DiffusionMode
InitiatorAndResponderDiffusionMode
                  ]
        Gen (PeerSharing -> Bool -> NodeToNodeVersionData)
-> Gen PeerSharing -> Gen (Bool -> NodeToNodeVersionData)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [PeerSharing] -> Gen PeerSharing
forall a. [a] -> Gen a
elements [ PeerSharing
PeerSharingDisabled
                     , PeerSharing
PeerSharingEnabled
                     ]
        Gen (Bool -> NodeToNodeVersionData)
-> Gen Bool -> Gen NodeToNodeVersionData
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Bool
forall a. Arbitrary a => Gen a
arbitrary

prop_nodeToNodeCodec :: NodeToNodeVersion -> NodeToNodeVersionData -> Bool
prop_nodeToNodeCodec :: NodeToNodeVersion -> NodeToNodeVersionData -> Bool
prop_nodeToNodeCodec NodeToNodeVersion
ntnVersion NodeToNodeVersionData
ntnData =
      case Term -> Either Text NodeToNodeVersionData
decodeTerm (NodeToNodeVersionData -> Term
encodeTerm NodeToNodeVersionData
ntnData) of
        Right NodeToNodeVersionData
ntnData' -> NodeToNodeVersionData -> NetworkMagic
networkMagic  NodeToNodeVersionData
ntnData' NetworkMagic -> NetworkMagic -> Bool
forall a. Eq a => a -> a -> Bool
== NodeToNodeVersionData -> NetworkMagic
networkMagic  NodeToNodeVersionData
ntnData
                       Bool -> Bool -> Bool
&& NodeToNodeVersionData -> DiffusionMode
diffusionMode NodeToNodeVersionData
ntnData' DiffusionMode -> DiffusionMode -> Bool
forall a. Eq a => a -> a -> Bool
== NodeToNodeVersionData -> DiffusionMode
diffusionMode NodeToNodeVersionData
ntnData
        Left {}        -> Bool
False
    where
      CodecCBORTerm { NodeToNodeVersionData -> Term
encodeTerm :: NodeToNodeVersionData -> Term
encodeTerm :: forall fail a. CodecCBORTerm fail a -> a -> Term
encodeTerm, Term -> Either Text NodeToNodeVersionData
decodeTerm :: Term -> Either Text NodeToNodeVersionData
decodeTerm :: forall fail a. CodecCBORTerm fail a -> Term -> Either fail a
decodeTerm } = NodeToNodeVersion -> CodecCBORTerm Text NodeToNodeVersionData
nodeToNodeCodecCBORTerm NodeToNodeVersion
ntnVersion