{-# LANGUAGE ScopedTypeVariables #-}

module Test.Util.SupportedNetworkProtocolVersion (exhaustiveSupportedNetworkProtocolVersions) where

import           Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import           Data.Proxy
import qualified Data.Set as Set
import           Data.Typeable
import           Ouroboros.Consensus.Node.NetworkProtocolVersion
import           Test.Tasty.HUnit

-- | Make sure that 'supportedNodeToNodeVersions' and
-- 'supportedNodeToClientVersions' contain entries for all 'NodeToNodeVersion's
-- and 'NodeToClientVersion', respectively.
exhaustiveSupportedNetworkProtocolVersions ::
     forall blk. (Typeable blk, SupportedNetworkProtocolVersion blk)
  => Proxy blk
  -> Assertion
exhaustiveSupportedNetworkProtocolVersions :: forall blk.
(Typeable blk, SupportedNetworkProtocolVersion blk) =>
Proxy blk -> Assertion
exhaustiveSupportedNetworkProtocolVersions Proxy blk
p = do
    (Proxy blk -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk))
-> Assertion
forall v a.
(Show v, Ord v, Enum v, Bounded v) =>
(Proxy blk -> Map v a) -> Assertion
testVersions Proxy blk -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk)
forall blk.
SupportedNetworkProtocolVersion blk =>
Proxy blk -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk)
supportedNodeToNodeVersions
    (Proxy blk
 -> Map NodeToClientVersion (BlockNodeToClientVersion blk))
-> Assertion
forall v a.
(Show v, Ord v, Enum v, Bounded v) =>
(Proxy blk -> Map v a) -> Assertion
testVersions Proxy blk -> Map NodeToClientVersion (BlockNodeToClientVersion blk)
forall blk.
SupportedNetworkProtocolVersion blk =>
Proxy blk -> Map NodeToClientVersion (BlockNodeToClientVersion blk)
supportedNodeToClientVersions
  where
    testVersions ::
         (Show v, Ord v, Enum v, Bounded v)
      => (Proxy blk -> Map v a)
      -> Assertion
    testVersions :: forall v a.
(Show v, Ord v, Enum v, Bounded v) =>
(Proxy blk -> Map v a) -> Assertion
testVersions Proxy blk -> Map v a
f =
        HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool
          (   String
"unmapped versions for " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep -> String
forall a. Show a => a -> String
show (Proxy blk -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep Proxy blk
p) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
": "
           String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [v] -> String
forall a. Show a => a -> String
show (Set v -> [v]
forall a. Set a -> [a]
Set.toList Set v
unmappedVersions)
          )
          (Set v -> Bool
forall a. Set a -> Bool
Set.null Set v
unmappedVersions)
      where
        unmappedVersions :: Set v
unmappedVersions = Set v
allVersions Set v -> Set v -> Set v
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ Set v
mappedVersions
        allVersions :: Set v
allVersions      = [v] -> Set v
forall a. Ord a => [a] -> Set a
Set.fromList [v
forall a. Bounded a => a
minBound .. v
forall a. Bounded a => a
maxBound]
        mappedVersions :: Set v
mappedVersions   = Map v a -> Set v
forall k a. Map k a -> Set k
Map.keysSet (Map v a -> Set v) -> Map v a -> Set v
forall a b. (a -> b) -> a -> b
$ Proxy blk -> Map v a
f Proxy blk
p