hstox-0.0.1: src/testsuite/Network/Tox/DHT/DhtStateSpec.hs
{-# LANGUAGE Trustworthy #-}
module Network.Tox.DHT.DhtStateSpec where
import Test.Hspec
import Test.QuickCheck
import Control.Monad (unless)
import Data.Proxy (Proxy (..))
import qualified Network.Tox.Crypto.KeyPair as KeyPair
import Network.Tox.DHT.DhtState (DhtState)
import qualified Network.Tox.DHT.DhtState as DhtState
import Network.Tox.EncodingSpec
import qualified Network.Tox.NodeInfo.NodeInfo as NodeInfo
spec :: Spec
spec = do
readShowSpec (Proxy :: Proxy DhtState)
it "the state can never contain itself" $
property $ \keyPair nodeInfo ->
let
dhtState = DhtState.empty keyPair
afterAdd = DhtState.addNode
nodeInfo { NodeInfo.publicKey = KeyPair.publicKey keyPair }
dhtState
in
afterAdd `shouldBe` dhtState
describe "adding a node that was not yet contained" $ do
it "should result in a different state" $
property $ \keyPair nodeInfo ->
let
dhtState = DhtState.empty keyPair
afterAdd = DhtState.addNode nodeInfo dhtState
in
unless (DhtState.containsNode (NodeInfo.publicKey nodeInfo) dhtState) $
afterAdd `shouldNotBe` dhtState
it "and removing it yields the same state" $
property $ \keyPair nodeInfo ->
let
dhtState = DhtState.empty keyPair
afterAdd = DhtState.addNode nodeInfo dhtState
afterRemove = DhtState.removeNode (NodeInfo.publicKey nodeInfo) afterAdd
in
unless (DhtState.containsNode (NodeInfo.publicKey nodeInfo) dhtState) $
afterRemove `shouldBe` dhtState
describe "adding a node" $
it "and adding it again does not change the state twice" $
property $ \keyPair nodeInfo ->
let
dhtState = DhtState.empty keyPair
afterAdd1 = DhtState.addNode nodeInfo dhtState
afterAdd2 = DhtState.addNode nodeInfo afterAdd1
in
afterAdd1 `shouldBe` afterAdd2
describe "adding a search node" $ do
it "should result in a different state" $
property $ \keyPair publicKey ->
let
dhtState = DhtState.empty keyPair
afterAdd = DhtState.addSearchKey publicKey dhtState
in
afterAdd `shouldNotBe` dhtState
it "and removing it yields the same state" $
property $ \keyPair publicKey ->
let
dhtState = DhtState.empty keyPair
afterAdd = DhtState.addSearchKey publicKey dhtState
afterRemove = DhtState.removeSearchKey publicKey afterAdd
in
afterRemove `shouldBe` dhtState
it "and adding it again does not change the state twice" $
property $ \keyPair publicKey ->
let
dhtState = DhtState.empty keyPair
afterAdd1 = DhtState.addSearchKey publicKey dhtState
afterAdd2 = DhtState.addSearchKey publicKey afterAdd1
in
afterAdd1 `shouldBe` afterAdd2
it "and adding a node info for it will not add it to the search entry's k-buckets" $
property $ \keyPair nodeInfo ->
let
dhtState = DhtState.empty keyPair
afterAddSearchKey = DhtState.addSearchKey
(NodeInfo.publicKey nodeInfo)
dhtState
in
DhtState.size (DhtState.addNode nodeInfo afterAddSearchKey)
`shouldBe`
DhtState.size (DhtState.addNode nodeInfo dhtState)