module Graph.QuickCheck where
import Graph.Graph
import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen
instance Arbitrary NodeId where
arbitrary =
NodeId <$> arbitrary
instance Arbitrary EdgeId where
arbitrary =
EdgeId <$> arbitrary
instance (Arbitrary n) => Arbitrary (Node n) where
arbitrary =
Node <$> arbitrary <*> arbitrary
shrink (Node id payload) =
map (Node id) (shrink payload)
instance (Arbitrary e) => Arbitrary (Edge e) where
arbitrary =
Edge <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
shrink (Edge id src tgt payload) =
map (Edge id src tgt) (shrink payload)
instance (Arbitrary n, Arbitrary e) => Arbitrary (Graph n e) where
arbitrary =
sized $ \size ->
let
nodeSizePeriod =
10
numNodes =
size `div` nodeSizePeriod
edgeIncrement =
(numNodes * numNodes) `div` nodeSizePeriod
numEdges =
(size `mod` nodeSizePeriod) * edgeIncrement
in
randomGraph arbitrary arbitrary numNodes numEdges
shrink =
shrinkGraph
instance Show (NodeContext n e) where
show _ =
"<NodeCtx>"
instance Eq n => Eq (Node n) where
Node id1 payload1 == Node id2 payload2 =
(id1, payload1) == (id2, payload2)
instance Eq e => Eq (Edge e) where
Edge id1 srcId1 tgtId1 payload1 == Edge id2 srcId2 tgtId2 payload2 =
(id1, srcId1, tgtId1, payload1) == (id2, srcId2, tgtId2, payload2)
randomNodeOf :: Graph n e -> Gen (Node n)
randomNodeOf =
elements . nodes
randomNodeIdOf :: Graph n e -> Gen NodeId
randomNodeIdOf =
elements . nodeIds
randomNodeInContextOf :: Graph n e -> Gen (NodeInContext n e)
randomNodeInContextOf =
elements . nodesInContext
randomEdgeOf :: Graph n e -> Gen (Edge e)
randomEdgeOf =
elements . edges
randomEdgeIdOf :: Graph n e -> Gen EdgeId
randomEdgeIdOf =
elements . edgeIds
randomEdgeInContextOf :: Graph n e -> Gen (EdgeInContext n e)
randomEdgeInContextOf =
elements . edgesInContext
randomGraph :: Gen n -> Gen e -> Int -> Int -> Gen (Graph n e)
randomGraph randomNodePayload randomEdgePayload numNodes numEdges =
let
nodeIds =
map toEnum [0 .. numNodes - 1]
edgeIds =
map toEnum [0 .. numEdges - 1]
randomNode n =
Node n <$> randomNodePayload
randomEdge e =
Edge e <$> elements nodeIds <*> elements nodeIds <*> randomEdgePayload
in
fromNodesAndEdges
<$> mapM randomNode nodeIds
<*> mapM randomEdge edgeIds
shrinkGraph :: Graph n e -> [Graph n e]
shrinkGraph graph =
[ removeNodeAndIncidentEdges n graph | n <- nodeIds graph ]
++ [ removeEdge e graph | e <- edgeIds graph ]