occam-directed-graphs 3.0.83 → 3.0.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -2
- package/.aiignore +0 -11
- package/.swcrc +0 -8
- package/bin/main.js +0 -15
- package/example.js +0 -3113
- package/index.html +0 -29
- package/test/cirectedGraph.js +0 -589
package/index.html
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Occam Directed Graphs</title>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<script src="example.js"> </script>
|
|
9
|
-
|
|
10
|
-
<script>
|
|
11
|
-
|
|
12
|
-
var xmlHttpRequest = new XMLHttpRequest();
|
|
13
|
-
|
|
14
|
-
xmlHttpRequest.onreadystatechange = function() {
|
|
15
|
-
if (xmlHttpRequest.readyState == 4) {
|
|
16
|
-
if (xmlHttpRequest.status == 200) {
|
|
17
|
-
location.reload();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
xmlHttpRequest.open("GET", "/live-reload");
|
|
23
|
-
|
|
24
|
-
xmlHttpRequest.send();
|
|
25
|
-
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
</body>
|
|
29
|
-
</html>
|
package/test/cirectedGraph.js
DELETED
|
@@ -1,589 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { assert } = require("chai"),
|
|
4
|
-
{ arrayUtilities } = require("necessary"),
|
|
5
|
-
{ Edge, Cycle, DirectedGraph } = require("../lib/index"); ///
|
|
6
|
-
|
|
7
|
-
const { first, second, third, fourth } = arrayUtilities;
|
|
8
|
-
|
|
9
|
-
describe("DirectedGraph", () => {
|
|
10
|
-
const vertexNameA = "a",
|
|
11
|
-
vertexNameB = "b",
|
|
12
|
-
vertexNameC = "c",
|
|
13
|
-
vertexNameD = "d",
|
|
14
|
-
vertexNameE = "e";
|
|
15
|
-
|
|
16
|
-
describe("getFirstCycle", () => {
|
|
17
|
-
describe("there are no cycles", () => {
|
|
18
|
-
let directedGraph;
|
|
19
|
-
|
|
20
|
-
before(() => {
|
|
21
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("returns null", () => {
|
|
25
|
-
const firstCycle = directedGraph.getFirstCycle();
|
|
26
|
-
|
|
27
|
-
assert.isNull(firstCycle);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe("there is a cycle present", () => {
|
|
32
|
-
let directedGraph;
|
|
33
|
-
|
|
34
|
-
before(() => {
|
|
35
|
-
const vertexNamesArray = [
|
|
36
|
-
[ vertexNameA, vertexNameB ],
|
|
37
|
-
[ vertexNameB, vertexNameC ],
|
|
38
|
-
[ vertexNameC, vertexNameD ],
|
|
39
|
-
[ vertexNameD, vertexNameE ],
|
|
40
|
-
[ vertexNameE, vertexNameB ]
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("returns a cycle", () => {
|
|
47
|
-
const firstCycle = directedGraph.getFirstCycle();
|
|
48
|
-
|
|
49
|
-
assert.instanceOf(firstCycle, Cycle);
|
|
50
|
-
|
|
51
|
-
const vertexNames = firstCycle.getVertexNames();
|
|
52
|
-
|
|
53
|
-
assert.deepEqual(vertexNames, [
|
|
54
|
-
vertexNameB,
|
|
55
|
-
vertexNameC,
|
|
56
|
-
vertexNameD,
|
|
57
|
-
vertexNameE
|
|
58
|
-
]);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe("areCyclesPresent", () => {
|
|
64
|
-
describe("there are no cycles", () => {
|
|
65
|
-
let directedGraph;
|
|
66
|
-
|
|
67
|
-
before(() => {
|
|
68
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("returns false", () => {
|
|
72
|
-
const cyclesPresent = directedGraph.areCyclesPresent();
|
|
73
|
-
|
|
74
|
-
assert.isFalse(cyclesPresent);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe("there is a cycle", () => {
|
|
79
|
-
let directedGraph;
|
|
80
|
-
|
|
81
|
-
before(() => {
|
|
82
|
-
const vertexNamesArray = [
|
|
83
|
-
[ vertexNameA, vertexNameB ],
|
|
84
|
-
[ vertexNameB, vertexNameA ]
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("returns true", () => {
|
|
91
|
-
const cyclesPresent = directedGraph.areCyclesPresent();
|
|
92
|
-
|
|
93
|
-
assert.isTrue(cyclesPresent);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
describe("there is a cycle one edge of which is subsequently removed", () => {
|
|
98
|
-
let directedGraph;
|
|
99
|
-
|
|
100
|
-
before(() => {
|
|
101
|
-
const vertexNamesArray = [
|
|
102
|
-
[ vertexNameA, vertexNameB ],
|
|
103
|
-
[ vertexNameB, vertexNameA ]
|
|
104
|
-
];
|
|
105
|
-
|
|
106
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
before(() => {
|
|
110
|
-
const sourceVertexName = vertexNameA, ///
|
|
111
|
-
targetVertexName = vertexNameB, ////
|
|
112
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
113
|
-
|
|
114
|
-
directedGraph.removeEdge(edge);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("returns false", () => {
|
|
118
|
-
const cyclesPresent = directedGraph.areCyclesPresent();
|
|
119
|
-
|
|
120
|
-
assert.isFalse(cyclesPresent);
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe("there is a cycle one vertex of which is subsequently removed", () => {
|
|
125
|
-
let directedGraph;
|
|
126
|
-
|
|
127
|
-
before(() => {
|
|
128
|
-
const vertexNamesArray = [
|
|
129
|
-
[ vertexNameA, vertexNameB ],
|
|
130
|
-
[ vertexNameB, vertexNameA ]
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
before(() => {
|
|
137
|
-
const vertexName = vertexNameA; ///
|
|
138
|
-
|
|
139
|
-
directedGraph.removeVertexByVertexName(vertexName);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("returns false", () => {
|
|
143
|
-
const cyclesPresent = directedGraph.areCyclesPresent();
|
|
144
|
-
|
|
145
|
-
assert.isFalse(cyclesPresent);
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
describe("getOrderedVertexNames", () => {
|
|
151
|
-
describe("no vertexes are present", () => {
|
|
152
|
-
let directedGraph;
|
|
153
|
-
|
|
154
|
-
before(() => {
|
|
155
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it("returns an empty array", () => {
|
|
159
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames();
|
|
160
|
-
|
|
161
|
-
assert.deepEqual(orderedVertexNames, []);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
describe("a single vertex is present", () => {
|
|
166
|
-
let directedGraph;
|
|
167
|
-
|
|
168
|
-
before(() => {
|
|
169
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
before(() => {
|
|
173
|
-
directedGraph.addVertexByVertexName(vertexNameA);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it("returns an array with the single vertex name", () => {
|
|
177
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames();
|
|
178
|
-
|
|
179
|
-
assert.deepEqual(orderedVertexNames, [ vertexNameA ]);
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
describe("a single edge is present", () => {
|
|
184
|
-
let directedGraph;
|
|
185
|
-
|
|
186
|
-
before(() => {
|
|
187
|
-
const vertexNamesArray = [
|
|
188
|
-
[ vertexNameA, vertexNameB ]
|
|
189
|
-
];
|
|
190
|
-
|
|
191
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("returns an array with the ordered vertex names", () => {
|
|
195
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames();
|
|
196
|
-
|
|
197
|
-
assert.deepEqual(orderedVertexNames, [ vertexNameA, vertexNameB ]);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
describe("two edges are present", () => {
|
|
202
|
-
let directedGraph;
|
|
203
|
-
|
|
204
|
-
before(() => {
|
|
205
|
-
const vertexNamesArray = [
|
|
206
|
-
[ vertexNameA, vertexNameB ],
|
|
207
|
-
[ vertexNameB, vertexNameC ]
|
|
208
|
-
];
|
|
209
|
-
|
|
210
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("returns an array with the ordered vertex names", () => {
|
|
214
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames();
|
|
215
|
-
|
|
216
|
-
assert.deepEqual(orderedVertexNames, [ vertexNameA, vertexNameB, vertexNameC ]);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
describe("addEdge", () => {
|
|
222
|
-
describe("the edge is not cyclic", () => {
|
|
223
|
-
let directedGraph;
|
|
224
|
-
|
|
225
|
-
before(() => {
|
|
226
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
it("leaves the source vertex index less than the target vertex index", () => {
|
|
230
|
-
const sourceVertexName = vertexNameA, ///
|
|
231
|
-
targetVertexName = vertexNameB, ///
|
|
232
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
233
|
-
|
|
234
|
-
directedGraph.addEdge(edge);
|
|
235
|
-
|
|
236
|
-
const sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName),
|
|
237
|
-
targetVertex = directedGraph.getVertexByVertexName(targetVertexName),
|
|
238
|
-
sourceVertexIndex = sourceVertex.getIndex(),
|
|
239
|
-
targetVertexIndex = targetVertex.getIndex();
|
|
240
|
-
|
|
241
|
-
assert.isTrue(sourceVertexIndex < targetVertexIndex);
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
describe("the edge is cyclic", () => {
|
|
246
|
-
let directedGraph;
|
|
247
|
-
|
|
248
|
-
before(() => {
|
|
249
|
-
const vertexNameArray = [
|
|
250
|
-
[ vertexNameB, vertexNameA ]
|
|
251
|
-
];
|
|
252
|
-
|
|
253
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNameArray);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it("leaves the source vertex index greater than the target vertex index", () => {
|
|
257
|
-
const sourceVertexName = vertexNameA, ///
|
|
258
|
-
targetVertexName = vertexNameB, ///
|
|
259
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
260
|
-
|
|
261
|
-
directedGraph.addEdge(edge);
|
|
262
|
-
|
|
263
|
-
const sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName),
|
|
264
|
-
targetVertex = directedGraph.getVertexByVertexName(targetVertexName),
|
|
265
|
-
sourceVertexIndex = sourceVertex.getIndex(),
|
|
266
|
-
targetVertexIndex = targetVertex.getIndex();
|
|
267
|
-
|
|
268
|
-
assert.isTrue(sourceVertexIndex > targetVertexIndex);
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe("removeEdge", () => {
|
|
274
|
-
describe("the edge is not cyclic", () => {
|
|
275
|
-
let edge,
|
|
276
|
-
directedGraph;
|
|
277
|
-
|
|
278
|
-
before(() => {
|
|
279
|
-
const vertexNamesArray = [
|
|
280
|
-
[ vertexNameA, vertexNameB ]
|
|
281
|
-
];
|
|
282
|
-
|
|
283
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray)
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
before(() => {
|
|
287
|
-
const sourceVertexName = vertexNameA, ///
|
|
288
|
-
targetVertexName = vertexNameB; ///
|
|
289
|
-
|
|
290
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
291
|
-
|
|
292
|
-
directedGraph.removeEdge(edge);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
it("removes the edge", () => {
|
|
296
|
-
const edgePresent = directedGraph.isEdgePresent(edge);
|
|
297
|
-
|
|
298
|
-
assert.isFalse(edgePresent);
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
describe("the edge is in a cycle and is the cyclic edge", () => {
|
|
303
|
-
let edge,
|
|
304
|
-
directedGraph;
|
|
305
|
-
|
|
306
|
-
before(() => {
|
|
307
|
-
const vertexNamesArray = [
|
|
308
|
-
[ vertexNameA, vertexNameB ],
|
|
309
|
-
[ vertexNameB, vertexNameA ],
|
|
310
|
-
];
|
|
311
|
-
|
|
312
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray)
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
before(() => {
|
|
316
|
-
const sourceVertexName = vertexNameB, ///
|
|
317
|
-
targetVertexName = vertexNameA; ///
|
|
318
|
-
|
|
319
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
320
|
-
|
|
321
|
-
directedGraph.removeEdge(edge);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
it("removes the edge and leaves the remaining edge's source vertex index less than its target vertex index", () => {
|
|
325
|
-
const edgePresent = directedGraph.isEdgePresent(edge);
|
|
326
|
-
|
|
327
|
-
assert.isFalse(edgePresent);
|
|
328
|
-
|
|
329
|
-
const sourceVertexName = vertexNameA, ///
|
|
330
|
-
targetVertexName = vertexNameB, ///
|
|
331
|
-
sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName),
|
|
332
|
-
targetVertex = directedGraph.getVertexByVertexName(targetVertexName),
|
|
333
|
-
sourceVertexIndex = sourceVertex.getIndex(),
|
|
334
|
-
targetVertexIndex = targetVertex.getIndex();
|
|
335
|
-
|
|
336
|
-
assert.isTrue(sourceVertexIndex < targetVertexIndex);
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
describe("the edge is in a cycle and is not the cyclic edge", () => {
|
|
341
|
-
let edge,
|
|
342
|
-
directedGraph;
|
|
343
|
-
|
|
344
|
-
before(() => {
|
|
345
|
-
const vertexNamesArray = [
|
|
346
|
-
[ vertexNameA, vertexNameB ],
|
|
347
|
-
[ vertexNameB, vertexNameA ],
|
|
348
|
-
];
|
|
349
|
-
|
|
350
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray)
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
before(() => {
|
|
354
|
-
const sourceVertexName = vertexNameA, ///
|
|
355
|
-
targetVertexName = vertexNameB; ///
|
|
356
|
-
|
|
357
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
358
|
-
|
|
359
|
-
directedGraph.removeEdge(edge);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it("removes the edge and set the remaining edge's source vertex index to be less than its target vertex index", () => {
|
|
363
|
-
const edgePresent = directedGraph.isEdgePresent(edge);
|
|
364
|
-
|
|
365
|
-
assert.isFalse(edgePresent);
|
|
366
|
-
|
|
367
|
-
const sourceVertexName = vertexNameB, ///
|
|
368
|
-
targetVertexName = vertexNameA, ///
|
|
369
|
-
sourceVertex = directedGraph.getVertexByVertexName(sourceVertexName),
|
|
370
|
-
targetVertex = directedGraph.getVertexByVertexName(targetVertexName),
|
|
371
|
-
sourceVertexIndex = sourceVertex.getIndex(),
|
|
372
|
-
targetVertexIndex = targetVertex.getIndex();
|
|
373
|
-
|
|
374
|
-
assert.isTrue(sourceVertexIndex < targetVertexIndex);
|
|
375
|
-
});
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
describe("removeVertexByVertexName", () => {
|
|
380
|
-
describe("the vertex has one immediate predecessor", () => {
|
|
381
|
-
let directedGraph;
|
|
382
|
-
|
|
383
|
-
before(() => {
|
|
384
|
-
const vertexNamesArray = [
|
|
385
|
-
[ vertexNameA, vertexNameB ]
|
|
386
|
-
];
|
|
387
|
-
|
|
388
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
it("removes itself from the immediate predecessor vertex's immediate successor vertexes", () => {
|
|
392
|
-
const vertexName = vertexNameB; ///
|
|
393
|
-
|
|
394
|
-
directedGraph.removeVertexByVertexName(vertexName);
|
|
395
|
-
|
|
396
|
-
const immediatePredecessorVertexName = vertexNameA, ///
|
|
397
|
-
immediatePredecessorVertex = directedGraph.getVertexByVertexName(immediatePredecessorVertexName),
|
|
398
|
-
immediateSuccessorVertexes = immediatePredecessorVertex.getImmediateSuccessorVertexes();
|
|
399
|
-
|
|
400
|
-
assert.isEmpty(immediateSuccessorVertexes);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
describe("the vertex has one immediate successor", () => {
|
|
405
|
-
let directedGraph;
|
|
406
|
-
|
|
407
|
-
before(() => {
|
|
408
|
-
const vertexNamesArray = [
|
|
409
|
-
[ vertexNameA, vertexNameB ]
|
|
410
|
-
];
|
|
411
|
-
|
|
412
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
it("removes itself from the immediate successor vertex's immediate predecessor vertexes and decrements its index", () => {
|
|
416
|
-
const vertexName = vertexNameA; ///
|
|
417
|
-
|
|
418
|
-
directedGraph.removeVertexByVertexName(vertexName);
|
|
419
|
-
|
|
420
|
-
const immediateSuccessorVertexName = vertexNameB, ///
|
|
421
|
-
immediateSuccessorVertex = directedGraph.getVertexByVertexName(immediateSuccessorVertexName),
|
|
422
|
-
immediatePredecessorVertexes = immediateSuccessorVertex.getImmediatePredecessorVertexes();
|
|
423
|
-
|
|
424
|
-
assert.isEmpty(immediatePredecessorVertexes);
|
|
425
|
-
|
|
426
|
-
const immediateSuccessorVertexIndex = immediateSuccessorVertex.getIndex();
|
|
427
|
-
|
|
428
|
-
assert.equal(immediateSuccessorVertexIndex, 0);
|
|
429
|
-
});
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
describe("the vertex is part of a cycle of length two", () => {
|
|
433
|
-
let directedGraph;
|
|
434
|
-
|
|
435
|
-
before(() => {
|
|
436
|
-
const vertexNamesArray = [
|
|
437
|
-
[ vertexNameA, vertexNameB ],
|
|
438
|
-
[ vertexNameB, vertexNameA ]
|
|
439
|
-
];
|
|
440
|
-
|
|
441
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it("removes itself andd the cyclic edge", () => {
|
|
445
|
-
const vertexName = vertexNameA; ///
|
|
446
|
-
|
|
447
|
-
directedGraph.removeVertexByVertexName(vertexName);
|
|
448
|
-
|
|
449
|
-
const vertex = directedGraph.getVertexByVertexName(vertexName);
|
|
450
|
-
|
|
451
|
-
assert.isNull(vertex);
|
|
452
|
-
|
|
453
|
-
const cyclicEdges = directedGraph.getCyclicEdges();
|
|
454
|
-
|
|
455
|
-
assert.isEmpty(cyclicEdges);
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
describe("reorderVertexesBySourceVertexAndTargetVertex", () => {
|
|
461
|
-
describe("it will create a cycle", () => {
|
|
462
|
-
let directedGraph;
|
|
463
|
-
|
|
464
|
-
before(() => {
|
|
465
|
-
const vertexNamesArray = [
|
|
466
|
-
[ vertexNameA, vertexNameB ]
|
|
467
|
-
];
|
|
468
|
-
|
|
469
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it("leaves the vertex indexes as-is", () => {
|
|
473
|
-
const sourceVertexName = vertexNameB, ///
|
|
474
|
-
targetVertexName = vertexNameA, ///
|
|
475
|
-
sourceVertex = directedGraph.addVertexByVertexName(sourceVertexName),
|
|
476
|
-
targetVertex = directedGraph.addVertexByVertexName(targetVertexName);
|
|
477
|
-
|
|
478
|
-
directedGraph.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
|
|
479
|
-
|
|
480
|
-
const sourceVertexIndex = sourceVertex.getIndex(),
|
|
481
|
-
targetVertexIndex = targetVertex.getIndex();
|
|
482
|
-
|
|
483
|
-
assert.isTrue(sourceVertexIndex > targetVertexIndex);
|
|
484
|
-
});
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
describe("it will not create a cycle", () => {
|
|
488
|
-
describe("the source vertex is before the target vertex", () => {
|
|
489
|
-
let directedGraph;
|
|
490
|
-
|
|
491
|
-
before(() => {
|
|
492
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
it("leaves the vertex indexes as-is", () => {
|
|
496
|
-
const sourceVertexName = vertexNameA, ///
|
|
497
|
-
targetVertexName = vertexNameB, ///
|
|
498
|
-
sourceVertex = directedGraph.addVertexByVertexName(sourceVertexName),
|
|
499
|
-
targetVertex = directedGraph.addVertexByVertexName(targetVertexName);
|
|
500
|
-
|
|
501
|
-
directedGraph.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
|
|
502
|
-
|
|
503
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames(),
|
|
504
|
-
firstOrderedVertexName = first(orderedVertexNames),
|
|
505
|
-
secondOrderedVertexName = second(orderedVertexNames);
|
|
506
|
-
|
|
507
|
-
assert.equal(firstOrderedVertexName, vertexNameA);
|
|
508
|
-
assert.equal(secondOrderedVertexName, vertexNameB);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
describe("the source vertex is after the target vertex", () => {
|
|
513
|
-
describe("there are no other vertexes", () => {
|
|
514
|
-
let directedGraph;
|
|
515
|
-
|
|
516
|
-
before(() => {
|
|
517
|
-
directedGraph = DirectedGraph.fromNothing();
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
it("swaps the vertex indexes", () => {
|
|
521
|
-
const targetVertexName = vertexNameB, ///
|
|
522
|
-
sourceVertexName = vertexNameA, ///
|
|
523
|
-
targetVertex = directedGraph.addVertexByVertexName(targetVertexName),
|
|
524
|
-
sourceVertex = directedGraph.addVertexByVertexName(sourceVertexName);
|
|
525
|
-
|
|
526
|
-
directedGraph.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
|
|
527
|
-
|
|
528
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames(),
|
|
529
|
-
firstOrderedVertexName = first(orderedVertexNames),
|
|
530
|
-
secondOrderedVertexName = second(orderedVertexNames);
|
|
531
|
-
|
|
532
|
-
assert.equal(firstOrderedVertexName, vertexNameA);
|
|
533
|
-
assert.equal(secondOrderedVertexName, vertexNameB);
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
describe("there are other vertexes", () => {
|
|
538
|
-
let directedGraph;
|
|
539
|
-
|
|
540
|
-
before(() => {
|
|
541
|
-
const vertexNamesArray = [
|
|
542
|
-
[ vertexNameA, vertexNameB ],
|
|
543
|
-
[ vertexNameC, vertexNameD ]
|
|
544
|
-
];
|
|
545
|
-
|
|
546
|
-
directedGraph = directedGraphFromVertexNamesArray(vertexNamesArray);
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
it("rearranges the vertexes and returns true", () => {
|
|
550
|
-
const sourceVertexName = vertexNameD, ///
|
|
551
|
-
targetVertexName = vertexNameA, ///
|
|
552
|
-
sourceVertex = directedGraph.addVertexByVertexName(sourceVertexName),
|
|
553
|
-
targetVertex = directedGraph.addVertexByVertexName(targetVertexName);
|
|
554
|
-
|
|
555
|
-
directedGraph.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
|
|
556
|
-
|
|
557
|
-
const orderedVertexNames = directedGraph.getOrderedVertexNames(),
|
|
558
|
-
firstOrderedVertexName = first(orderedVertexNames),
|
|
559
|
-
secondOrderedVertexName = second(orderedVertexNames),
|
|
560
|
-
thirdOrderedVertexName = third(orderedVertexNames),
|
|
561
|
-
fourthOrderedVertexName = fourth(orderedVertexNames);
|
|
562
|
-
|
|
563
|
-
assert.equal(firstOrderedVertexName, vertexNameC);
|
|
564
|
-
assert.equal(secondOrderedVertexName, vertexNameD);
|
|
565
|
-
assert.equal(thirdOrderedVertexName, vertexNameA);
|
|
566
|
-
assert.equal(fourthOrderedVertexName, vertexNameB);
|
|
567
|
-
});
|
|
568
|
-
});
|
|
569
|
-
});
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
function directedGraphFromVertexNamesArray(vertexNamesArray) {
|
|
575
|
-
const directedGraph = DirectedGraph.fromNothing(),
|
|
576
|
-
edges = vertexNamesArray.map((vertexNames) => {
|
|
577
|
-
const firstVertexName = first(vertexNames),
|
|
578
|
-
secondVertexName = second(vertexNames),
|
|
579
|
-
sourceVertexName = firstVertexName, ///
|
|
580
|
-
targetVertexName = secondVertexName, ///
|
|
581
|
-
edge = Edge.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
|
|
582
|
-
|
|
583
|
-
return edge;
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
directedGraph.addEdges(edges);
|
|
587
|
-
|
|
588
|
-
return directedGraph;
|
|
589
|
-
}
|