Files
iD/test/spec/graph/history.js
T
Brandon Liu ded802049a add history.numChanges method.
Use hasChanges/numChanges to toggle Save button and show confirmation dialog when navigating away from page.
2013-01-19 23:16:48 -08:00

174 lines
6.0 KiB
JavaScript

describe("iD.History", function () {
var history, spy,
action = function() { return iD.Graph(); };
beforeEach(function () {
history = iD.History();
spy = sinon.spy();
});
describe("#graph", function () {
it("returns the current graph", function () {
expect(history.graph()).to.be.an.instanceOf(iD.Graph);
});
});
describe("#perform", function () {
it("updates the graph", function () {
var graph = iD.Graph();
history.perform(d3.functor(graph));
expect(history.graph()).to.equal(graph);
});
it("pushes an undo annotation", function () {
history.perform(action, "annotation");
expect(history.undoAnnotation()).to.equal("annotation");
});
it("emits a change event", function () {
history.on('change', spy);
history.perform(action);
expect(spy).to.have.been.calledWith([]);
});
it("performs multiple actions", function () {
var action1 = sinon.stub().returns(iD.Graph()),
action2 = sinon.stub().returns(iD.Graph());
history.perform(action1, action2, "annotation");
expect(action1).to.have.been.called;
expect(action2).to.have.been.called;
expect(history.undoAnnotation()).to.equal("annotation");
});
});
describe("#replace", function () {
it("updates the graph", function () {
var graph = iD.Graph();
history.replace(d3.functor(graph));
expect(history.graph()).to.equal(graph);
});
it("replaces the undo annotation", function () {
history.perform(action, "annotation1");
history.replace(action, "annotation2");
expect(history.undoAnnotation()).to.equal("annotation2");
});
it("emits a change event", function () {
history.on('change', spy);
history.replace(action);
expect(spy).to.have.been.calledWith([]);
});
it("performs multiple actions", function () {
var action1 = sinon.stub().returns(iD.Graph()),
action2 = sinon.stub().returns(iD.Graph());
history.replace(action1, action2, "annotation");
expect(action1).to.have.been.called;
expect(action2).to.have.been.called;
expect(history.undoAnnotation()).to.equal("annotation");
});
});
describe("#undo", function () {
it("pops the undo stack", function () {
history.perform(action, "annotation");
history.undo();
expect(history.undoAnnotation()).to.be.undefined;
});
it("pushes the redo stack", function () {
history.perform(action, "annotation");
history.undo();
expect(history.redoAnnotation()).to.equal("annotation");
});
it("emits a change event", function () {
history.perform(action);
history.on('change', spy);
history.undo();
expect(spy).to.have.been.calledWith([]);
});
});
describe("#redo", function () {
it("emits a change event", function () {
history.perform(action);
history.undo();
history.on('change', spy);
history.redo();
expect(spy).to.have.been.calledWith([]);
});
});
describe("#changes", function () {
it("includes created entities", function () {
var node = iD.Node();
history.perform(function (graph) { return graph.replace(node); });
expect(history.changes().created).to.eql([node]);
});
it("includes modified entities", function () {
var node1 = iD.Node({id: "n1"}),
node2 = node1.update({}),
graph = iD.Graph([node1]);
history.merge(graph);
history.perform(function (graph) { return graph.replace(node2); });
expect(history.changes().modified).to.eql([node2]);
});
it("includes deleted entities", function () {
var node = iD.Node({id: "n1"}),
graph = iD.Graph([node]);
history.merge(graph);
history.perform(function (graph) { return graph.remove(node); });
expect(history.changes().deleted).to.eql([node]);
});
});
describe("#hasChanges", function() {
it("is true when any of change's values are nonempty", function() {
var node = iD.Node();
history.perform(function (graph) { return graph.replace(node); });
expect(history.hasChanges()).to.eql(true);
});
it("is false when all of change's values are empty", function() {
expect(history.hasChanges()).to.eql(false);
});
});
describe("#numChanges", function() {
it("is 0 when there are no changes", function() {
expect(history.numChanges()).to.eql(0);
});
it("is the sum of all types of changes", function() {
var node1 = iD.Node({id: "n1"}),
node2 = iD.Node();
history.merge(iD.Graph([node1]));
history.perform(function (graph) { return graph.remove(node1); });
expect(history.numChanges()).to.eql(1);
history.perform(function (graph) { return graph.replace(node2); });
expect(history.numChanges()).to.eql(2);
});
});
describe("#reset", function () {
it("clears the version stack", function () {
history.perform(action, "annotation");
history.perform(action, "annotation");
history.undo();
history.reset();
expect(history.undoAnnotation()).to.be.undefined;
expect(history.redoAnnotation()).to.be.undefined;
});
it("emits a change event", function () {
history.on('change', spy);
history.reset();
expect(spy).to.have.been.called;
});
});
});