1 // Written in the D programming language.
2 
3 /**
4   Test collection for dgraph library.
5 
6   Authors:   $(LINK2 http://braingam.es/, Joseph Rushton Wakeling)
7   Copyright: Copyright © 2013 Joseph Rushton Wakeling
8   License:   This program is free software: you can redistribute it and/or modify
9              it under the terms of the GNU General Public License as published by
10              the Free Software Foundation, either version 3 of the License, or
11              (at your option) any later version.
12 
13              This program is distributed in the hope that it will be useful,
14              but WITHOUT ANY WARRANTY; without even the implied warranty of
15              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16              GNU General Public License for more details.
17 
18              You should have received a copy of the GNU General Public License
19              along with this program.  If not, see $(LINK http://www.gnu.org/licenses/).
20 */
21 
22 module dgraph.test.tests;
23 
24 import std.algorithm, std.conv, std.exception;
25 
26 import dgraph.graph;
27 
28 /**
29  * Tests adding edges to a graph, either one at a time or all in one go.  Can
30  * be used e.g. for benchmarking or for checking that network properties are
31  * reliably imported.
32  */
33 void testAddEdge(Graph, bool allAtOnce = false, ushort verbose = 0, T : size_t)
34                 (immutable size_t v, T[] edgeList)
35     if (isGraph!Graph)
36 {
37     assert(edgeList.length % 2 == 0);
38     static if (is(Graph == class))
39     {
40         auto g = new Graph;
41     }
42     else
43     {
44         auto g = Graph;
45     }
46     g.vertexCount = v;
47 
48     static if (allAtOnce)
49     {
50         g.addEdge(edgeList);
51     }
52     else
53     {
54         foreach (immutable i; 0 .. edgeList.length / 2)
55         {
56             g.addEdge(edgeList[2*i], edgeList[2 * i + 1]);
57         }
58     }
59 
60     static if (verbose > 0)
61     {
62         import std.stdio;
63         static if (g.directed)
64         {
65             writeln("Directed graph.");
66         }
67         else
68         {
69             writeln("Undirected graph.");
70         }
71         writeln("Number of vertices: ", g.vertexCount);
72         writeln("Number of edges: ", g.edgeCount);
73         static if (g.directed)
74         {
75             writeln("Incoming neighbours of vertex 0: ", g.neighboursIn(0));
76             writeln("Outgoing neighbours of vertex 0: ", g.neighboursOut(0));
77         }
78         else
79         {
80             writeln("Neighbours of node 0: ", g.neighbours(0));
81         }
82     }
83     static if (verbose > 1)
84     {
85         static if (g.directed)
86         {
87             writeln("In- and out-degrees of vertices:");
88             foreach (immutable i; 0 .. g.vertexCount)
89             {
90                 writeln("\t", i, "\t", g.degreeIn(i), "\t", g.degreeOut(i));
91             }
92         }
93         else
94         {
95             writeln("Degrees of vertices:");
96             foreach (immutable i; 0 .. g.vertexCount)
97             {
98                 writeln("\t", i, "\t", g.degree(i));
99             }
100         }
101     }
102     static if (verbose > 2)
103     {
104         writeln("Incoming neighbours for vertices:");
105         foreach (immutable i; 0 .. g.vertexCount)
106         {
107             write("\t", i, ": ");
108             foreach (immutable n; g.neighboursIn(i))
109             {
110                 write(" ", n);
111             }
112             writeln;
113             assert(isSorted(g.neighboursIn(i)));
114         }
115         writeln("Outgoing neighbours for vertices:");
116         foreach (immutable i; 0 .. g.vertexCount)
117         {
118             write("\t", i, ": ");
119             foreach (immutable n; g.neighboursOut(i))
120             {
121                 write(" ", n);
122             }
123             writeln;
124             assert(isSorted(g.neighboursOut(i)));
125         }
126     }
127 }
128 
129 /// Tests that the edgeID function returns correct values for all edges in the graph.
130 void testEdgeID(Graph)(ref Graph g)
131     if (isGraph!Graph)
132 {
133     foreach (immutable i; 0 .. g.edgeCount)
134     {
135         auto edge = g.edge[i];
136         size_t id = g.edgeID(edge[0], edge[1]);
137         enforce(i == id, text("Edge ID failure for edge ", i, ": edgeID(", edge[0], ", ", edge[1], ") returns ", id));
138         static if (!Graph.directed)
139         {
140             id = g.edgeID(edge[1], edge[0]);
141             enforce(i == id, text("Edge ID failure for edge ", i, ": edgeID(", edge[1], ", ", edge[0], ") returns ", id));
142         }
143     }
144 }
145 
146 unittest
147 {
148     import std.typetuple;
149     foreach (Graph; TypeTuple!(IndexedEdgeList, CachedEdgeList))
150     {
151         foreach (directed; TypeTuple!(false, true))
152         {
153             {
154                 import dgraph.test.samplegraph50;
155                 auto g = new Graph!directed;
156                 g.vertexCount = 50;
157                 g.addEdge(sampleGraph50);
158                 testEdgeID(g);
159             }
160 
161             {
162                 import dgraph.test.samplegraph10k;
163                 auto g = new Graph!directed;
164                 g.vertexCount = 10_000;
165                 g.addEdge(sampleGraph10k);
166                 testEdgeID(g);
167             }
168         }
169     }
170 }