mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-11 04:48:44 +03:00
69300e0766
We no longer need to restore selection ranges before and after transactions now because selections are based on markers so they go along for the ride for free. This allows us to delegate directly to Buffer.transact from EditSession.
164 lines
5.0 KiB
CoffeeScript
164 lines
5.0 KiB
CoffeeScript
UndoManager = require 'undo-manager'
|
|
Buffer = require 'text-buffer'
|
|
Range = require 'range'
|
|
|
|
describe "UndoManager", ->
|
|
[buffer, undoManager] = []
|
|
|
|
beforeEach ->
|
|
buffer = new Buffer(require.resolve('fixtures/sample.js'))
|
|
undoManager = buffer.undoManager
|
|
|
|
afterEach ->
|
|
buffer.destroy()
|
|
|
|
describe ".undo()", ->
|
|
it "undoes the last change", ->
|
|
buffer.change(new Range([0, 5], [0, 9]), '')
|
|
buffer.insert([0, 6], 'h')
|
|
buffer.insert([0, 10], 'y')
|
|
expect(buffer.lineForRow(0)).toContain 'qshorty'
|
|
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toContain 'qshort'
|
|
expect(buffer.lineForRow(0)).not.toContain 'qshorty'
|
|
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toContain 'qsort'
|
|
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toContain 'quicksort'
|
|
|
|
it "does not throw an exception when there is nothing to undo", ->
|
|
undoManager.undo()
|
|
|
|
describe ".redo()", ->
|
|
beforeEach ->
|
|
buffer.change(new Range([0, 5], [0, 9]), '')
|
|
buffer.insert([0, 6], 'h')
|
|
buffer.insert([0, 10], 'y')
|
|
undoManager.undo()
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toContain 'qsort'
|
|
|
|
it "redoes the last undone change", ->
|
|
undoManager.redo()
|
|
expect(buffer.lineForRow(0)).toContain 'qshort'
|
|
|
|
undoManager.redo()
|
|
expect(buffer.lineForRow(0)).toContain 'qshorty'
|
|
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toContain 'qshort'
|
|
|
|
it "does not throw an exception when there is nothing to redo", ->
|
|
undoManager.redo()
|
|
undoManager.redo()
|
|
undoManager.redo()
|
|
|
|
it "discards the redo history when there is a new change following an undo", ->
|
|
buffer.insert([0, 6], 'p')
|
|
expect(buffer.getText()).toContain 'qsport'
|
|
|
|
undoManager.redo()
|
|
expect(buffer.getText()).toContain 'qsport'
|
|
|
|
describe "transaction methods", ->
|
|
describe "transact()", ->
|
|
beforeEach ->
|
|
buffer.setText('')
|
|
|
|
it "starts a transaction that can be committed later", ->
|
|
buffer.append('1')
|
|
undoManager.transact()
|
|
buffer.append('2')
|
|
buffer.append('3')
|
|
undoManager.commit()
|
|
buffer.append('4')
|
|
|
|
expect(buffer.getText()).toBe '1234'
|
|
undoManager.undo()
|
|
expect(buffer.getText()).toBe '123'
|
|
undoManager.undo()
|
|
expect(buffer.getText()).toBe '1'
|
|
undoManager.redo()
|
|
expect(buffer.getText()).toBe '123'
|
|
|
|
it "starts a transaction that can be aborted later", ->
|
|
buffer.append('1')
|
|
buffer.append('2')
|
|
|
|
undoManager.transact()
|
|
|
|
buffer.append('3')
|
|
buffer.append('4')
|
|
expect(buffer.getText()).toBe '1234'
|
|
|
|
undoManager.abort()
|
|
expect(buffer.getText()).toBe '12'
|
|
|
|
undoManager.undo()
|
|
expect(buffer.getText()).toBe '1'
|
|
|
|
undoManager.redo()
|
|
expect(buffer.getText()).toBe '12'
|
|
|
|
undoManager.redo()
|
|
expect(buffer.getText()).toBe '12'
|
|
|
|
describe "commit", ->
|
|
it "throws an exception if there is no current transaction", ->
|
|
expect(-> buffer.commit()).toThrow()
|
|
|
|
it "does not record empty transactions", ->
|
|
buffer.insert([0,0], "foo")
|
|
undoManager.transact()
|
|
undoManager.commit()
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).not.toContain("foo")
|
|
|
|
describe "abort", ->
|
|
it "does not affect the undo stack when the current transaction is empty", ->
|
|
buffer.setText('')
|
|
buffer.append('1')
|
|
buffer.transact()
|
|
buffer.abort()
|
|
expect(buffer.getText()).toBe '1'
|
|
buffer.undo()
|
|
expect(buffer.getText()).toBe ''
|
|
|
|
it "throws an exception if there is no current transaction", ->
|
|
expect(-> buffer.abort()).toThrow()
|
|
|
|
describe "exception handling", ->
|
|
describe "when a `do` operation throws an exception", ->
|
|
it "clears the stack", ->
|
|
spyOn(console, 'error')
|
|
buffer.setText("word")
|
|
buffer.insert([0,0], "1")
|
|
expect(->
|
|
undoManager.pushOperation(do: -> throw new Error("I'm a bad do operation"))
|
|
).toThrow("I'm a bad do operation")
|
|
|
|
undoManager.undo()
|
|
expect(buffer.lineForRow(0)).toBe "1word"
|
|
|
|
describe "when an `undo` operation throws an exception", ->
|
|
it "clears the stack", ->
|
|
spyOn(console, 'error')
|
|
buffer.setText("word")
|
|
buffer.insert([0,0], "1")
|
|
undoManager.pushOperation(undo: -> throw new Error("I'm a bad undo operation"))
|
|
expect(-> undoManager.undo()).toThrow("I'm a bad undo operation")
|
|
expect(buffer.lineForRow(0)).toBe "1word"
|
|
|
|
describe "when an `redo` operation throws an exception", ->
|
|
it "clears the stack", ->
|
|
spyOn(console, 'error')
|
|
buffer.setText("word")
|
|
buffer.insert([0,0], "1")
|
|
undoManager.pushOperation(redo: -> throw new Error("I'm a bad redo operation"))
|
|
undoManager.undo()
|
|
expect(-> undoManager.redo()).toThrow("I'm a bad redo operation")
|
|
expect(buffer.lineForRow(0)).toBe "1word"
|