Skip to content

Commit

Permalink
Add recording to traversal and add visitedVertices() w docs and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
devinivy committed Nov 6, 2015
1 parent 349f606 commit 88b596a
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 7 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ An array of visited vertex ids in the order that they were visited. Should be c
#### `traversal.distance`
The sum of the edge weights of the edges traversed using [`traversal.walk()`](#traversalwalkv). Should be considered read-only.

#### `traversal.recording`
A boolean indicating if recording is currently active, per [`traversal.record()`](#traversalrecord) and [`traversal.stop()`](#traversalstop). Should be considered read-only.

#### `traversal.hop(v)`
Visits vertex with id `v` without traversing any edges. A new traversal might begin by calling `traversal.hop()` to visit the first vertex. Returns `traversal`.

Expand All @@ -228,5 +231,11 @@ Returns the number of times the traversal has visited the vertex with id `v`,
#### `traversal.subgraph()`
Returns a `Graph` representing the subgraph of visited nodes and traversed edges.

#### `traversal.record()`
Start recording traversal.

#### `traversal.stop()`
Stop recording traversal.

#### `traversal.play([graph])`
Returns a new `Traversal` of the in-progress traversal played over `graph`. It calls [`traversal.hop()`](#traversalhopv) and [`traversal.walk()`](#traversalwalkv) in the order they were called on `traversal`. If `graph` isn't specified, the traversal will be replayed over [`traversal.graph`](#traversalgraph).
Returns a new `Traversal` of the recorded traversal steps played over `graph`. It calls [`traversal.hop()`](#traversalhopv) and [`traversal.walk()`](#traversalwalkv) in the order they were called on `traversal` while recording was active. If `graph` isn't specified, the traversal steps will be replayed over [`traversal.graph`](#traversalgraph).
30 changes: 28 additions & 2 deletions lib/traversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exports = module.exports = internals.Traversal = function (graph) {
this.graph = graph;
this.sequence = [];
this.distance = 0;
this.recording = false;

this._records = [];
this._currentVertex = null;
Expand All @@ -19,9 +20,12 @@ internals.Traversal.prototype.hop = function (v) {

Hoek.assert(this.graph.vertexExists(v), 'Vertex [', v, '] does not exist.');

this._records.push({ act: 'hop', args: [v] });
this._visit(v);

if (this.recording) {
this._records.push({ act: 'hop', args: [v] });
}

return this;
};

Expand All @@ -33,10 +37,13 @@ internals.Traversal.prototype.walk = function (v) {
Hoek.assert(edge, 'Edge [', this._currentVertex, ']-->[', v, '] does not exist.');

this.distance += edge.weight;
this._records.push({ act: 'walk', args: [v] });
this._rememberEdge(this._currentVertex, v);
this._visit(v);

if (this.recording) {
this._records.push({ act: 'walk', args: [v] });
}

return this;
};

Expand All @@ -56,6 +63,11 @@ internals.Traversal.prototype.visits = function (v) {
return (this._visited[v] || 0);
};

internals.Traversal.prototype.visitedVertices = function () {

return Object.keys(this._visited);
};

internals.Traversal.prototype.subgraph = function () {

var subset = {
Expand All @@ -66,6 +78,20 @@ internals.Traversal.prototype.subgraph = function () {
return this.graph.subgraph(subset);
};

internals.Traversal.prototype.record = function () {

this.recording = true;

return this;
};

internals.Traversal.prototype.stop = function () {

this.recording = false;

return this;
};

internals.Traversal.prototype.play = function (graph) {

graph = graph || this.graph;
Expand Down
66 changes: 62 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2985,6 +2985,7 @@ describe('Gert', function () {
expect(traversal.currentVertex()).to.equal(null);
expect(traversal.sequence).to.deep.equal([]);
expect(traversal.distance).to.equal(0);
expect(traversal.recording).to.equal(false);

done();
});
Expand Down Expand Up @@ -3106,6 +3107,31 @@ describe('Gert', function () {
done();
});

it('vistedVertices() returns an array of visited vertex ids.', function (done) {

var graph = new Graph({
vertices: {
a: ['b', 'c'],
b: ['c'],
c: ['a'],
d: []
}
});

var traversal = new Traversal(graph);

traversal.hop('a')
.walk('b').hop('a')
.walk('c').walk('a')
.walk('b').hop('a')
.hop('c').walk('a')
.walk('c');

expect(traversal.visitedVertices()).to.only.include(['a', 'b', 'c']);

done();
});

it('subgraph() returns a directed subgraph of visited vertices and walked edges.', function (done) {

var graph = new Graph({
Expand Down Expand Up @@ -3188,10 +3214,12 @@ describe('Gert', function () {

var traversal = new Traversal(graph);

traversal.hop('a').walk('b')
traversal.record()
.hop('a').walk('b')
.walk('c').walk('b')
.walk('c').walk('b')
.hop('e');
.hop('e')
.stop();

var replayed = traversal.play();

Expand Down Expand Up @@ -3231,10 +3259,12 @@ describe('Gert', function () {

var traversal = new Traversal(graphOne);

traversal.hop('a').walk('b')
traversal.record()
.hop('a').walk('b')
.walk('c').walk('b')
.walk('c').walk('b')
.hop('e');
.hop('e')
.stop();

var replayed = traversal.play(graphTwo);

Expand All @@ -3248,6 +3278,34 @@ describe('Gert', function () {
done();
});

it('record() and stop() manage recording state.', function (done) {

var graph = new Graph({
vertices: ['a', 'b', 'c', 'd', 'e'],
edges: [
['d', 'a']
]
});

var traversal = new Traversal(graph);
expect(traversal.recording).to.equal(false);

traversal.record();
expect(traversal.recording).to.equal(true);

traversal.hop('b').hop('e').hop('d').walk('a');
traversal.stop();
expect(traversal.recording).to.equal(false);

traversal.hop('d').hop('a').hop('d').walk('a');
expect(traversal.sequence).to.deep.equal(['b', 'e', 'd', 'a', 'd', 'a', 'd', 'a']);

var replayed = traversal.play();
expect(replayed.sequence).to.deep.equal(['b', 'e', 'd', 'a']);

done();
});

});

});

0 comments on commit 88b596a

Please sign in to comment.