mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Buffer listens for changes to file and triggers 'contents-change' event
This commit is contained in:
@@ -10,7 +10,13 @@ describe 'Buffer', ->
|
||||
fileContents = fs.read(filePath)
|
||||
buffer = new Buffer(filePath)
|
||||
|
||||
afterEach ->
|
||||
buffer.destroy()
|
||||
|
||||
describe 'constructor', ->
|
||||
beforeEach ->
|
||||
buffer.destroy()
|
||||
|
||||
describe "when given a path", ->
|
||||
describe "when a file exists for the path", ->
|
||||
it "loads the contents of that file", ->
|
||||
@@ -19,12 +25,11 @@ describe 'Buffer', ->
|
||||
expect(buffer.getText()).toBe fs.read(filePath)
|
||||
|
||||
describe "when no file exists for the path", ->
|
||||
it "creates an empty buffer", ->
|
||||
it "throws an exception", ->
|
||||
filePath = "does-not-exist.txt"
|
||||
expect(fs.exists(filePath)).toBeFalsy()
|
||||
|
||||
buffer = new Buffer(filePath)
|
||||
expect(buffer.getText()).toBe ""
|
||||
expect(-> new Buffer(filePath)).toThrow()
|
||||
|
||||
describe "when no path is given", ->
|
||||
it "creates an empty buffer", ->
|
||||
@@ -32,22 +37,26 @@ describe 'Buffer', ->
|
||||
expect(buffer.getText()).toBe ""
|
||||
|
||||
describe "path-change event", ->
|
||||
afterEach ->
|
||||
fs.remove("/tmp/moo.text") if fs.exists("/tmp/moo.text")
|
||||
|
||||
it "emits path-change event when path is changed", ->
|
||||
eventHandler = jasmine.createSpy('eventHandler')
|
||||
buffer.on 'path-change', eventHandler
|
||||
buffer.setPath("moo.text")
|
||||
buffer.saveAs("/tmp/moo.text")
|
||||
expect(eventHandler).toHaveBeenCalledWith(buffer)
|
||||
|
||||
describe "when the buffer's file is modified (via another process)", ->
|
||||
path = null
|
||||
beforeEach ->
|
||||
path = fs.join(require.resolve('fixtures'), "tmp.txt")
|
||||
path = "/tmp/tmp.txt"
|
||||
fs.write(path, "first")
|
||||
buffer.destroy()
|
||||
|
||||
afterEach ->
|
||||
fs.remove(path)
|
||||
|
||||
describe "when the buffer is in an unmodified", ->
|
||||
describe "when the buffer is unmodified", ->
|
||||
it "triggers 'change' event", ->
|
||||
buffer = new Buffer(path)
|
||||
changeHandler = jasmine.createSpy('changeHandler')
|
||||
@@ -66,6 +75,9 @@ describe 'Buffer', ->
|
||||
expect(event.newText).toBe "second"
|
||||
|
||||
describe ".isModified()", ->
|
||||
beforeEach ->
|
||||
buffer.destroy()
|
||||
|
||||
it "returns true when user changes buffer", ->
|
||||
expect(buffer.isModified()).toBeFalsy()
|
||||
buffer.insert([0,0], "hi")
|
||||
@@ -210,12 +222,15 @@ describe 'Buffer', ->
|
||||
expect(event.newRange).toEqual [[0, 0], [1, 14]]
|
||||
|
||||
describe ".save()", ->
|
||||
beforeEach ->
|
||||
buffer.destroy()
|
||||
|
||||
describe "when the buffer has a path", ->
|
||||
[filePath, buffer] = []
|
||||
filePath = null
|
||||
|
||||
beforeEach ->
|
||||
filePath = '/tmp/temp.txt'
|
||||
fs.remove filePath if fs.exists(filePath)
|
||||
fs.write(filePath, "")
|
||||
buffer = new Buffer filePath
|
||||
|
||||
afterEach ->
|
||||
@@ -242,7 +257,7 @@ describe 'Buffer', ->
|
||||
buffer.save()
|
||||
expect(events).toEqual ['beforeSave1', 'beforeSave2', 'fs.write', 'afterSave1', 'afterSave2']
|
||||
|
||||
describe "when the buffer no path", ->
|
||||
describe "when the buffer has no path", ->
|
||||
it "throws an exception", ->
|
||||
buffer = new Buffer
|
||||
expect(-> buffer.save()).toThrow()
|
||||
@@ -251,13 +266,12 @@ describe 'Buffer', ->
|
||||
filePath = null
|
||||
|
||||
beforeEach ->
|
||||
filePath = require.resolve('fixtures') + '/temp.txt'
|
||||
expect(fs.exists(filePath)).toBeFalsy()
|
||||
|
||||
afterEach ->
|
||||
fs.remove filePath
|
||||
buffer.destroy()
|
||||
|
||||
it "saves the contents of the buffer to the path", ->
|
||||
filePath = '/tmp/temp.txt'
|
||||
fs.remove filePath if fs.exists(filePath)
|
||||
|
||||
buffer = new Buffer()
|
||||
eventHandler = jasmine.createSpy('eventHandler')
|
||||
buffer.on 'path-change', eventHandler
|
||||
@@ -268,6 +282,25 @@ describe 'Buffer', ->
|
||||
|
||||
expect(eventHandler).toHaveBeenCalledWith(buffer)
|
||||
|
||||
it "stops listening to events on previous path and begins listening to events on new path", ->
|
||||
originalPath = "/tmp/original.txt"
|
||||
newPath = "/tmp/new.txt"
|
||||
fs.write(originalPath, "")
|
||||
buffer = new Buffer(originalPath)
|
||||
changeHandler = jasmine.createSpy('changeHandler')
|
||||
buffer.on 'change', changeHandler
|
||||
buffer.saveAs(newPath)
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
|
||||
fs.write(originalPath, "should not trigger buffer event")
|
||||
waits 20
|
||||
runs ->
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
fs.write(newPath, "should trigger buffer event")
|
||||
|
||||
waitsFor ->
|
||||
changeHandler.callCount > 0
|
||||
|
||||
describe ".getTextInRange(range)", ->
|
||||
describe "when range is empty", ->
|
||||
it "returns an empty string", ->
|
||||
@@ -478,23 +511,3 @@ describe 'Buffer', ->
|
||||
expect(buffer.positionForCharacterIndex(30)).toEqual [1, 0]
|
||||
expect(buffer.positionForCharacterIndex(61)).toEqual [2, 0]
|
||||
expect(buffer.positionForCharacterIndex(408)).toEqual [12, 2]
|
||||
|
||||
describe ".setPath(path)", ->
|
||||
[path, newPath] = []
|
||||
beforeEach ->
|
||||
path = fs.join(require.resolve('fixtures'), "tmp.txt")
|
||||
fs.write(path, "first")
|
||||
|
||||
afterEach ->
|
||||
fs.remove(path)
|
||||
|
||||
it "stops listening to events on previous path and begins listening to events on new path", ->
|
||||
buffer = new Buffer(path)
|
||||
changeHandler = jasmine.createSpy('changeHandler')
|
||||
buffer.on 'change', changeHandler
|
||||
buffer.setPath(filePath)
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
|
||||
fs.write(path, "should not trigger buffer event")
|
||||
waits 20
|
||||
runs -> expect(changeHandler).not.toHaveBeenCalled()
|
||||
|
||||
@@ -10,6 +10,9 @@ describe "DisplayBuffer", ->
|
||||
changeHandler = jasmine.createSpy 'changeHandler'
|
||||
displayBuffer.on 'change', changeHandler
|
||||
|
||||
afterEach ->
|
||||
buffer.destroy()
|
||||
|
||||
describe "when the buffer changes", ->
|
||||
it "renders line numbers correctly", ->
|
||||
originalLineCount = displayBuffer.lineCount()
|
||||
@@ -196,6 +199,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "primitive folding", ->
|
||||
beforeEach ->
|
||||
buffer.destroy()
|
||||
buffer = new Buffer(require.resolve 'fixtures/two-hundred.txt')
|
||||
displayBuffer = new DisplayBuffer(buffer, {tabText})
|
||||
displayBuffer.on 'change', changeHandler
|
||||
|
||||
@@ -14,6 +14,9 @@ describe "EditSession", ->
|
||||
|
||||
lineLengths = buffer.getLines().map (line) -> line.length
|
||||
|
||||
afterEach ->
|
||||
buffer.destroy()
|
||||
|
||||
describe "cursor movement", ->
|
||||
describe ".setCursorScreenPosition(screenPosition)", ->
|
||||
it "clears a goal column established by vertical movement", ->
|
||||
@@ -1326,6 +1329,12 @@ describe "EditSession", ->
|
||||
editSession.foldAll()
|
||||
expect(editSession.getCursorBufferPosition()).toEqual([5,5])
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "triggers `destroy` event", ->
|
||||
spyOn(editSession, 'trigger')
|
||||
editSession.destroy()
|
||||
expect(editSession.trigger).toHaveBeenCalledWith('destroy')
|
||||
|
||||
describe ".clipBufferPosition(bufferPosition)", ->
|
||||
it "clips the given position to a valid position", ->
|
||||
expect(editSession.clipBufferPosition([-1, -1])).toEqual [0,0]
|
||||
|
||||
@@ -37,7 +37,7 @@ describe "Editor", ->
|
||||
editor.isFocused = true
|
||||
|
||||
afterEach ->
|
||||
editor.remove()
|
||||
rootView.remove()
|
||||
|
||||
describe "construction", ->
|
||||
it "throws an error if no editor session is given", ->
|
||||
@@ -54,7 +54,7 @@ describe "Editor", ->
|
||||
editor.scrollTop(1.5 * editor.lineHeight)
|
||||
editor.scrollView.scrollLeft(44)
|
||||
|
||||
# prove this test covers serialization and deserialization
|
||||
# proves this test covers serialization and deserialization
|
||||
spyOn(editor, 'serialize').andCallThrough()
|
||||
spyOn(Editor, 'deserialize').andCallThrough()
|
||||
|
||||
@@ -278,7 +278,9 @@ describe "Editor", ->
|
||||
tempFilePath = null
|
||||
|
||||
beforeEach ->
|
||||
rootView.remove()
|
||||
tempFilePath = '/tmp/atom-temp.txt'
|
||||
fs.write(tempFilePath, "")
|
||||
rootView = new RootView(tempFilePath)
|
||||
project = rootView.project
|
||||
|
||||
@@ -290,7 +292,7 @@ describe "Editor", ->
|
||||
|
||||
it "saves the current buffer to disk", ->
|
||||
editor.buffer.setText 'Edited!'
|
||||
expect(fs.exists(tempFilePath)).toBeFalsy()
|
||||
expect(fs.read(tempFilePath)).not.toBe "Edited!"
|
||||
|
||||
editor.save()
|
||||
|
||||
@@ -314,6 +316,7 @@ describe "Editor", ->
|
||||
it "saves the buffer to the chosen path", ->
|
||||
selectedFilePath = '/tmp/temp.txt'
|
||||
|
||||
console.log 'about to save'
|
||||
editor.save()
|
||||
|
||||
expect(fs.exists(selectedFilePath)).toBeTruthy()
|
||||
@@ -409,15 +412,24 @@ describe "Editor", ->
|
||||
expect(openHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "editor-path-change event", ->
|
||||
path = null
|
||||
beforeEach ->
|
||||
path = "/tmp/something.txt"
|
||||
fs.write(path, path)
|
||||
|
||||
afterEach ->
|
||||
fs.remove(path) if fs.exists(path)
|
||||
|
||||
it "emits event when buffer's path is changed", ->
|
||||
eventHandler = jasmine.createSpy('eventHandler')
|
||||
editor.on 'editor-path-change', eventHandler
|
||||
editor.buffer.setPath("moo.text")
|
||||
editor.buffer.saveAs(path)
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
it "emits event when editor receives a new buffer", ->
|
||||
eventHandler = jasmine.createSpy('eventHandler')
|
||||
editor.on 'editor-path-change', eventHandler
|
||||
editor.edit(rootView.project.open("something.txt"))
|
||||
editor.edit(rootView.project.open(path))
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
it "stops listening to events on previously set buffers", ->
|
||||
@@ -425,15 +437,15 @@ describe "Editor", ->
|
||||
oldBuffer = editor.buffer
|
||||
editor.on 'editor-path-change', eventHandler
|
||||
|
||||
editor.edit(rootView.project.open("something.txt"))
|
||||
editor.edit(rootView.project.open(path))
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
eventHandler.reset()
|
||||
oldBuffer.setPath("bad.txt")
|
||||
oldBuffer.saveAs("/tmp/atom-bad.txt")
|
||||
expect(eventHandler).not.toHaveBeenCalled()
|
||||
|
||||
eventHandler.reset()
|
||||
editor.buffer.setPath("new.txt")
|
||||
editor.buffer.saveAs("/tmp/atom-new.txt")
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
describe "font size", ->
|
||||
|
||||
@@ -6,6 +6,24 @@ describe "Project", ->
|
||||
beforeEach ->
|
||||
project = new Project(require.resolve('fixtures/dir'))
|
||||
|
||||
describe "when editSession is destroyed", ->
|
||||
it "removes edit session and calls destroy on buffer (if buffer is not referenced by other edit sessions)", ->
|
||||
editSession = project.open("a")
|
||||
anotherEditSession = project.open("a")
|
||||
buffer = editSession.buffer
|
||||
spyOn(buffer, 'destroy').andCallThrough()
|
||||
|
||||
expect(project.editSessions.length).toBe 2
|
||||
expect(editSession.buffer).toBe anotherEditSession.buffer
|
||||
|
||||
editSession.destroy()
|
||||
expect(buffer.destroy).not.toHaveBeenCalled()
|
||||
expect(project.editSessions.length).toBe 1
|
||||
|
||||
anotherEditSession.destroy()
|
||||
expect(buffer.destroy).toHaveBeenCalled()
|
||||
expect(project.editSessions.length).toBe 0
|
||||
|
||||
describe ".open(path)", ->
|
||||
[absolutePath, newBufferHandler, newEditSessionHandler] = []
|
||||
beforeEach ->
|
||||
@@ -18,14 +36,14 @@ describe "Project", ->
|
||||
describe "when given an absolute path that hasn't been opened previously", ->
|
||||
it "returns a new edit session for the given path and emits 'new-buffer' and 'new-edit-session' events", ->
|
||||
editSession = project.open(absolutePath)
|
||||
expect(editSession.buffer.path).toBe absolutePath
|
||||
expect(editSession.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
|
||||
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
|
||||
|
||||
describe "when given a relative path that hasn't been opened previously", ->
|
||||
it "returns a new edit session for the given path (relative to the project root) and emits 'new-buffer' and 'new-edit-session' events", ->
|
||||
editSession = project.open('a')
|
||||
expect(editSession.buffer.path).toBe absolutePath
|
||||
expect(editSession.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
|
||||
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
|
||||
|
||||
@@ -78,7 +96,6 @@ describe "Project", ->
|
||||
expect(project.getPath()?).toBeFalsy()
|
||||
expect(project.getRootDirectory()?).toBeFalsy()
|
||||
|
||||
|
||||
describe ".getFilePaths()", ->
|
||||
it "ignores files that return true from atom.ignorePath(path)", ->
|
||||
spyOn(project, 'ignorePath').andCallFake (path) -> fs.base(path).match /a$/
|
||||
|
||||
@@ -15,6 +15,9 @@ describe "RootView", ->
|
||||
rootView.enableKeymap()
|
||||
rootView.focus()
|
||||
|
||||
afterEach ->
|
||||
rootView.remove()
|
||||
|
||||
describe "initialize(pathToOpen)", ->
|
||||
describe "when called with a pathToOpen", ->
|
||||
describe "when pathToOpen references a file", ->
|
||||
@@ -27,6 +30,9 @@ describe "RootView", ->
|
||||
expect(document.title).toBe path
|
||||
|
||||
describe "when pathToOpen references a directory", ->
|
||||
beforeEach ->
|
||||
rootView.remove()
|
||||
|
||||
it "creates a project for the directory and sets the document.title, but does not open an editor", ->
|
||||
path = require.resolve 'fixtures/dir'
|
||||
rootView = new RootView(path)
|
||||
@@ -43,6 +49,7 @@ describe "RootView", ->
|
||||
buffer = null
|
||||
|
||||
beforeEach ->
|
||||
rootView.remove()
|
||||
rootView = new RootView
|
||||
rootView.open()
|
||||
editor1 = rootView.activeEditor()
|
||||
@@ -60,6 +67,7 @@ describe "RootView", ->
|
||||
describe "when the serialized RootView has a project", ->
|
||||
beforeEach ->
|
||||
path = require.resolve 'fixtures'
|
||||
rootView.remove()
|
||||
rootView = new RootView(path)
|
||||
rootView.open('dir/a')
|
||||
|
||||
@@ -87,11 +95,11 @@ describe "RootView", ->
|
||||
editor2 = rootView.panes.find('.row > .column > .pane .editor:eq(0)').view()
|
||||
editor4 = rootView.panes.find('.row > .column > .pane .editor:eq(1)').view()
|
||||
|
||||
expect(editor1.buffer.path).toBe require.resolve('fixtures/dir/a')
|
||||
expect(editor2.buffer.path).toBe require.resolve('fixtures/dir/b')
|
||||
expect(editor3.buffer.path).toBe require.resolve('fixtures/sample.js')
|
||||
expect(editor1.buffer.getPath()).toBe require.resolve('fixtures/dir/a')
|
||||
expect(editor2.buffer.getPath()).toBe require.resolve('fixtures/dir/b')
|
||||
expect(editor3.buffer.getPath()).toBe require.resolve('fixtures/sample.js')
|
||||
expect(editor3.getCursorScreenPosition()).toEqual [2, 3]
|
||||
expect(editor4.buffer.path).toBe require.resolve('fixtures/sample.txt')
|
||||
expect(editor4.buffer.getPath()).toBe require.resolve('fixtures/sample.txt')
|
||||
expect(editor4.getCursorScreenPosition()).toEqual [0, 2]
|
||||
|
||||
# ensure adjust pane dimensions is called
|
||||
@@ -106,10 +114,11 @@ describe "RootView", ->
|
||||
expect(editor3.isFocused).toBeFalsy()
|
||||
expect(editor4.isFocused).toBeFalsy()
|
||||
|
||||
expect(document.title).toBe editor2.buffer.path
|
||||
expect(document.title).toBe editor2.buffer.getPath()
|
||||
|
||||
describe "when called with no pathToOpen", ->
|
||||
it "opens no buffer", ->
|
||||
rootView.remove()
|
||||
rootView = new RootView
|
||||
expect(rootView.editors().length).toBe 0
|
||||
expect(document.title).toBe 'untitled'
|
||||
@@ -137,6 +146,7 @@ describe "RootView", ->
|
||||
|
||||
describe "focus", ->
|
||||
it "can receive focus if there is no active editor, but otherwise hands off focus to the active editor", ->
|
||||
rootView.remove()
|
||||
rootView = new RootView(require.resolve 'fixtures')
|
||||
rootView.attachToDom()
|
||||
expect(rootView).toMatchSelector(':focus')
|
||||
@@ -433,7 +443,7 @@ describe "RootView", ->
|
||||
expect(Object.keys(keybindings).length).toBe 2
|
||||
expect(keybindings["meta-a"]).toEqual "test-event-a"
|
||||
|
||||
describe "when the path of the focused editor's buffer changes", ->
|
||||
describe "when the focused editor changes", ->
|
||||
it "changes the document.title and emits an active-editor-path-change event", ->
|
||||
pathChangeHandler = jasmine.createSpy 'pathChangeHandler'
|
||||
rootView.on 'active-editor-path-change', pathChangeHandler
|
||||
@@ -442,16 +452,19 @@ describe "RootView", ->
|
||||
expect(document.title).toBe path
|
||||
|
||||
editor2 = rootView.activeEditor().splitLeft()
|
||||
editor2.edit(rootView.project.open("second.txt"))
|
||||
|
||||
path = rootView.project.resolve('b')
|
||||
editor2.edit(rootView.project.open(path))
|
||||
expect(pathChangeHandler).toHaveBeenCalled()
|
||||
expect(document.title).toBe rootView.project.resolve("second.txt")
|
||||
expect(document.title).toBe rootView.project.resolve(path)
|
||||
|
||||
pathChangeHandler.reset()
|
||||
editor1.buffer.setPath("should-not-be-title.txt")
|
||||
editor1.buffer.saveAs("/tmp/should-not-be-title.txt")
|
||||
expect(pathChangeHandler).not.toHaveBeenCalled()
|
||||
expect(document.title).toBe rootView.project.resolve("second.txt")
|
||||
expect(document.title).toBe rootView.project.resolve(path)
|
||||
|
||||
it "creates a project if there isn't one yet and the buffer was previously unsaved", ->
|
||||
rootView.remove()
|
||||
rootView = new RootView
|
||||
rootView.open()
|
||||
expect(rootView.project.getPath()?).toBeFalsy()
|
||||
|
||||
177
spec/extensions/file-finder-spec.coffee
Normal file
177
spec/extensions/file-finder-spec.coffee
Normal file
@@ -0,0 +1,177 @@
|
||||
RootView = require 'root-view'
|
||||
FileFinder = require 'file-finder'
|
||||
$ = require 'jquery'
|
||||
{$$} = require 'space-pen'
|
||||
|
||||
describe 'FileFinder', ->
|
||||
[rootView, finder] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView(require.resolve('fixtures/sample.js'))
|
||||
rootView.enableKeymap()
|
||||
rootView.activateExtension(FileFinder)
|
||||
finder = FileFinder.instance
|
||||
|
||||
describe "when the file-finder:toggle event is triggered on the root view", ->
|
||||
describe "when there is a project", ->
|
||||
it "shows or hides the FileFinder, returning focus to the active editor when hiding it", ->
|
||||
rootView.attachToDom()
|
||||
expect(rootView.find('.file-finder')).not.toExist()
|
||||
rootView.find('.editor').trigger 'split-right'
|
||||
[editor1, editor2] = rootView.find('.editor').map -> $(this).view()
|
||||
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(rootView.find('.file-finder')).toExist()
|
||||
expect(rootView.find('.file-finder input:focus')).toExist()
|
||||
finder.miniEditor.insertText('this should not show up next time we toggle')
|
||||
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(editor1.isFocused).toBeFalsy()
|
||||
expect(editor2.isFocused).toBeTruthy()
|
||||
expect(rootView.find('.file-finder')).not.toExist()
|
||||
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(finder.miniEditor.getText()).toBe ''
|
||||
|
||||
it "shows all relative file paths for the current project and selects the first", ->
|
||||
finder.maxResults = 1000
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
rootView.project.getFilePaths().done (paths) ->
|
||||
expect(finder.pathList.children('li').length).toBe paths.length, finder.maxResults
|
||||
for path in paths
|
||||
expect(finder.pathList.find("li:contains(#{path})")).toExist()
|
||||
expect(finder.pathList.children().first()).toHaveClass 'selected'
|
||||
|
||||
describe "when root view's project has no path", ->
|
||||
beforeEach ->
|
||||
rootView.project.setPath(null)
|
||||
|
||||
it "does not open the FileFinder", ->
|
||||
expect(rootView.find('.file-finder')).not.toExist()
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(rootView.find('.file-finder')).not.toExist()
|
||||
|
||||
describe "file-finder:cancel event", ->
|
||||
it "hides the finder", ->
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(finder.hasParent()).toBeTruthy()
|
||||
|
||||
finder.trigger 'file-finder:cancel'
|
||||
expect(finder.hasParent()).toBeFalsy()
|
||||
|
||||
it "focuses previously focused element", ->
|
||||
rootView.attachToDom()
|
||||
activeEditor = rootView.activeEditor()
|
||||
activeEditor.focus()
|
||||
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
expect(activeEditor.isFocused).toBeFalsy()
|
||||
expect(finder.miniEditor.isFocused).toBeTruthy()
|
||||
|
||||
finder.trigger 'file-finder:cancel'
|
||||
expect(activeEditor.isFocused).toBeTruthy()
|
||||
expect(finder.miniEditor.isFocused).toBeFalsy()
|
||||
|
||||
describe "when the file finder loses focus", ->
|
||||
it "detaches itself", ->
|
||||
rootView.attachToDom()
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
|
||||
expect(finder.hasParent()).toBeTruthy()
|
||||
rootView.focus()
|
||||
expect(finder.hasParent()).toBeFalsy()
|
||||
|
||||
describe "when characters are typed into the input element", ->
|
||||
it "displays matching paths in the ol element and selects the first", ->
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
|
||||
listLengthBefore = finder.pathList.children().length
|
||||
|
||||
finder.miniEditor.insertText('samp')
|
||||
|
||||
expect(finder.pathList.children().length).toBeLessThan(listLengthBefore)
|
||||
expect(finder.pathList.find('li:first')).toHaveClass 'selected'
|
||||
expect(finder.pathList.find('li.selected').length).toBe 1
|
||||
|
||||
# we should clear the list before re-populating it
|
||||
finder.miniEditor.insertText('txt')
|
||||
|
||||
expect(finder.pathList.children().length).toBe 1
|
||||
expect(finder.pathList.find('li:first')).toHaveClass 'selected'
|
||||
expect(finder.pathList.find('li:first')).toHaveText 'sample.txt'
|
||||
|
||||
describe "move-down / move-up events", ->
|
||||
beforeEach ->
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
|
||||
it "selects the next / previous path in the list", ->
|
||||
expect(finder.find('li:eq(0)')).toHaveClass "selected"
|
||||
expect(finder.find('li:eq(2)')).not.toHaveClass "selected"
|
||||
|
||||
finder.miniEditor.trigger keydownEvent('down')
|
||||
finder.miniEditor.trigger keydownEvent('down')
|
||||
|
||||
expect(finder.find('li:eq(0)')).not.toHaveClass "selected"
|
||||
expect(finder.find('li:eq(2)')).toHaveClass "selected"
|
||||
|
||||
finder.miniEditor.trigger keydownEvent('up')
|
||||
|
||||
expect(finder.find('li:eq(0)')).not.toHaveClass "selected"
|
||||
expect(finder.find('li:eq(1)')).toHaveClass "selected"
|
||||
expect(finder.find('li:eq(2)')).not.toHaveClass "selected"
|
||||
|
||||
it "does not fall off the end or begining of the list", ->
|
||||
expect(finder.find('li:first')).toHaveClass "selected"
|
||||
finder.miniEditor.trigger keydownEvent('up')
|
||||
expect(finder.find('li:first')).toHaveClass "selected"
|
||||
|
||||
for i in [1..finder.pathList.children().length+2]
|
||||
finder.miniEditor.trigger keydownEvent('down')
|
||||
|
||||
expect(finder.find('li:last')).toHaveClass "selected"
|
||||
|
||||
describe "select-file events", ->
|
||||
[editor1, editor2] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView.attachToDom()
|
||||
editor1 = rootView.activeEditor()
|
||||
editor2 = editor1.splitRight()
|
||||
expect(rootView.activeEditor()).toBe editor2
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
|
||||
describe "when there is a path selected", ->
|
||||
it "opens the file associated with that path in the editor", ->
|
||||
finder.trigger 'move-down'
|
||||
selectedLi = finder.find('li:eq(1)')
|
||||
|
||||
expectedPath = rootView.project.resolve(selectedLi.text())
|
||||
expect(editor1.buffer.getPath()).not.toBe expectedPath
|
||||
expect(editor2.buffer.getPath()).not.toBe expectedPath
|
||||
|
||||
finder.trigger 'file-finder:select-file'
|
||||
|
||||
expect(finder.hasParent()).toBeFalsy()
|
||||
expect(editor1.buffer.getPath()).not.toBe expectedPath
|
||||
expect(editor2.buffer.getPath()).toBe expectedPath
|
||||
expect(editor2.isFocused).toBeTruthy()
|
||||
|
||||
describe "when there is no path selected", ->
|
||||
it "does nothing", ->
|
||||
finder.miniEditor.insertText('this should match nothing, because no one wants to drink battery acid')
|
||||
finder.trigger 'file-finder:select-file'
|
||||
expect(finder.hasParent()).toBeTruthy()
|
||||
|
||||
describe ".findMatches(queryString)", ->
|
||||
beforeEach ->
|
||||
rootView.trigger 'file-finder:toggle'
|
||||
|
||||
it "returns up to finder.maxResults paths if queryString is empty", ->
|
||||
expect(finder.findMatches('').length).toBeLessThan finder.maxResults + 1
|
||||
finder.maxResults = 5
|
||||
expect(finder.findMatches('').length).toBeLessThan finder.maxResults + 1
|
||||
|
||||
it "returns paths sorted by score of match against the given query", ->
|
||||
finder.paths = ["app.coffee", "atom/app.coffee"]
|
||||
expect(finder.findMatches('app.co')).toEqual ["app.coffee", "atom/app.coffee"]
|
||||
expect(finder.findMatches('atom/app.co')).toEqual ["atom/app.coffee"]
|
||||
@@ -3,22 +3,27 @@ RootView = require 'root-view'
|
||||
fs = require 'fs'
|
||||
|
||||
describe "StripTrailingWhitespace", ->
|
||||
[rootView, editor] = []
|
||||
[rootView, editor, path] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView
|
||||
rootView.open()
|
||||
path = "/tmp/atom-whitespace.txt"
|
||||
fs.write(path, "")
|
||||
rootView = new RootView(path)
|
||||
|
||||
StripTrailingWhitespace.activate(rootView)
|
||||
rootView.focus()
|
||||
editor = rootView.activeEditor()
|
||||
|
||||
afterEach ->
|
||||
fs.remove(path) if fs.exists(path)
|
||||
rootView.remove()
|
||||
|
||||
it "strips trailing whitespace before an editor saves a buffer", ->
|
||||
spyOn(fs, 'write')
|
||||
|
||||
# works for buffers that are already open when extension is initialized
|
||||
editor.insertText("foo \nbar\t \n\nbaz")
|
||||
editor.buffer.saveAs("/tmp/test")
|
||||
editor.save()
|
||||
expect(editor.buffer.getText()).toBe "foo\nbar\n\nbaz"
|
||||
|
||||
# works for buffers that are opened after extension is initialized
|
||||
|
||||
@@ -168,20 +168,20 @@ describe "TreeView", ->
|
||||
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleJs).toHaveClass 'selected'
|
||||
expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.js')
|
||||
expect(rootView.activeEditor().buffer.getPath()).toBe require.resolve('fixtures/sample.js')
|
||||
expect(rootView.activeEditor().isFocused).toBeFalsy()
|
||||
|
||||
sampleTxt.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleTxt).toHaveClass 'selected'
|
||||
expect(treeView.find('.selected').length).toBe 1
|
||||
expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.txt')
|
||||
expect(rootView.activeEditor().buffer.getPath()).toBe require.resolve('fixtures/sample.txt')
|
||||
expect(rootView.activeEditor().isFocused).toBeFalsy()
|
||||
|
||||
describe "when a file is double-clicked", ->
|
||||
it "selects the file and opens it in the active editor on the first click, then changes focus to the active editor on the second", ->
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleJs).toHaveClass 'selected'
|
||||
expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.js')
|
||||
expect(rootView.activeEditor().buffer.getPath()).toBe require.resolve('fixtures/sample.js')
|
||||
expect(rootView.activeEditor().isFocused).toBeFalsy()
|
||||
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 2 })
|
||||
@@ -388,7 +388,7 @@ describe "TreeView", ->
|
||||
it "opens the file in the editor", ->
|
||||
treeView.root.find('.file:contains(sample.js)').click()
|
||||
treeView.root.trigger 'tree-view:open-selected-entry'
|
||||
expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.js')
|
||||
expect(rootView.activeEditor().buffer.getPath()).toBe require.resolve('fixtures/sample.js')
|
||||
|
||||
describe "when a directory is selected", ->
|
||||
it "expands or collapses the directory", ->
|
||||
@@ -467,7 +467,7 @@ describe "TreeView", ->
|
||||
expect(fs.exists(newPath)).toBeTruthy()
|
||||
expect(fs.isFile(newPath)).toBeTruthy()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.activeEditor().buffer.path).toBe newPath
|
||||
expect(rootView.activeEditor().buffer.getPath()).toBe newPath
|
||||
|
||||
waitsFor "tree view to be updated", ->
|
||||
dirView.entries.find("> .file").length > 1
|
||||
@@ -496,7 +496,7 @@ describe "TreeView", ->
|
||||
expect(fs.exists(newPath)).toBeTruthy()
|
||||
expect(fs.isDirectory(newPath)).toBeTruthy()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.activeEditor().buffer.path).not.toBe newPath
|
||||
expect(rootView.activeEditor().buffer.getPath()).not.toBe newPath
|
||||
|
||||
describe "when a or directory already exists at the given path", ->
|
||||
it "shows an error message and does not close the dialog", ->
|
||||
|
||||
@@ -13,20 +13,34 @@ class Buffer
|
||||
lines: null
|
||||
file: null
|
||||
|
||||
|
||||
constructor: (path) ->
|
||||
@id = @constructor.idCounter++
|
||||
@setPath(path)
|
||||
@lines = ['']
|
||||
if fs.exists(@getPath())
|
||||
@undoManager = new UndoManager(this)
|
||||
|
||||
if path
|
||||
throw "Path '#{path}' does not exist" unless fs.exists(path)
|
||||
@setPath(path)
|
||||
@setText(fs.read(@getPath()))
|
||||
else
|
||||
@setText('')
|
||||
@undoManager = new UndoManager(this)
|
||||
|
||||
@modified = false
|
||||
|
||||
destroy: ->
|
||||
@file?.off()
|
||||
|
||||
getPath: ->
|
||||
@file.getPath()
|
||||
@file?.getPath()
|
||||
|
||||
setPath: (path) ->
|
||||
return if path == @getPath()
|
||||
|
||||
@file?.off()
|
||||
@file = new File(path)
|
||||
@file.on "contents-change", =>
|
||||
@setText(fs.read(@file.getPath())) unless @isModified()
|
||||
@trigger "path-change", this
|
||||
|
||||
getExtension: ->
|
||||
if @getPath()
|
||||
@@ -34,13 +48,6 @@ class Buffer
|
||||
else
|
||||
null
|
||||
|
||||
setPath: (path) ->
|
||||
@file?.off()
|
||||
@file = new File(path)
|
||||
@file.on "contents-change", =>
|
||||
@setText(fs.read(@file.getPath())) unless @isModified()
|
||||
@trigger "path-change", this
|
||||
|
||||
getText: ->
|
||||
@lines.join('\n')
|
||||
|
||||
@@ -156,15 +163,16 @@ class Buffer
|
||||
@undoManager.redo()
|
||||
|
||||
save: ->
|
||||
if not @getPath() then throw new Error("Can't save buffer with no file path")
|
||||
@trigger 'before-save'
|
||||
fs.write @getPath(), @getText()
|
||||
@modified = false
|
||||
@trigger 'after-save'
|
||||
@saveAs(@getPath())
|
||||
|
||||
saveAs: (path) ->
|
||||
if not path then throw new Error("Can't save buffer with no file path")
|
||||
|
||||
@trigger 'before-save'
|
||||
fs.write path, @getText()
|
||||
@modified = false
|
||||
@setPath(path)
|
||||
@save()
|
||||
@trigger 'after-save'
|
||||
|
||||
isModified: ->
|
||||
@modified
|
||||
|
||||
@@ -54,6 +54,7 @@ class EditSession
|
||||
@buffer.off ".edit-session-#{@id}"
|
||||
@displayBuffer.off ".edit-session-#{@id}"
|
||||
@displayBuffer.destroy()
|
||||
@trigger "destroy"
|
||||
|
||||
serialize: ->
|
||||
buffer: @buffer.getPath()
|
||||
|
||||
@@ -572,7 +572,8 @@ class Editor extends View
|
||||
@buffer.off ".editor#{@id}"
|
||||
|
||||
destroyEditSessions: ->
|
||||
session.destroy() for session in @editSessions
|
||||
for session in @editSessions
|
||||
session.destroy()
|
||||
|
||||
renderWhenAttached: ->
|
||||
return unless @attached
|
||||
|
||||
@@ -89,6 +89,11 @@ class Project
|
||||
softTabs: @getSoftTabs()
|
||||
softWrap: @getSoftWrap()
|
||||
|
||||
editSession.on 'destroy', =>
|
||||
@editSessions = _.without(@editSessions, editSession)
|
||||
bufferIsOrphaned = not _.find @editSessions, (e) -> e.buffer == editSession.buffer
|
||||
editSession.buffer.destroy() if bufferIsOrphaned
|
||||
|
||||
@editSessions.push editSession
|
||||
@trigger 'new-edit-session', editSession
|
||||
editSession
|
||||
|
||||
@@ -132,9 +132,9 @@ class RootView extends View
|
||||
|
||||
if not editor.mini
|
||||
editor.on 'editor-path-change.root-view', =>
|
||||
@trigger 'active-editor-path-change', editor.buffer.path
|
||||
if not previousActiveEditor or editor.buffer.path != previousActiveEditor.buffer.path
|
||||
@trigger 'active-editor-path-change', editor.buffer.path
|
||||
@trigger 'active-editor-path-change', editor.buffer.getPath()
|
||||
if not previousActiveEditor or editor.buffer.getPath() != previousActiveEditor.buffer.getPath()
|
||||
@trigger 'active-editor-path-change', editor.buffer.getPath()
|
||||
|
||||
activeKeybindings: ->
|
||||
keymap.bindingsForElement(document.activeElement)
|
||||
|
||||
@@ -28,7 +28,7 @@ class StatusBar extends View
|
||||
@editor.on 'cursor-move', => @updateCursorPositionText()
|
||||
|
||||
updatePathText: ->
|
||||
path = @editor.buffer.path
|
||||
path = @editor.buffer.getPath()
|
||||
if path
|
||||
@currentPath.text(@rootView.project.relativize(path))
|
||||
else
|
||||
|
||||
@@ -101,7 +101,7 @@ class TreeView extends View
|
||||
@append(@root)
|
||||
|
||||
selectActiveFile: ->
|
||||
activeFilePath = @rootView.activeEditor()?.buffer.path
|
||||
activeFilePath = @rootView.activeEditor()?.buffer.getPath()
|
||||
@selectEntryForPath(activeFilePath)
|
||||
|
||||
selectEntryForPath: (path) ->
|
||||
|
||||
Reference in New Issue
Block a user