1 | describe('default Graph', () => {
|
2 | const no = require('not-defined')
|
3 | const should = require('should')
|
4 | const Graph = require('iper').Graph
|
5 |
|
6 | describe('constructor', () => {
|
7 | it('defaults to an empty generic graph', () => {
|
8 | const graph = new Graph()
|
9 |
|
10 | graph.edges.should.deepEqual({})
|
11 | graph.nodes.should.deepEqual({})
|
12 |
|
13 | should.not.exist(graph.multigraph)
|
14 | should.not.exist(graph.pseudograph)
|
15 | should.not.exist(graph.uniform)
|
16 | })
|
17 | })
|
18 |
|
19 | describe('addNode()', () => {
|
20 | it('creates a node', () => {
|
21 | const graph = new Graph()
|
22 | const nodeData = 'foo'
|
23 |
|
24 | const nodeId = graph.addNode(nodeData)
|
25 |
|
26 | graph.nodes[nodeId].should.be.eql(nodeData)
|
27 | })
|
28 |
|
29 | it('returns an id', () => {
|
30 | const graph = new Graph()
|
31 |
|
32 | const nodeId = graph.addNode()
|
33 |
|
34 | nodeId.should.be.a.String()
|
35 | })
|
36 | })
|
37 |
|
38 | describe('addEdge()', () => {
|
39 | it('creates an edge', () => {
|
40 | const graph = new Graph()
|
41 |
|
42 | const nodeId1 = graph.addNode()
|
43 | const nodeId2 = graph.addNode()
|
44 | const nodeIds = [nodeId1, nodeId2]
|
45 |
|
46 | const edgeId = graph.addEdge(nodeIds)
|
47 |
|
48 | graph.edges[edgeId].should.be.eql(nodeIds)
|
49 | })
|
50 |
|
51 | it('requires at least two nodeIds', () => {
|
52 | const graph = new Graph()
|
53 |
|
54 | const nodeId = graph.addNode()
|
55 |
|
56 | const nodeIds = [nodeId]
|
57 |
|
58 | ;(() => {
|
59 | graph.addEdge(nodeIds)
|
60 | }).should.throw()
|
61 | })
|
62 |
|
63 | it('cannot create an edge pointing to some nodeId not found', () => {
|
64 | const graph = new Graph()
|
65 |
|
66 | const nodeId1 = graph.addNode()
|
67 | const nodeId2 = graph.addNode()
|
68 |
|
69 | const nodeIds = [nodeId1, 'nodeIdNotFound', nodeId2]
|
70 |
|
71 | ;(() => {
|
72 | graph.addEdge(nodeIds)
|
73 | }).should.throw()
|
74 | })
|
75 |
|
76 | it('can create edges with cardinality greater than 2', () => {
|
77 | const graph = new Graph()
|
78 |
|
79 | const nodeId1 = graph.addNode()
|
80 | const nodeId2 = graph.addNode()
|
81 | const nodeId3 = graph.addNode()
|
82 |
|
83 | const nodeIds = [nodeId1, nodeId2, nodeId3]
|
84 |
|
85 | const edgeId1 = graph.addEdge(nodeIds)
|
86 |
|
87 | graph.edges[edgeId1].should.be.eql(nodeIds)
|
88 | })
|
89 |
|
90 | it('returns an id', () => {
|
91 | const graph = new Graph()
|
92 |
|
93 | const nodeId1 = graph.addNode()
|
94 | const nodeId2 = graph.addNode()
|
95 |
|
96 | const nodeIds = [nodeId1, nodeId2]
|
97 |
|
98 | const edgeId = graph.addEdge(nodeIds)
|
99 |
|
100 | edgeId.should.be.a.String()
|
101 | })
|
102 |
|
103 | it('cannot create loops', () => {
|
104 | const graph = new Graph()
|
105 |
|
106 | const nodeId = graph.addNode()
|
107 |
|
108 | const nodeIds = [nodeId, nodeId]
|
109 |
|
110 | ;(() => {
|
111 | graph.addEdge(nodeIds)
|
112 | }).should.throw()
|
113 | })
|
114 |
|
115 | it('cannot create duplicated edges', () => {
|
116 | const graph = new Graph()
|
117 |
|
118 | const nodeId = graph.addNode()
|
119 | const nodeIds = [nodeId, nodeId]
|
120 |
|
121 | ;(() => {
|
122 | graph.addEdge(nodeIds)
|
123 | }).should.throw()
|
124 | })
|
125 | })
|
126 |
|
127 | describe('degreeOf(nodeId)', () => {
|
128 | it('returns the degree of a node', () => {
|
129 | const graph = new Graph()
|
130 |
|
131 | const nodeId1 = graph.addNode()
|
132 | const nodeId2 = graph.addNode()
|
133 | const nodeIds = [nodeId1, nodeId2]
|
134 |
|
135 | graph.addEdge(nodeIds)
|
136 |
|
137 | graph.degreeOf(nodeId1).should.be.eql(1)
|
138 | })
|
139 | })
|
140 |
|
141 | describe('delNode()', () => {
|
142 | it('removes a node', () => {
|
143 | const graph = new Graph()
|
144 | const nodeData = 'foo'
|
145 |
|
146 | const nodeId = graph.addNode(nodeData)
|
147 |
|
148 | graph.nodes[nodeId].should.be.eql(nodeData)
|
149 |
|
150 | graph.delNode(nodeId)
|
151 |
|
152 | const nodeNotDefined = no(graph.nodes[nodeId])
|
153 |
|
154 | nodeNotDefined.should.be.true()
|
155 | })
|
156 |
|
157 | it('removes incident edges', () => {
|
158 | const graph = new Graph()
|
159 |
|
160 | const nodeId1 = graph.addNode()
|
161 | const nodeId2 = graph.addNode()
|
162 | const nodeIds = [nodeId1, nodeId2]
|
163 |
|
164 | const edgeId = graph.addEdge(nodeIds)
|
165 |
|
166 | graph.edges[edgeId].should.be.eql(nodeIds)
|
167 |
|
168 | graph.delNode(nodeId1)
|
169 |
|
170 | const incidentEdgeRemoved = no(graph.edges[edgeId])
|
171 | incidentEdgeRemoved.should.be.true()
|
172 | })
|
173 | })
|
174 |
|
175 | describe('delEdge()', () => {
|
176 | it('removes an edge', () => {
|
177 | const graph = new Graph()
|
178 | const nodeId1 = graph.addNode()
|
179 | const nodeId2 = graph.addNode()
|
180 | const nodeIds = [nodeId1, nodeId2]
|
181 |
|
182 | const edgeId = graph.addEdge(nodeIds)
|
183 |
|
184 | graph.delEdge(edgeId)
|
185 |
|
186 | const edgeNotDefined = no(graph.edges[edgeId])
|
187 | edgeNotDefined.should.be.true()
|
188 | })
|
189 | })
|
190 |
|
191 | describe('getRank()', () => {
|
192 | it('returns the max cardinality of any edge', () => {
|
193 | const graph = new Graph()
|
194 |
|
195 | const nodeId1 = graph.addNode()
|
196 | const nodeId2 = graph.addNode()
|
197 | const nodeId3 = graph.addNode()
|
198 | const nodeId4 = graph.addNode()
|
199 |
|
200 | graph.addEdge([nodeId1, nodeId2])
|
201 | graph.addEdge([nodeId3, nodeId2])
|
202 | graph.addEdge([nodeId1, nodeId4])
|
203 |
|
204 | graph.getRank().should.be.eql(2)
|
205 |
|
206 | graph.addEdge([nodeId1, nodeId2, nodeId3])
|
207 |
|
208 | graph.getRank().should.be.eql(3)
|
209 |
|
210 | graph.addEdge([nodeId4, nodeId1, nodeId2, nodeId3])
|
211 |
|
212 | graph.getRank().should.be.eql(4)
|
213 | })
|
214 | })
|
215 | })
|