Skip to content

Commit d4f4ee0

Browse files
committedFeb 8, 2024
feat(tests): add tests and fix things
1 parent 38f53f6 commit d4f4ee0

11 files changed

+612
-142
lines changed
 

‎go.mod

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ module github.com/jmCodeCraft/go-network
22

33
go 1.21.1
44

5-
require github.com/mroth/weightedrand v1.0.0
5+
require (
6+
github.com/jinzhu/copier v0.4.0
7+
github.com/mroth/weightedrand v1.0.0
8+
)

‎go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
2+
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
13
github.com/mroth/weightedrand v1.0.0 h1:V8JeHChvl2MP1sAoXq4brElOcza+jxLkRuwvtQu8L3E=
24
github.com/mroth/weightedrand v1.0.0/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=

‎io/io.go

+21-14
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ type IGraphFormatReader interface {
1818
AddNodesToGraph(g *model.UndirectedGraph, nodes []model.Node)
1919
}
2020

21-
type AdjacencyListReader struct{ IGraphFormatReader } // DONE
22-
type EdgeListReader struct{ IGraphFormatReader } // DONE
21+
type GraphFormatReader struct {
22+
IGraphFormatReader IGraphFormatReader
23+
}
24+
25+
type AdjacencyListReader struct{ GraphFormatReader } // DONE
26+
type EdgeListReader struct{ GraphFormatReader } // DONE
2327

24-
func (strategy *IGraphFormatReader) Read(reader io.Reader) model.UndirectedGraph {
25-
ng := model.UndirectedGraph{}
28+
func (strategy *GraphFormatReader) Read(reader io.Reader) (*model.UndirectedGraph, error) {
29+
ng := &model.UndirectedGraph{}
2630

2731
csvReader := csv.NewReader(reader)
2832
lineCount := 0
@@ -32,37 +36,40 @@ func (strategy *IGraphFormatReader) Read(reader io.Reader) model.UndirectedGraph
3236
if errors.Is(err, io.EOF) {
3337
break
3438
}
35-
return nil
39+
return nil, fmt.Errorf("error reading csv: %w", err)
3640
}
3741
slog.Info(fmt.Sprintf("read: %+v", read))
3842
nodes := lineToList(read)
39-
IGraphFormatReader.AddNodesToGraph(ng, nodes)
43+
strategy.IGraphFormatReader.AddNodesToGraph(ng, nodes)
4044
lineCount++
4145
}
42-
return ng
46+
return ng, nil
4347
}
4448

45-
func (strategy *IGraphFormatReader) ReadFromFile(filename string) model.UndirectedGraph {
49+
func (strategy *GraphFormatReader) ReadFromFile(filename string) (*model.UndirectedGraph, error) {
4650
readFile, err := os.Open(filename)
4751
if err != nil {
48-
return fmt.Errorf("error opening file: %w", err)
52+
return nil, fmt.Errorf("error opening file: %w", err)
4953
}
5054

51-
ng := strategy.Read(readFile)
55+
ng, err := strategy.Read(readFile)
56+
if err != nil {
57+
return nil, fmt.Errorf("error reading file: %w", err)
58+
}
5259

5360
err = readFile.Close()
5461
if err != nil {
55-
return fmt.Errorf("error closing file: %w", err)
62+
return nil, fmt.Errorf("error closing file: %w", err)
5663
}
57-
return ng
64+
return ng, nil
5865
}
5966

6067
func (a *AdjacencyListReader) AddNodesToGraph(g *model.UndirectedGraph, nodes []model.Node) {
61-
g.AddEdgesFromIntEdgeList(model.Node(nodes[0]), nodes[1:])
68+
g.AddEdgesFromIntEdgeList(nodes[0], nodes[1:])
6269
}
6370

6471
func (a *EdgeListReader) AddNodesToGraph(g *model.UndirectedGraph, nodes []model.Node) {
65-
g.AddEdge(model.Edge{nodes[0], nodes[1]})
72+
g.AddEdge(model.Edge{Node1: nodes[0], Node2: nodes[1]})
6673
}
6774

6875
/*

‎io/io_test.go

-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
package io
22

33
import (
4-
"bytes"
54
"testing"
65
)
76

8-
func TestFromAdjacencyList(t *testing.T) {
9-
var buffer bytes.Buffer
10-
buffer.WriteString("1,2\n2,3\n3,4\n")
11-
FromAdjacencyList(&buffer)
12-
}
13-
147
func TestLinetoList(t *testing.T) {
158
list := lineToList([]string{"1", "2", "3"})
169

‎model/generator_classic.go

+23-8
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,39 @@ func CompleteGraph(numberOfNodes int) *UndirectedGraph {
1414
}
1515

1616
// LadderGraph returns the Ladder graph of length n and 2n nodes
17-
func LadderGraph(nodesInSinglePath int) (g UndirectedGraph) {
18-
g = UndirectedGraph{}
19-
edgesLadder1 := Pairwise(Range(nodesInSinglePath, 2*nodesInSinglePath))
20-
for i := 0; i <= len(edgesLadder1); i++ {
21-
g.AddEdge(edgesLadder1[i])
17+
func LadderGraph(nodesInSinglePath int) *UndirectedGraph {
18+
g := &UndirectedGraph{}
19+
20+
// Generate and add edges for the ladder structure
21+
for _, edge := range Pairwise(Range(nodesInSinglePath, 2*nodesInSinglePath)) {
22+
g.AddEdge(edge)
2223
}
23-
for i := 0; i <= nodesInSinglePath; i++ {
24+
25+
// Add rung edges between the two paths of the ladder
26+
for i := 0; i < nodesInSinglePath; i++ {
2427
g.AddEdge(Edge{
2528
Node1: Node(i),
2629
Node2: Node(i + nodesInSinglePath),
2730
})
31+
32+
if i != nodesInSinglePath-1 {
33+
g.AddEdge(Edge{
34+
Node1: Node(i + nodesInSinglePath),
35+
Node2: Node(i + nodesInSinglePath + 1),
36+
})
37+
g.AddEdge(Edge{
38+
Node1: Node(i),
39+
Node2: Node(i + 1),
40+
})
41+
}
2842
}
43+
2944
return g
3045
}
3146

3247
// CircularLadderGraph returns the circular ladder graph $CL_n$ of length n
33-
func CircularLadderGraph(nodesInSinglePath int) (g UndirectedGraph) {
34-
g = LadderGraph(nodesInSinglePath)
48+
func CircularLadderGraph(nodesInSinglePath int) *UndirectedGraph {
49+
g := LadderGraph(nodesInSinglePath)
3550
g.AddEdge(Edge{
3651
Node2: Node(nodesInSinglePath - 1),
3752
})

‎model/generator_classic_test.go

+172
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package model
22

33
import (
4+
"fmt"
5+
"reflect"
46
"testing"
57
)
68

@@ -57,3 +59,173 @@ func TestCompleteGraph(t *testing.T) {
5759
})
5860
}
5961
}
62+
63+
func TestLadderGraph(t *testing.T) {
64+
testCases := []struct {
65+
nodes int
66+
expectedNodes map[Node]bool
67+
expectedEdges map[Node][]Node
68+
}{
69+
{
70+
nodes: 0,
71+
expectedNodes: map[Node]bool{},
72+
expectedEdges: map[Node][]Node{},
73+
},
74+
{
75+
nodes: 3,
76+
expectedNodes: map[Node]bool{
77+
0: true, 1: true, 2: true, 3: true, 4: true, 5: true,
78+
},
79+
expectedEdges: map[Node][]Node{
80+
0: {1, 3},
81+
1: {0, 2, 4},
82+
2: {1, 5},
83+
3: {0, 4},
84+
4: {1, 3, 5},
85+
5: {2, 4},
86+
},
87+
},
88+
{
89+
nodes: 5,
90+
expectedNodes: map[Node]bool{
91+
0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true,
92+
},
93+
expectedEdges: map[Node][]Node{
94+
0: {1},
95+
1: {0, 2},
96+
2: {1, 3},
97+
3: {2, 4},
98+
4: {3, 5},
99+
5: {4, 6},
100+
6: {5, 7},
101+
7: {6, 8},
102+
8: {7, 9},
103+
9: {8, 10},
104+
10: {9},
105+
},
106+
},
107+
{
108+
nodes: 2,
109+
expectedNodes: map[Node]bool{
110+
0: true, 1: true, 2: true,
111+
},
112+
expectedEdges: map[Node][]Node{
113+
0: {1},
114+
1: {0, 2},
115+
2: {1},
116+
},
117+
},
118+
{
119+
nodes: 1,
120+
expectedNodes: map[Node]bool{
121+
0: true, 1: true,
122+
},
123+
expectedEdges: map[Node][]Node{
124+
0: {1},
125+
1: {0},
126+
},
127+
},
128+
}
129+
130+
for _, tc := range testCases {
131+
t.Run(fmt.Sprintf("Nodes: %d", tc.nodes), func(t *testing.T) {
132+
g := LadderGraph(tc.nodes)
133+
validateGraph(t, g, tc.expectedNodes, tc.expectedEdges)
134+
})
135+
}
136+
}
137+
138+
func TestCircularLadderGraph(t *testing.T) {
139+
// Test case 1: Basic Test
140+
nodesInSinglePath := 4
141+
g := CircularLadderGraph(nodesInSinglePath)
142+
expectedNodes := map[Node]bool{1: true, 2: true, 3: true, 4: true, 5: true, 6: true}
143+
expectedEdges := map[Node][]Node{
144+
1: {2, 6},
145+
2: {1, 3},
146+
3: {2, 4},
147+
4: {3, 5},
148+
5: {4, 6},
149+
6: {1, 5},
150+
}
151+
validateGraph(t, g, expectedNodes, expectedEdges)
152+
153+
// Test case 2: Edge Case Test
154+
nodesInSinglePath = 2
155+
g = CircularLadderGraph(nodesInSinglePath)
156+
expectedNodes = map[Node]bool{1: true, 2: true, 3: true}
157+
expectedEdges = map[Node][]Node{
158+
1: {2, 3},
159+
2: {1, 3},
160+
3: {1, 2},
161+
}
162+
validateGraph(t, g, expectedNodes, expectedEdges)
163+
164+
// Test case 3: Larger Graph Test
165+
nodesInSinglePath = 6
166+
g = CircularLadderGraph(nodesInSinglePath)
167+
expectedNodes = map[Node]bool{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true}
168+
expectedEdges = map[Node][]Node{
169+
1: {2, 12},
170+
2: {1, 3},
171+
3: {2, 4},
172+
4: {3, 5},
173+
5: {4, 6},
174+
6: {5, 7},
175+
7: {6, 8},
176+
8: {7, 9},
177+
9: {8, 10},
178+
10: {9, 11},
179+
11: {10, 12},
180+
12: {1, 11},
181+
}
182+
validateGraph(t, g, expectedNodes, expectedEdges)
183+
184+
// Test case 4: Connectivity Test
185+
// Validate if all nodes are properly connected
186+
for node, neighbors := range g.Edges {
187+
for _, neighbor := range neighbors {
188+
if !contains(g.Edges[neighbor], node) {
189+
t.Errorf("Test case 4 failed: Nodes %d and %d are not properly connected", node, neighbor)
190+
}
191+
}
192+
}
193+
194+
// Test case 5: Node Existence Test
195+
// Validate if all expected nodes exist
196+
for node := range expectedNodes {
197+
if !g.Nodes[node] {
198+
t.Errorf("Test case 5 failed: Expected node %d does not exist in the generated graph", node)
199+
}
200+
}
201+
}
202+
203+
// Helper function to validate the generated graph
204+
func validateGraph(t *testing.T, g *UndirectedGraph, expectedNodes map[Node]bool, expectedEdges map[Node][]Node) {
205+
// Validate nodes
206+
if len(g.Nodes) != len(expectedNodes) {
207+
t.Errorf("Nodes mismatch, expected: %v, got: %v", expectedNodes, g.Nodes)
208+
} else {
209+
for node := range expectedNodes {
210+
if !g.Nodes[node] {
211+
t.Errorf("Nodes mismatch, expected: %v, got: %v", expectedNodes, g.Nodes)
212+
}
213+
}
214+
}
215+
// Validate edges
216+
for node, edges := range expectedEdges {
217+
if !reflect.DeepEqual(g.Edges[node], edges) {
218+
t.Errorf("Edges mismatch for node %d, expected: %v, got: %v. Full graph: %v", node, edges, g.Edges[node], g)
219+
}
220+
}
221+
}
222+
223+
// Helper function to check if a node exists in a slice
224+
func contains(slice []Node, value Node) bool {
225+
for _, item := range slice {
226+
if item == value {
227+
return true
228+
}
229+
}
230+
return false
231+
}

0 commit comments

Comments
 (0)
Please sign in to comment.