Skip to content

Commit

Permalink
Add JSON writer / parser
Browse files Browse the repository at this point in the history
  • Loading branch information
cpettitt committed Sep 24, 2014
1 parent 7824897 commit 2cb6f49
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 0 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
var _ = require("lodash");

module.exports = _.clone(require("./lib"));
module.exports.json = require("./lib/json");
module.exports.alg = require("./lib/alg");
66 changes: 66 additions & 0 deletions lib/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var _ = require("lodash"),
Graph = require("./Graph");

module.exports = {
write: write,
read: read
};

function write(g) {
var json = {
options: {
directed: g.isDirected(),
multigraph: g.isMultigraph(),
compound: g.isCompound()
},
nodes: writeNodes(g),
edges: writeEdges(g)
};
if (!_.isUndefined(g.getGraph())) {
json.value = _.clone(g.getGraph());
}
return json;
}

function writeNodes(g) {
return _.map(g.nodes(), function(v) {
var nodeValue = g.getNode(v),
parent = g.getParent(v),
node = { v: v };
if (!_.isUndefined(nodeValue)) {
node.value = nodeValue;
}
if (!_.isUndefined(parent)) {
node.parent = parent;
}
return node;
});
}

function writeEdges(g) {
return _.map(g.edges(), function(e) {
var edgeValue = g.getEdge(e),
edge = { v: e.v, w: e.w };
if (!_.isUndefined(e.name)) {
edge.name = e.name;
}
if (!_.isUndefined(edgeValue)) {
edge.value = edgeValue;
}
return edge;
});
}

function read(json) {
var g = new Graph(json.options).setGraph(json.value);
_.each(json.nodes, function(entry) {
g.setNode(entry.v, entry.value);
if (entry.parent) {
g.setParent(entry.v, entry.parent);
}
});
_.each(json.edges, function(entry) {
g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value);
});
return g;
}
64 changes: 64 additions & 0 deletions test/json-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
var expect = require("./chai").expect,
Graph = require("..").Graph,
read = require("..").json.read,
write = require("..").json.write;

describe("json", function() {
it("preserves the graph options", function() {
expect(rw(new Graph({ directed: true })).isDirected()).to.be.true;
expect(rw(new Graph({ directed: false })).isDirected()).to.be.false;
expect(rw(new Graph({ multigraph: true })).isMultigraph()).to.be.true;
expect(rw(new Graph({ multigraph: false })).isMultigraph()).to.be.false;
expect(rw(new Graph({ compound: true })).isCompound()).to.be.true;
expect(rw(new Graph({ compound: false })).isCompound()).to.be.false;
});

it("preserves the graph value, if any", function() {
expect(rw(new Graph().setGraph(1)).getGraph()).equals(1);
expect(rw(new Graph().setGraph({ foo: "bar" })).getGraph()).eqls({ foo: "bar" });
expect(rw(new Graph()).getGraph()).to.be.undefined;
});

it("preserves nodes", function() {
expect(rw(new Graph().setNode("a")).hasNode("a")).to.be.true;
expect(rw(new Graph().setNode("a")).getNode("a")).to.be.undefined;
expect(rw(new Graph().setNode("a", 1)).getNode("a")).equals(1);
expect(rw(new Graph().setNode("a", { foo: "bar" })).getNode("a"))
.eqls({ foo: "bar" });
});

it("preserves simple edges", function() {
expect(rw(new Graph().setEdge("a", "b")).hasEdge("a", "b")).to.be.true;
expect(rw(new Graph().setEdge("a", "b")).getEdge("a", "b")).to.be.undefined;
expect(rw(new Graph().setEdge("a", "b", 1)).getEdge("a", "b")).equals(1);
expect(rw(new Graph().setEdge("a", "b", { foo: "bar" })).getEdge("a", "b"))
.eqls({ foo: "bar" });
});

it("preserves multi-edges", function() {
var g = new Graph({ multigraph: true });

g.setEdge({ v: "a", w: "b", name: "foo" });
expect(rw(g).hasEdge("a", "b", "foo")).to.be.true;

g.setEdge({ v: "a", w: "b", name: "foo" });
expect(rw(g).getEdge("a", "b", "foo")).to.be.undefined;

g.setEdge({ v: "a", w: "b", name: "foo" }, 1);
expect(rw(g).getEdge("a", "b", "foo")).equals(1);

g.setEdge({ v: "a", w: "b", name: "foo" }, { foo: "bar" });
expect(rw(g).getEdge("a", "b", "foo")).eqls({ foo: "bar" });
});

it("preserves parent / child relationships", function() {
expect(rw(new Graph({ compound: true }).setNode("a")).getParent("a"))
.to.be.undefined;
expect(rw(new Graph({ compound: true }).setParent("a", "parent")).getParent("a"))
.to.equal("parent");
});
});

function rw(g) {
return read(write(g));
}

0 comments on commit 2cb6f49

Please sign in to comment.