protected static void AddVertexRange_Throws_Clusters_Test <TEdge>( ClusteredAdjacencyGraph <TestVertex, TEdge> graph) where TEdge : IEdge <TestVertex> { AssertNoVertex(graph); // ReSharper disable once AssignNullToNotNullAttribute Assert.Throws <ArgumentNullException>(() => graph.AddVertexRange(null)); AssertNoVertex(graph); // Vertex 1, 2, 3 var vertex1 = new TestVertex("1"); var vertex3 = new TestVertex("3"); Assert.Throws <ArgumentNullException>(() => graph.AddVertexRange(new[] { vertex1, null, vertex3 })); AssertNoVertex(graph); }
public void GenerateSameDot() { var graph = new AdjacencyGraph <int, Edge <int> >(); // Empty graph TestGenerate(graph); // Only vertices graph.AddVertexRange(new[] { 1, 2 }); TestGenerate(graph); // With edges graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(2, 3), new Edge <int>(3, 1) }); TestGenerate(graph); // With no cluster var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph); TestGenerate(clusteredGraph); // With clusters ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster(); subGraph1.AddVertexRange(new[] { 4, 5 }); ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster(); subGraph2.AddVerticesAndEdge(new Edge <int>(1, 6)); TestGenerate(clusteredGraph); #region Local function void TestGenerate <TVertex, TEdge>(IEdgeListGraph <TVertex, TEdge> g) where TEdge : IEdge <TVertex> { var algorithm = new GraphvizAlgorithm <TVertex, TEdge>(g); string generatedDot = algorithm.Generate(); Assert.IsNotEmpty(generatedDot); var dotEngine = new TestDotEngine { ExpectedDot = generatedDot }; // ReSharper disable once ReturnValueOfPureMethodIsNotUsed algorithm.Generate(dotEngine, "NotSaved.dot"); } #endregion }
protected static void AddVertexRange_Clusters_Test <TEdge>( ClusteredAdjacencyGraph <TestVertex, TEdge> graph1, ClusteredAdjacencyGraph <TestVertex, TEdge> parent2, ClusteredAdjacencyGraph <TestVertex, TEdge> graph2) where TEdge : IEdge <TestVertex> { AssertNoVertex(graph1); // Graph without parent // Vertex 1, 2, 3 var vertex1 = new TestVertex("1"); var vertex2 = new TestVertex("2"); var vertex3 = new TestVertex("3"); Assert.AreEqual(3, graph1.AddVertexRange(new[] { vertex1, vertex2, vertex3 })); AssertHasVertices(graph1, new[] { vertex1, vertex2, vertex3 }); // Vertex 1, 4 var vertex4 = new TestVertex("4"); Assert.AreEqual(1, graph1.AddVertexRange(new[] { vertex1, vertex4 })); AssertHasVertices(graph1, new[] { vertex1, vertex2, vertex3, vertex4 }); // Graph with parent AssertNoVertex(parent2); AssertNoVertex(graph2); // Vertex 1, 2, 3 Assert.AreEqual(3, graph2.AddVertexRange(new[] { vertex1, vertex2, vertex3 })); AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3 }); AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3 }); // Vertex 1, 4 Assert.AreEqual(1, parent2.AddVertexRange(new[] { vertex1, vertex4 })); AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3, vertex4 }); AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3 }); Assert.AreEqual(1, graph2.AddVertexRange(new[] { vertex1, vertex4 })); AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3, vertex4 }); AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3, vertex4 }); }
protected static void RemoveEdgeIf_Clusters_Test( [NotNull] ClusteredAdjacencyGraph <int, Edge <int> > graph) { var edge12 = new Edge <int>(1, 2); var edge13 = new Edge <int>(1, 3); var edge13Bis = new Edge <int>(1, 3); var edge14 = new Edge <int>(1, 4); var edge24 = new Edge <int>(2, 4); var edge31 = new Edge <int>(3, 1); var edge33 = new Edge <int>(3, 3); graph.AddVertexRange(new[] { 1, 2, 3, 4 }); graph.AddEdgeRange(new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 }); Assert.AreEqual(0, graph.RemoveEdgeIf(edge => edge.Target == 5)); Assert.AreEqual(2, graph.RemoveEdgeIf(edge => edge.Source == 3)); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertHasEdges(graph, new[] { edge12, edge13, edge13Bis, edge14, edge24 }); Assert.AreEqual(5, graph.RemoveEdgeIf(edge => true)); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertNoEdge(graph); }
protected static void RemoveVertex_Clusters_Test( [NotNull] ClusteredAdjacencyGraph <int, Edge <int> > graph) { var edge12 = new Edge <int>(1, 2); var edge13 = new Edge <int>(1, 3); var edge14 = new Edge <int>(1, 4); var edge24 = new Edge <int>(2, 4); var edge31 = new Edge <int>(3, 1); var edge33 = new Edge <int>(3, 3); graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge14, edge24, edge31, edge33 }); Assert.IsFalse(graph.RemoveVertex(5)); Assert.IsTrue(graph.RemoveVertex(3)); AssertHasVertices(graph, new[] { 1, 2, 4 }); AssertHasEdges(graph, new[] { edge12, edge14, edge24 }); Assert.IsTrue(graph.RemoveVertex(1)); AssertHasVertices(graph, new[] { 2, 4 }); AssertHasEdges(graph, new[] { edge24 }); Assert.IsTrue(graph.RemoveVertex(2)); AssertHasVertices(graph, new[] { 4 }); AssertNoEdge(graph); Assert.IsTrue(graph.RemoveVertex(4)); AssertEmptyGraph(graph); // With cluster ClusteredAdjacencyGraph <int, Edge <int> > cluster1 = graph.AddCluster(); ClusteredAdjacencyGraph <int, Edge <int> > cluster2 = graph.AddCluster(); ClusteredAdjacencyGraph <int, Edge <int> > cluster3 = graph.AddCluster(); cluster1.AddVertexRange(new[] { 1, 2 }); AssertHasVertices(cluster1, new[] { 1, 2 }); cluster2.AddVertexRange(new[] { 1, 2, 4 }); AssertHasVertices(cluster2, new[] { 1, 2, 4 }); cluster3.AddVertex(2); AssertHasVertices(cluster3, new[] { 2 }); graph.AddVertexRange(new[] { 1, 2, 3, 4 }); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); graph.RemoveVertex(2); AssertHasVertices(graph, new[] { 1, 3, 4 }); AssertHasVertices(cluster1, new[] { 1 }); AssertHasVertices(cluster2, new[] { 1, 4 }); AssertNoVertex(cluster3); graph.RemoveVertex(1); AssertHasVertices(graph, new[] { 3, 4 }); AssertNoVertex(cluster1); AssertHasVertices(cluster2, new[] { 4 }); AssertNoVertex(cluster3); graph.RemoveVertex(3); AssertHasVertices(graph, new[] { 4 }); AssertNoVertex(cluster1); AssertHasVertices(cluster2, new[] { 4 }); AssertNoVertex(cluster3); graph.RemoveVertex(4); AssertNoVertex(graph); AssertNoVertex(cluster1); AssertNoVertex(cluster2); AssertNoVertex(cluster3); }
public void FormatHandlers() { var graph = new AdjacencyGraph <int, Edge <int> >(); var algorithm = new GraphvizAlgorithm <int, Edge <int> >(graph); algorithm.FormatVertex += NoVertexOnFormatVertex; algorithm.FormatEdge += NoEdgeOnFormatEdge; algorithm.FormatCluster += NoClusterOnFormatCluster; // Empty graph algorithm.Generate(); // Only vertices graph.AddVertexRange(new[] { 1, 2 }); algorithm = new GraphvizAlgorithm <int, Edge <int> >(graph); List <int> notFormattedVertices = RegisterOnFormatVertex(algorithm, graph.Vertices); algorithm.FormatEdge += NoEdgeOnFormatEdge; algorithm.FormatCluster += NoClusterOnFormatCluster; algorithm.Generate(); CollectionAssert.IsEmpty(notFormattedVertices); // With edges graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(2, 3), new Edge <int>(3, 1) }); algorithm = new GraphvizAlgorithm <int, Edge <int> >(graph); notFormattedVertices = RegisterOnFormatVertex(algorithm, graph.Vertices); List <Edge <int> > notFormattedEdges = RegisterOnFormatEdge(algorithm, graph.Edges); algorithm.FormatCluster += NoClusterOnFormatCluster; algorithm.Generate(); CollectionAssert.IsEmpty(notFormattedVertices); CollectionAssert.IsEmpty(notFormattedEdges); // With no cluster var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph); algorithm = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph); notFormattedVertices = RegisterOnFormatVertex(algorithm, clusteredGraph.Vertices); notFormattedEdges = RegisterOnFormatEdge(algorithm, clusteredGraph.Edges); algorithm.FormatCluster += NoClusterOnFormatCluster; algorithm.Generate(); CollectionAssert.IsEmpty(notFormattedVertices); CollectionAssert.IsEmpty(notFormattedEdges); // With clusters ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster(); subGraph1.AddVertexRange(new[] { 4, 5 }); ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster(); subGraph2.AddVerticesAndEdge(new Edge <int>(1, 6)); algorithm = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph); notFormattedVertices = RegisterOnFormatVertex(algorithm, clusteredGraph.Vertices); notFormattedEdges = RegisterOnFormatEdge(algorithm, clusteredGraph.Edges); List <IVertexAndEdgeListGraph <int, Edge <int> > > notFormattedClusters = RegisterOnFormatCluster( algorithm, new[] { subGraph1, subGraph2 }); algorithm.Generate(); CollectionAssert.IsEmpty(notFormattedVertices); CollectionAssert.IsEmpty(notFormattedEdges); CollectionAssert.IsEmpty(notFormattedClusters); #region Local functions void NoVertexOnFormatVertex(object sender, FormatVertexEventArgs <int> args) { Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatVertex)} called while no vertex in graph."); } List <TVertex> RegisterOnFormatVertex <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <TVertex> vertices) where TEdge : IEdge <TVertex> { var verticesList = new List <TVertex>(vertices); algo.FormatVertex += (sender, args) => { Assert.IsTrue(verticesList.Remove(args.Vertex)); }; return(verticesList); } void NoEdgeOnFormatEdge(object sender, FormatEdgeEventArgs <int, Edge <int> > args) { Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatEdge)} called while no edge in graph."); } List <TEdge> RegisterOnFormatEdge <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <TEdge> edges) where TEdge : IEdge <TVertex> { var edgeList = new List <TEdge>(edges); algo.FormatEdge += (sender, args) => { Assert.IsTrue(edgeList.Remove(args.Edge)); }; return(edgeList); } void NoClusterOnFormatCluster(object sender, FormatClusterEventArgs <int, Edge <int> > args) { Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatCluster)} called while no cluster in graph."); } List <IVertexAndEdgeListGraph <TVertex, TEdge> > RegisterOnFormatCluster <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <IVertexAndEdgeListGraph <TVertex, TEdge> > clusters) where TEdge : IEdge <TVertex> { var clusterList = new List <IVertexAndEdgeListGraph <TVertex, TEdge> >(clusters); algo.FormatCluster += (sender, args) => { Assert.IsTrue(clusterList.Remove(args.Cluster)); }; return(clusterList); } #endregion }
public void GenerateWithFormats() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(3, 2), new Edge <int>(3, 4), new Edge <int>(4, 6), new Edge <int>(5, 2), new Edge <int>(5, 5) }); graph.AddVertex(7); var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph); ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster(); subGraph1.AddVertexRange(new[] { 8, 9, 10 }); ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster(); subGraph2.AddVerticesAndEdgeRange(new[] { new Edge <int>(11, 12), new Edge <int>(11, 13), new Edge <int>(12, 13) }); var algorithm = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph); algorithm.GraphFormat.Name = "MyGraph"; algorithm.GraphFormat.NodeSeparation = 2; algorithm.GraphFormat.FontColor = GraphvizColor.Red; algorithm.CommonVertexFormat.Url = "https://myurl.com"; algorithm.CommonVertexFormat.FillColor = GraphvizColor.LightYellow; algorithm.CommonVertexFormat.Style = GraphvizVertexStyle.Filled; algorithm.CommonEdgeFormat.Direction = GraphvizEdgeDirection.Back; algorithm.CommonEdgeFormat.ToolTip = "Edge"; algorithm.FormatCluster += (sender, args) => { args.GraphFormat.Label = args.Cluster == subGraph1 ? "Only Vertices cluster" : "Triangle cluster"; }; algorithm.FormatVertex += (sender, args) => { if (args.Vertex == 2 || args.Vertex == 11) { args.VertexFormat.Label = "Special Node"; } }; algorithm.FormatEdge += (sender, args) => { if (args.Edge.Source == args.Edge.Target) { args.EdgeFormat.StrokeColor = GraphvizColor.Gold; } }; string dot = algorithm.Generate(); string expectedDot = "digraph MyGraph {" + Environment.NewLine + "fontcolor=\"#FF0000FF\"; nodesep=2;" + Environment.NewLine + "node [style=filled, fillcolor=\"#FFFFE0FF\", URL=\"https://myurl.com\"];" + Environment.NewLine + "edge [dir=back, tooltip=\"Edge\"];" + Environment.NewLine + "subgraph cluster1 {" + Environment.NewLine + "label=\"Only Vertices cluster\"" + Environment.NewLine + "7 [label=\"8\"];" + Environment.NewLine + "8 [label=\"9\"];" + Environment.NewLine + "9 [label=\"10\"];" + Environment.NewLine + "}" + Environment.NewLine + "subgraph cluster2 {" + Environment.NewLine + "label=\"Triangle cluster\"" + Environment.NewLine + "10 [label=\"Special Node\"];" + Environment.NewLine + "11 [label=\"12\"];" + Environment.NewLine + "12 [label=\"13\"];" + Environment.NewLine + "10 -> 11;" + Environment.NewLine + "10 -> 12;" + Environment.NewLine + "11 -> 12;" + Environment.NewLine + "}" + Environment.NewLine + "0 [label=\"1\"];" + Environment.NewLine + "1 [label=\"Special Node\"];" + Environment.NewLine + "2 [label=\"3\"];" + Environment.NewLine + "3 [label=\"4\"];" + Environment.NewLine + "4 [label=\"6\"];" + Environment.NewLine + "5 [label=\"5\"];" + Environment.NewLine + "6 [label=\"7\"];" + Environment.NewLine + "0 -> 1;" + Environment.NewLine + "0 -> 2;" + Environment.NewLine + "2 -> 1;" + Environment.NewLine + "2 -> 3;" + Environment.NewLine + "3 -> 4;" + Environment.NewLine + "5 -> 1;" + Environment.NewLine + "5 -> 5 [color=\"#FFD700FF\"];" + Environment.NewLine + "}"; Assert.AreEqual(expectedDot, dot); }