@@ -12,6 +12,12 @@ using shared = std::shared_ptr<T>;
1212using std::make_shared;
1313using std::make_unique;
1414
15+ /*
16+ * 3 Nodes
17+ * Node1 -> Node2 weight = 1
18+ * Node2 -> Node3 weight = 1
19+ * Node1 <-> Node3 weight = 6
20+ */
1521TEST (DialTest, test_1) {
1622 CXXGraph::Node<int > node1 (" 1" , 1 );
1723 CXXGraph::Node<int > node2 (" 2" , 2 );
@@ -34,6 +40,12 @@ TEST(DialTest, test_1) {
3440 ASSERT_EQ (res.minDistanceMap .at (node3.getId ()), 2 );
3541}
3642
43+ /*
44+ * 3 Nodes
45+ * Node1 -> Node2 weight = 5
46+ * Node2 -> Node3 weight = 4
47+ * Node1 <-> Node3 weight = 6
48+ */
3749TEST (DialTest, test_2) {
3850 CXXGraph::Node<int > node1 (" 1" , 1 );
3951 CXXGraph::Node<int > node2 (" 2" , 2 );
@@ -57,6 +69,12 @@ TEST(DialTest, test_2) {
5769 ASSERT_EQ (res.minDistanceMap .at (node3.getId ()), 6 );
5870}
5971
72+ /*
73+ * 3 Nodes
74+ * Node1 -> Node2 weight = 5
75+ * Node2 -> Node3 unweighted
76+ * Node1 <-> Node3 weight = 6
77+ */
6078TEST (DialTest, test_3) {
6179 CXXGraph::Node<int > node1 (" 1" , 1 );
6280 CXXGraph::Node<int > node2 (" 2" , 2 );
@@ -77,6 +95,11 @@ TEST(DialTest, test_3) {
7795 ASSERT_TRUE (res.minDistanceMap .empty ());
7896}
7997
98+ /*
99+ * 3 Nodes
100+ * Node2 -> Node3 unweighted
101+ * Node1 <-> Node3 weight = 6
102+ */
80103TEST (DialTest, test_4) {
81104 CXXGraph::Node<int > node1 (" 1" , 1 );
82105 CXXGraph::Node<int > node2 (" 2" , 2 );
@@ -96,6 +119,12 @@ TEST(DialTest, test_4) {
96119 ASSERT_EQ (res.minDistanceMap .at (node3.getId ()), 6 );
97120}
98121
122+ /*
123+ * 4 Nodes
124+ * Node2 -> Node3 unweighted
125+ * Node1 <-> Node3 weight = 6
126+ * Only nodes which are a part of the edgeSet are a part of the graph (nodeSet)
127+ */
99128TEST (DialTest, test_5) {
100129 CXXGraph::Node<int > node1 (" 1" , 1 );
101130 CXXGraph::Node<int > node2 (" 2" , 2 );
@@ -112,3 +141,153 @@ TEST(DialTest, test_5) {
112141 ASSERT_EQ (res.errorMessage , CXXGraph::ERR_SOURCE_NODE_NOT_IN_GRAPH);
113142 ASSERT_TRUE (res.minDistanceMap .empty ());
114143}
144+
145+ /*
146+ * 3 Nodes, zero weight edges
147+ * Node1 -> Node2 weight = 0
148+ * Node2 -> Node3 weight = 0
149+ */
150+ TEST (DialTest, test_6) {
151+ CXXGraph::Node<int > node1 (" 1" , 1 );
152+ CXXGraph::Node<int > node2 (" 2" , 2 );
153+ CXXGraph::Node<int > node3 (" 3" , 3 );
154+
155+ CXXGraph::DirectedWeightedEdge<int > edge12 (1 , node1, node2, 0 );
156+ CXXGraph::DirectedWeightedEdge<int > edge23 (1 , node2, node3, 0 );
157+
158+ CXXGraph::T_EdgeSet<int > edgeSet;
159+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge12));
160+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge23));
161+
162+ CXXGraph::Graph<int > graph (edgeSet);
163+
164+ // Setting maxWeight = 0 causes an early exit
165+ // As a consequence all distances except source node are at infinity.
166+ auto res = graph.dial (node1, 1 );
167+ ASSERT_TRUE (res.success );
168+ ASSERT_EQ (res.errorMessage , " " );
169+ ASSERT_EQ (res.minDistanceMap .at (node1.getId ()), 0 );
170+ ASSERT_EQ (res.minDistanceMap .at (node2.getId ()), 0 );
171+ ASSERT_EQ (res.minDistanceMap .at (node3.getId ()), 0 );
172+ }
173+
174+ /*
175+ * 2 Nodes, multi edges, same end points, choose smaller edge
176+ * Node1 -> Node2 weight = 3
177+ * Node1 -> Node2 weight = 5
178+ */
179+ TEST (DialTest, test_7) {
180+ CXXGraph::Node<int > node1 (" 1" , 1 );
181+ CXXGraph::Node<int > node2 (" 2" , 2 );
182+
183+ CXXGraph::DirectedWeightedEdge<int > edge12First (1 , node1, node2, 3 );
184+ CXXGraph::DirectedWeightedEdge<int > edge12Second (1 , node1, node2, 5 );
185+
186+ CXXGraph::T_EdgeSet<int > edgeSet;
187+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge12First));
188+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge12Second));
189+
190+ CXXGraph::Graph<int > graph (edgeSet);
191+
192+ auto res = graph.dial (node1, 5 );
193+ ASSERT_TRUE (res.success );
194+ ASSERT_EQ (res.errorMessage , " " );
195+ ASSERT_EQ (res.minDistanceMap .at (node1.getId ()), 0 );
196+ ASSERT_EQ (res.minDistanceMap .at (node2.getId ()), 3 );
197+ }
198+
199+ /*
200+ * 3 Nodes, multi edges with a cycle, cycle should not trap algorithm
201+ * Node1 -> Node2 weight = 3
202+ * Node2 -> Node3 weight = 5
203+ * Node3 -> Node1 weight = 8
204+ * Node1 -> Node3 weight = 2
205+ */
206+ TEST (DialTest, test_8) {
207+ CXXGraph::Node<int > node1 (" 1" , 1 );
208+ CXXGraph::Node<int > node2 (" 2" , 2 );
209+ CXXGraph::Node<int > node3 (" 3" , 3 );
210+
211+ CXXGraph::DirectedWeightedEdge<int > edge12 (1 , node1, node2, 3 );
212+ CXXGraph::DirectedWeightedEdge<int > edge23 (1 , node2, node3, 5 );
213+ CXXGraph::DirectedWeightedEdge<int > edge31 (1 , node3, node1, 8 );
214+ CXXGraph::DirectedWeightedEdge<int > edge13 (1 , node1, node3, 2 );
215+
216+ CXXGraph::T_EdgeSet<int > edgeSet;
217+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge12));
218+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge23));
219+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge31));
220+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge13));
221+
222+ CXXGraph::Graph<int > graph (edgeSet);
223+
224+ auto res = graph.dial (node1, 5 );
225+ ASSERT_TRUE (res.success );
226+ ASSERT_EQ (res.errorMessage , " " );
227+ ASSERT_EQ (res.minDistanceMap .at (node1.getId ()), 0 );
228+ ASSERT_EQ (res.minDistanceMap .at (node2.getId ()), 3 );
229+ ASSERT_EQ (res.minDistanceMap .at (node3.getId ()), 2 );
230+ }
231+
232+ /*
233+ * 2 Nodes, self loop
234+ * Node1 -> Node1 weight = 3
235+ * Node1 -> Node2 weight = 5
236+ */
237+ TEST (DialTest, test_9) {
238+ CXXGraph::Node<int > node1 (" 1" , 1 );
239+ CXXGraph::Node<int > node2 (" 2" , 2 );
240+
241+ CXXGraph::DirectedWeightedEdge<int > edge11 (1 , node1, node1, 3 );
242+ CXXGraph::DirectedWeightedEdge<int > edge12 (1 , node1, node2, 5 );
243+
244+ CXXGraph::T_EdgeSet<int > edgeSet;
245+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge11));
246+ edgeSet.insert (make_shared<CXXGraph::DirectedWeightedEdge<int >>(edge12));
247+
248+ CXXGraph::Graph<int > graph (edgeSet);
249+
250+ auto res = graph.dial (node1, 5 );
251+ ASSERT_TRUE (res.success );
252+ ASSERT_EQ (res.errorMessage , " " );
253+ ASSERT_EQ (res.minDistanceMap .at (node1.getId ()), 0 );
254+ ASSERT_EQ (res.minDistanceMap .at (node2.getId ()), 5 );
255+ }
256+
257+ template <typename T>
258+ class BadDirectedWeightedEdge : public CXXGraph ::DirectedWeightedEdge<T> {
259+ public:
260+ using Base = CXXGraph::DirectedWeightedEdge<T>;
261+ // forward to existing ctor
262+ BadDirectedWeightedEdge (const CXXGraph::id_t id,
263+ const CXXGraph::Node<T> &n1,
264+ const CXXGraph::Node<T> &n2,
265+ const double weight)
266+ : Base(id, n1, n2, weight) {}
267+
268+ const std::optional<bool > isDirected () const override {
269+ return std::nullopt ;
270+ }
271+ };
272+
273+ /*
274+ * 2 Nodes, invalid directed weighted edge
275+ * The edge claims it's weighted but does not tell us direction
276+ * Node1 -> Node2 weight = 5
277+ */
278+ TEST (DialTest, test_10) {
279+ CXXGraph::Node<int > node1 (" 1" , 1 );
280+ CXXGraph::Node<int > node2 (" 2" , 2 );
281+
282+ auto badEdge = std::make_shared<BadDirectedWeightedEdge<int >>(1 , node1, node2, 5 );
283+
284+ CXXGraph::T_EdgeSet<int > edgeSet;
285+ edgeSet.insert (badEdge);
286+
287+ CXXGraph::Graph<int > graph (edgeSet);
288+
289+ auto res = graph.dial (node1, 5 );
290+ ASSERT_FALSE (res.success );
291+ ASSERT_EQ (res.errorMessage , CXXGraph::ERR_NO_DIR_OR_UNDIR_EDGE);
292+ ASSERT_TRUE (res.minDistanceMap .empty ());
293+ }
0 commit comments