Skip to content

Commit 1f32fad

Browse files
committed
Rename some stuff. Add tests. Add convenience functions.
1 parent c45b020 commit 1f32fad

6 files changed

+101
-7
lines changed

Code/Graph+Algorithms/Graph+Condensation.swift renamed to Code/Graph+Algorithms/Graph+CondensationGraph.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public extension Graph
88

99
See <https://en.wikipedia.org/wiki/Strongly_connected_component>
1010
*/
11-
func makeCondensation() -> CondensationGraph
11+
func makeCondensationGraph() -> CondensationGraph
1212
{
1313
// get SCCs
1414
let sccs = findStronglyConnectedComponents().map { StronglyConnectedComponent(nodes: $0) }

Code/Graph/Graph.swift

+12-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ public class Graph<NodeID: Hashable, NodeValue>
2727

2828
// MARK: - Edges
2929

30+
public func removeEdge(from sourceID: NodeID, to targetID: NodeID)
31+
{
32+
removeEdge(with: .init(sourceID, targetID))
33+
}
34+
35+
public func removeEdge(from source: Node, to target: Node)
36+
{
37+
removeEdge(with: .init(source, target))
38+
}
39+
3040
public func removeEdge(with id: Edge.ID)
3141
{
3242
guard let edge = edgesByID[id] else { return }
@@ -63,7 +73,7 @@ public class Graph<NodeID: Hashable, NodeValue>
6373
to target: Node,
6474
count: Int = 1) -> Edge
6575
{
66-
let edgeID = Edge.ID(source: source, target: target)
76+
let edgeID = Edge.ID(source, target)
6777

6878
if let edge = edgesByID[edgeID]
6979
{
@@ -94,7 +104,7 @@ public class Graph<NodeID: Hashable, NodeValue>
94104

95105
public func edge(from sourceID: NodeID, to targetID: NodeID) -> Edge?
96106
{
97-
edgesByID[.init(sourceID: sourceID, targetID: targetID)]
107+
edgesByID[.init(sourceID, targetID)]
98108
}
99109

100110
public var edges: Dictionary<Edge.ID, Edge>.Values

Code/Graph/GraphEdge.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ public class GraphEdge<NodeID: Hashable, NodeValue>: Identifiable, Hashable
1010

1111
// MARK: - Identity
1212

13-
public var id: ID { ID(source: source, target: target) }
13+
public var id: ID { ID(source, target) }
1414

1515
public struct ID: Hashable
1616
{
17-
internal init(source: Node, target: Node)
17+
internal init(_ source: Node, _ target: Node)
1818
{
19-
self.init(sourceID: source.id, targetID: target.id)
19+
self.init(source.id, target.id)
2020
}
2121

22-
internal init(sourceID: NodeID, targetID: NodeID)
22+
internal init(_ sourceID: NodeID, _ targetID: NodeID)
2323
{
2424
self.sourceID = sourceID
2525
self.targetID = targetID

Tests/SwiftNodesTests.swift

+84
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,90 @@ import XCTest
33

44
class SwiftNodesTests: XCTestCase {
55

6+
func testCodeExamplesFromREADME() throws {
7+
let graph = Graph<String, Int> { "id\($0)" } // NodeID == String, NodeValue == Int
8+
let node1 = graph.insert(1) // node1.id == "id1"
9+
10+
let valueForID1 = graph.value(for: "id1") // valueForID1 == 1
11+
let nodeForID1 = graph.node(for: "id1") // nodeForID1 === node1
12+
13+
XCTAssertEqual(valueForID1, node1.value)
14+
XCTAssertIdentical(nodeForID1, node1)
15+
}
16+
17+
func testAddingEdges() throws {
18+
let graph = Graph<String, Int> { "id\($0)" }
19+
let node1 = graph.insert(1)
20+
let node2 = graph.insert(2)
21+
graph.addEdge(from: node1, to: node2)
22+
23+
XCTAssertNotNil(graph.edge(from: node1, to: node2))
24+
XCTAssertNil(graph.edge(from: node2, to: node1))
25+
XCTAssertEqual(graph.edge(from: node1, to: node2)?.count, 1)
26+
}
27+
28+
func testAddingEdgeWithBigCount() throws {
29+
let graph = Graph<String, Int> { "id\($0)" }
30+
let node1 = graph.insert(1)
31+
let node2 = graph.insert(2)
32+
33+
graph.addEdge(from: node1, to: node2, count: 42)
34+
XCTAssertEqual(graph.edge(from: node1, to: node2)?.count, 42)
35+
36+
graph.addEdge(from: node1, to: node2, count: 58)
37+
XCTAssertEqual(graph.edge(from: node1, to: node2)?.count, 100)
38+
}
39+
40+
func testEdgesAreDirected() throws {
41+
let graph = Graph<String, Int> { "id\($0)" }
42+
let node1 = graph.insert(1)
43+
let node2 = graph.insert(2)
44+
XCTAssertNotNil(graph.addEdge(from: node1, to: node2))
45+
XCTAssertNil(graph.edge(from: node2, to: node1))
46+
}
47+
48+
func testUUIDAsID() throws {
49+
let graph = Graph<UUID, Int> { _ in UUID() } // NodeID == UUID, NodeValue == Int
50+
let node1 = graph.insert(1)
51+
let node2 = graph.insert(1)
52+
XCTAssertNotIdentical(node1, node2)
53+
XCTAssertEqual(node1.value, node2.value)
54+
XCTAssertNotEqual(node1.id, node2.id)
55+
}
56+
57+
func testOmittingClosureForIdentifiableValues() throws {
58+
struct IdentifiableValue: Identifiable { let id = UUID() }
59+
let graph = Graph<UUID, IdentifiableValue>() // NodeID == NodeValue.ID == UUID
60+
let node = graph.insert(IdentifiableValue()) // node.id == node.value.id
61+
XCTAssertEqual(node.id, node.value.id)
62+
}
63+
64+
func testSorting() throws {
65+
let graph = Graph<Int, Int>()
66+
67+
let node1 = graph.insert(1)
68+
let node2 = graph.insert(2)
69+
let edge = graph.addEdge(from: node1, to: node2)
70+
71+
graph.remove(edge)
72+
graph.removeEdge(with: edge.id)
73+
graph.removeEdge(with: .init(node1, node2))
74+
graph.removeEdge(with: .init(node1.id, node2.id))
75+
graph.removeEdge(from: node1, to: node2)
76+
graph.removeEdge(from: node1.id, to: node2.id)
77+
}
78+
79+
func testWaysToRemoveAnEdgeCompile() {
80+
let graph = Graph<Int, Int>()
81+
graph.insert(5)
82+
graph.insert(3)
83+
84+
graph.remove(edge)
85+
graph.removeEdge(from: node1, to: node2)
86+
graph.removeEdge(from: node1.id, to: node2.id)
87+
graph.removeEdge(with: edge.id)
88+
}
89+
690
func testInsertingConnectingAndDisconnectingValues() throws {
791
let graph = Graph<String, Int> { "id\($0)" }
892
XCTAssertNil(graph.node(for: "id1"))

0 commit comments

Comments
 (0)