pulsar/spec/extensions/command-interpreter-spec.coffee
2012-04-23 10:54:56 -06:00

255 lines
12 KiB
CoffeeScript

CommandInterpreter = require 'command-interpreter'
Buffer = require 'buffer'
Editor = require 'editor'
describe "CommandInterpreter", ->
[interpreter, editor, buffer] = []
beforeEach ->
buffer = new Buffer(require.resolve 'fixtures/sample.js')
editor = new Editor({buffer})
interpreter = new CommandInterpreter()
describe "addresses", ->
beforeEach ->
editor.addSelectionForBufferRange([[7,0], [7,11]])
editor.addSelectionForBufferRange([[8,0], [8,11]])
describe "a line address", ->
it "selects the specified line", ->
interpreter.eval(editor, '4')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [4, 0]]
describe "0", ->
it "selects the zero-length string at the start of the file", ->
interpreter.eval(editor, '0')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [0,0]]
interpreter.eval(editor, '0,1')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [1,0]]
describe "$", ->
it "selects EOF", ->
interpreter.eval(editor, '$')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[12,2], [12,2]]
interpreter.eval(editor, '1,$')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [12,2]]
describe ".", ->
describe "when a single selection", ->
it 'maintains the current selection', ->
editor.clearSelections()
editor.setSelectionBufferRange([[1,1], [2,2]])
interpreter.eval(editor, '.')
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [2,2]]
editor.setSelectionBufferRange([[1,1], [2,2]])
interpreter.eval(editor, '.,')
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [12,2]]
editor.setSelectionBufferRange([[1,1], [2,2]])
interpreter.eval(editor, ',.')
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [2,2]]
describe "with multiple selections", ->
it "maintains the current selections", ->
preSelections = editor.getSelections()
expect(preSelections.length).toBe 3
[preRange1, preRange2, preRange3] = preSelections.map (s) -> s.getScreenRange()
interpreter.eval(editor, '.')
selections = editor.getSelections()
expect(selections.length).toBe 3
[selection1, selection2, selection3] = selections
expect(selection1.getScreenRange()).toEqual preRange1
expect(selection2.getScreenRange()).toEqual preRange2
expect(selection3.getScreenRange()).toEqual preRange3
describe "/regex/", ->
beforeEach ->
editor.clearSelections()
it 'selects text matching regex after current selection', ->
editor.setSelectionBufferRange([[4,16], [4,20]])
interpreter.eval(editor, '/pivot/')
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
it 'does not require the trailing slash', ->
editor.setSelectionBufferRange([[4,16], [4,20]])
interpreter.eval(editor, '/pivot')
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
it "searches from the end of each selection in the buffer", ->
editor.clearSelections()
editor.setSelectionBufferRange([[4,16], [4,20]])
editor.addSelectionForBufferRange([[1,16], [2,20]])
expect(editor.getSelections().length).toBe 2
interpreter.eval(editor, '/pivot')
selections = editor.getSelections()
expect(selections.length).toBe 2
expect(selections[0].getBufferRange()).toEqual [[3,8], [3,13]]
expect(selections[1].getBufferRange()).toEqual [[6,16], [6,21]]
it "wraps around to the beginning of the buffer, but doesn't infinitely loop if no matches are found", ->
editor.setSelectionBufferRange([[10, 0], [10,3]])
interpreter.eval(editor, '/pivot')
expect(editor.getSelection().getBufferRange()).toEqual [[3,8], [3,13]]
interpreter.eval(editor, '/mike tyson')
expect(editor.getSelection().getBufferRange()).toEqual [[3,8], [3,13]]
describe "address range", ->
describe "when two addresses are specified", ->
it "selects from the begining of the left address to the end of the right address", ->
interpreter.eval(editor, '4,7')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [7, 0]]
describe "when the left address is unspecified", ->
it "selects from the begining of buffer to the end of the right address", ->
interpreter.eval(editor, ',7')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[0, 0], [7, 0]]
describe "when the right address is unspecified", ->
it "selects from the begining of left address to the end file", ->
interpreter.eval(editor, '4,')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [12, 2]]
describe "when the neither address is specified", ->
it "selects the entire file", ->
interpreter.eval(editor, ',')
expect(editor.getSelections().length).toBe 1
expect(editor.getSelection().getBufferRange()).toEqual [[0, 0], [12, 2]]
describe "x/regex/", ->
it "sets the current selection to every match of the regex in the current selection", ->
interpreter.eval(editor, '6,7 x/current/')
selections = editor.getSelections()
expect(selections.length).toBe 4
expect(selections[0].getBufferRange()).toEqual [[5,6], [5,13]]
expect(selections[1].getBufferRange()).toEqual [[6,6], [6,13]]
expect(selections[2].getBufferRange()).toEqual [[6,34], [6,41]]
expect(selections[3].getBufferRange()).toEqual [[6,56], [6,63]]
describe "when matching /$/", ->
it "matches the end of each line in the selected region", ->
interpreter.eval(editor, '6,8 x/$/')
cursors = editor.getCursors()
expect(cursors.length).toBe 3
expect(cursors[0].getBufferPosition()).toEqual [5, 30]
expect(cursors[1].getBufferPosition()).toEqual [6, 65]
expect(cursors[2].getBufferPosition()).toEqual [7, 5]
it "loops through current selections and selects text matching the regex", ->
editor.setSelectionBufferRange [[3,0], [3,62]]
editor.addSelectionForBufferRange [[6,0], [6,65]]
interpreter.eval(editor, 'x/current')
selections = editor.getSelections()
expect(selections.length).toBe 4
expect(selections[0].getBufferRange()).toEqual [[3,31], [3,38]]
expect(selections[1].getBufferRange()).toEqual [[6,6], [6,13]]
expect(selections[2].getBufferRange()).toEqual [[6,34], [6,41]]
expect(selections[3].getBufferRange()).toEqual [[6,56], [6,63]]
describe "substitution", ->
it "does nothing if there are no matches", ->
editor.setSelectionBufferRange([[6, 0], [6, 44]])
interpreter.eval(editor, 's/not-in-text/foo/')
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);'
describe "when not global", ->
describe "when there is a single selection", ->
it "performs a single substitution within the current selection", ->
editor.setSelectionBufferRange([[6, 0], [6, 44]])
interpreter.eval(editor, 's/current/foo/')
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(current) : right.push(current);'
describe "when there are multiple selections", ->
it "performs a single substitutions within each of the selections", ->
editor.setSelectionBufferRange([[5, 0], [5, 20]])
editor.addSelectionForBufferRange([[6, 0], [6, 44]])
interpreter.eval(editor, 's/current/foo/')
expect(buffer.lineForRow(5)).toBe ' foo = items.shift();'
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(current) : right.push(current);'
describe "when global", ->
it "performs a multiple substitutions within the current selection", ->
editor.setSelectionBufferRange([[6, 0], [6, 44]])
interpreter.eval(editor, 's/current/foo/g')
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(foo) : right.push(current);'
describe "when prefixed with an address", ->
it "only makes substitutions within given lines", ->
interpreter.eval(editor, '4,6s/ /!/g')
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return items;'
expect(buffer.lineForRow(3)).toBe '!!!!var!pivot!=!items.shift(),!current,!left!=![],!right!=![];'
expect(buffer.lineForRow(4)).toBe '!!!!while(items.length!>!0)!{'
expect(buffer.lineForRow(5)).toBe '!!!!!!current!=!items.shift();'
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);'
describe "when matching $", ->
it "matches the end of each line and avoids infinitely looping on a zero-width match", ->
interpreter.eval(editor, ',s/$/!!!/g')
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {!!!'
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return items;!!!'
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);!!!'
expect(buffer.lineForRow(12)).toBe '};!!!'
describe "when matching ^", ->
it "matches the beginning of each line and avoids infinitely looping on a zero-width match", ->
interpreter.eval(editor, ',s/^/!!!/g')
expect(buffer.lineForRow(0)).toBe '!!!var quicksort = function () {'
expect(buffer.lineForRow(2)).toBe '!!! if (items.length <= 1) return items;'
expect(buffer.lineForRow(6)).toBe '!!! current < pivot ? left.push(current) : right.push(current);'
expect(buffer.lineForRow(12)).toBe '!!!};'
describe "when there are multiple selections", ->
it "performs a multiple substitutions within each of the selections", ->
editor.setSelectionBufferRange([[5, 0], [5, 20]])
editor.addSelectionForBufferRange([[6, 0], [6, 44]])
interpreter.eval(editor, 's/current/foo/g')
expect(buffer.lineForRow(5)).toBe ' foo = items.shift();'
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(foo) : right.push(current);'
describe ".repeatRelativeAddress()", ->
it "repeats the last search command if there is one", ->
interpreter.repeatRelativeAddress(editor) # don't raise an exception
editor.setCursorScreenPosition([4, 0])
interpreter.eval(editor, '/current')
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
interpreter.repeatRelativeAddress(editor)
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
interpreter.eval(editor, 's/r/R/g')
interpreter.repeatRelativeAddress(editor)
expect(editor.getSelection().getBufferRange()).toEqual [[6,34], [6,41]]
interpreter.eval(editor, '0')
interpreter.eval(editor, '/sort/ s/r/R/') # this contains a substitution... won't be repeated
interpreter.repeatRelativeAddress(editor)
expect(editor.getSelection().getBufferRange()).toEqual [[3,31], [3,38]]