Mailspring/app/spec/stores/undo-redo-store-spec.es6

136 lines
4.5 KiB
JavaScript

import {Actions, Task, UndoRedoStore} from 'nylas-exports'
class Undoable extends Task {
constructor() {
super();
this.canBeUndone = true;
}
}
class PermanentTask extends Task {
constructor() {
super();
this.canBeUndone = false;
}
}
describe("UndoRedoStore", function undoRedoStoreSpec() {
beforeEach(() => {
UndoRedoStore._undo = []
UndoRedoStore._redo = []
spyOn(UndoRedoStore, "trigger")
spyOn(Actions, "queueTask").andCallFake((...args) => {
UndoRedoStore._onQueue(...args)
});
spyOn(Actions, "queueTasks").andCallFake((...args) => {
UndoRedoStore._onQueue(...args)
});
this.ids = (arrarr) => arrarr.map((arr) => arr.map((itm) => itm.id))
this.t1 = new Undoable();
this.t2 = new Undoable();
this.t3 = new Undoable();
this.t4 = new Undoable();
this.p1 = new PermanentTask();
this.t1.id = "t1"
this.t2.id = "t2"
this.t3.id = "t3"
this.t4.id = "t4"
this.p1.id = "p1"
});
it("pushes single tasks onto undo/redo", () => {
Actions.queueTask(this.t1)
expect(UndoRedoStore._redo).toEqual([])
expect(UndoRedoStore._undo).toEqual([[this.t1]])
expect(UndoRedoStore.trigger).toHaveBeenCalled()
});
it("pushes multiple tasks onto redo", () => {
Actions.queueTasks([this.t1, this.t2])
expect(UndoRedoStore._redo).toEqual([])
expect(UndoRedoStore._undo).toEqual([[this.t1, this.t2]])
expect(UndoRedoStore.trigger).toHaveBeenCalled()
});
it("only undoes task if they're all 'undoable'", () => {
Actions.queueTask([this.t1, this.p1])
expect(UndoRedoStore._redo).toEqual([])
expect(UndoRedoStore._undo).toEqual([])
expect(UndoRedoStore.trigger).not.toHaveBeenCalled()
});
it("refreshes redo if we get a new task", () => {
UndoRedoStore._redo = [[this.t1, this.t2], [this.t3]]
Actions.queueTask(this.t3)
expect(UndoRedoStore._redo).toEqual([])
});
it("doesn't refresh redo if our task is itself a redo task", () => {
UndoRedoStore._redo = [[this.t1, this.t2], [this.t3]]
const tr = new Undoable()
tr.source = 'redo'
Actions.queueTask(tr)
expect(UndoRedoStore._redo).toEqual([[this.t1, this.t2], [this.t3]])
expect(UndoRedoStore._undo).toEqual([[tr]])
});
it("runs undoTask on each group of undo tasks", () => {
UndoRedoStore._undo = [[this.t3], [this.t1, this.t2]]
UndoRedoStore.undo()
expect(Actions.queueTask.calls.length).toBe(2)
expect(Actions.queueTask.calls[0].args[0]).toBe("t1")
expect(Actions.queueTask.calls[1].args[0]).toBe("t2")
expect(UndoRedoStore._undo).toEqual([[this.t3]])
});
it("creates identical redo tasks and pushes on the stack", () => {
UndoRedoStore._undo = [[this.t3], [this.t1, this.t2]]
UndoRedoStore.undo()
expect(UndoRedoStore._undo).toEqual([[this.t3]])
expect(UndoRedoStore._redo[0][0].id).toBe("t1")
expect(UndoRedoStore._redo[0][1].id).toBe("t2")
expect(UndoRedoStore._redo.length).toBe(1)
});
it("redoes the latest task", () => {
UndoRedoStore._undo = [[this.t3], [this.t1, this.t2]]
UndoRedoStore.undo()
UndoRedoStore.redo()
expect(Actions.queueTasks.calls[0].args[0][0].id).toBe('t1')
expect(Actions.queueTasks.calls[0].args[0][1].id).toBe('t2')
expect(UndoRedoStore._undo[0]).toEqual([this.t3])
expect(UndoRedoStore._undo[1][0].id).toBe('t1')
expect(UndoRedoStore._undo[1][1].id).toBe('t2')
});
it("marks the incoming task as a redo task", () => {
UndoRedoStore._undo = [[this.t3], [this.t1, this.t2]]
UndoRedoStore.undo()
UndoRedoStore.redo()
expect(Actions.queueTasks.calls[0].args[0][0].source).toEqual('redo')
expect(Actions.queueTasks.calls[0].args[0][1].source).toEqual('redo')
});
it("correctly follows the undo redo sequence of events", () => {
Actions.queueTask(this.t1)
Actions.queueTask(this.t2)
Actions.queueTasks([this.t3, this.t4])
expect(UndoRedoStore._undo).toEqual([[this.t1], [this.t2], [this.t3, this.t4]])
UndoRedoStore.undo()
UndoRedoStore.undo()
UndoRedoStore.undo()
UndoRedoStore.undo()
UndoRedoStore.undo()
expect(UndoRedoStore._undo).toEqual([])
expect(this.ids(UndoRedoStore._redo)).toEqual([["t3", "t4"], ["t2"], ["t1"]])
UndoRedoStore.redo()
UndoRedoStore.redo()
UndoRedoStore.redo()
UndoRedoStore.redo()
UndoRedoStore.redo()
UndoRedoStore.redo()
expect(this.ids(UndoRedoStore._undo)).toEqual([["t1"], ["t2"], ["t3", "t4"]])
expect(this.ids(UndoRedoStore._redo)).toEqual([])
});
});