mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-11 16:09:57 +03:00
666 lines
27 KiB
CoffeeScript
666 lines
27 KiB
CoffeeScript
$ = require 'jquery'
|
|
_ = require 'underscore'
|
|
TreeView = require 'tree-view'
|
|
RootView = require 'root-view'
|
|
Directory = require 'directory'
|
|
Native = require 'native'
|
|
fs = require 'fs'
|
|
|
|
describe "TreeView", ->
|
|
[rootView, project, treeView, sampleJs, sampleTxt] = []
|
|
|
|
beforeEach ->
|
|
rootView = new RootView(require.resolve('fixtures/'))
|
|
project = rootView.project
|
|
|
|
rootView.activateExtension(TreeView)
|
|
treeView = rootView.find(".tree-view").view()
|
|
treeView.root = treeView.find('> li:first').view()
|
|
sampleJs = treeView.find('.file:contains(sample.js)')
|
|
sampleTxt = treeView.find('.file:contains(sample.txt)')
|
|
|
|
expect(treeView.root.directory.subscriptionCount()).toBeGreaterThan 0
|
|
|
|
afterEach ->
|
|
treeView.deactivate()
|
|
|
|
describe ".initialize(project)", ->
|
|
it "renders the root of the project and its contents alphabetically with subdirectories first in a collapsed state", ->
|
|
expect(treeView.root.find('> .header .disclosure-arrow')).toHaveText('▾')
|
|
expect(treeView.root.find('> .header .name')).toHaveText('fixtures/')
|
|
|
|
rootEntries = treeView.root.find('.entries')
|
|
subdir1 = rootEntries.find('> li:eq(0)')
|
|
expect(subdir1.find('.disclosure-arrow')).toHaveText('▸')
|
|
expect(subdir1.find('.name')).toHaveText('dir/')
|
|
expect(subdir1.find('.entries')).not.toExist()
|
|
|
|
subdir2 = rootEntries.find('> li:eq(1)')
|
|
expect(subdir2.find('.disclosure-arrow')).toHaveText('▸')
|
|
expect(subdir2.find('.name')).toHaveText('zed/')
|
|
expect(subdir2.find('.entries')).not.toExist()
|
|
|
|
expect(rootEntries.find('> .file:contains(sample.js)')).toExist()
|
|
expect(rootEntries.find('> .file:contains(sample.txt)')).toExist()
|
|
|
|
it "selects the rootview", ->
|
|
expect(treeView.selectedEntry()).toEqual treeView.root
|
|
|
|
describe "when the project has no path", ->
|
|
beforeEach ->
|
|
treeView.deactivate()
|
|
|
|
rootView = new RootView
|
|
rootView.activateExtension(TreeView)
|
|
treeView = rootView.find(".tree-view").view()
|
|
|
|
it "does not create a root node", ->
|
|
expect(treeView.root).not.toExist()
|
|
|
|
it "creates a root view when the project path is created", ->
|
|
rootView.open(require.resolve('fixtures/sample.js'))
|
|
expect(treeView.root.getPath()).toBe require.resolve('fixtures')
|
|
expect(treeView.root.parent()).toMatchSelector(".tree-view")
|
|
|
|
oldRoot = treeView.root
|
|
|
|
rootView.project.setPath('/tmp')
|
|
expect(treeView.root).not.toEqual oldRoot
|
|
expect(oldRoot.hasParent()).toBeFalsy()
|
|
|
|
describe "serialization", ->
|
|
newTreeView = null
|
|
|
|
afterEach ->
|
|
newTreeView.deactivate()
|
|
|
|
it "restores expanded directories and selected file when deserialized", ->
|
|
treeView.find('.directory:contains(zed)').click()
|
|
sampleJs.click()
|
|
newRootView = RootView.deserialize(rootView.serialize())
|
|
newRootView.activateExtension(TreeView)
|
|
|
|
newTreeView = newRootView.find(".tree-view").view()
|
|
|
|
expect(newTreeView).toExist()
|
|
expect(newTreeView.selectedEntry()).toMatchSelector(".file:contains(sample.js)")
|
|
expect(newTreeView.find(".directory:contains(zed)")).toHaveClass("expanded")
|
|
|
|
it "restores the focus state of the tree view", ->
|
|
treeView.attachToDom()
|
|
treeView.focus()
|
|
expect(treeView).toMatchSelector ':focus'
|
|
|
|
newRootView = RootView.deserialize(rootView.serialize())
|
|
rootView.remove()
|
|
newRootView.attachToDom()
|
|
newRootView.activateExtension(TreeView)
|
|
|
|
newTreeView = newRootView.find(".tree-view").view()
|
|
expect(newTreeView).toMatchSelector ':focus'
|
|
|
|
describe "when tree-view:toggle is triggered on the root view", ->
|
|
it "shows/hides the tree view", ->
|
|
rootView.attachToDom()
|
|
treeView.focus()
|
|
expect(treeView.hasParent()).toBeTruthy()
|
|
rootView.trigger 'tree-view:toggle'
|
|
expect(treeView.hasParent()).toBeFalsy()
|
|
expect(rootView).toMatchSelector(':focus')
|
|
|
|
rootView.trigger 'tree-view:toggle'
|
|
expect(treeView.hasParent()).toBeTruthy()
|
|
expect(treeView).toMatchSelector(':focus')
|
|
|
|
describe "when a directory's disclosure arrow is clicked", ->
|
|
it "expands / collapses the associated directory", ->
|
|
subdir = treeView.root.find('.entries > li:contains(dir/)').view()
|
|
|
|
expect(subdir.disclosureArrow).toHaveText('▸')
|
|
expect(subdir.find('.entries')).not.toExist()
|
|
|
|
subdir.disclosureArrow.click()
|
|
|
|
expect(subdir.disclosureArrow).toHaveText('▾')
|
|
expect(subdir.find('.entries')).toExist()
|
|
|
|
subdir.disclosureArrow.click()
|
|
expect(subdir.disclosureArrow).toHaveText('▸')
|
|
expect(subdir.find('.entries')).not.toExist()
|
|
|
|
it "restores the expansion state of descendant directories", ->
|
|
child = treeView.root.find('.entries > li:contains(dir/)').view()
|
|
child.disclosureArrow.click()
|
|
|
|
grandchild = child.find('.entries > li:contains(a-dir/)').view()
|
|
grandchild.disclosureArrow.click()
|
|
|
|
treeView.root.disclosureArrow.click()
|
|
expect(treeView.root.find('.entries')).not.toExist()
|
|
treeView.root.disclosureArrow.click()
|
|
|
|
# previously expanded descendants remain expanded
|
|
expect(treeView.root.find('> .entries > li:contains(dir/) > .entries > li:contains(a-dir/) > .entries').length).toBe 1
|
|
|
|
# collapsed descendants remain collapsed
|
|
expect(treeView.root.find('> .entries > li.contains(zed/) > .entries')).not.toExist()
|
|
|
|
it "when collapsing a directory, removes change subscriptions from the collapsed directory and its descendants", ->
|
|
child = treeView.root.entries.find('li:contains(dir/)').view()
|
|
child.disclosureArrow.click()
|
|
|
|
grandchild = child.entries.find('li:contains(a-dir/)').view()
|
|
grandchild.disclosureArrow.click()
|
|
|
|
expect(treeView.root.directory.subscriptionCount()).toBe 1
|
|
expect(child.directory.subscriptionCount()).toBe 1
|
|
expect(grandchild.directory.subscriptionCount()).toBe 1
|
|
|
|
treeView.root.disclosureArrow.click()
|
|
|
|
expect(treeView.root.directory.subscriptionCount()).toBe 0
|
|
expect(child.directory.subscriptionCount()).toBe 0
|
|
expect(grandchild.directory.subscriptionCount()).toBe 0
|
|
|
|
describe "when a file is single-clicked", ->
|
|
it "selects the files and opens it in the active editor, without changing focus", ->
|
|
expect(rootView.activeEditor()).toBeUndefined()
|
|
|
|
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
|
expect(sampleJs).toHaveClass 'selected'
|
|
expect(rootView.activeEditor().buffer.path).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().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().isFocused).toBeFalsy()
|
|
|
|
sampleJs.trigger clickEvent(originalEvent: { detail: 2 })
|
|
expect(rootView.activeEditor().isFocused).toBeTruthy()
|
|
|
|
describe "when a directory is single-clicked", ->
|
|
it "is selected", ->
|
|
subdir = treeView.root.find('.directory:first').view()
|
|
subdir.trigger clickEvent(originalEvent: { detail: 1 })
|
|
expect(subdir).toHaveClass 'selected'
|
|
|
|
describe "when a directory is double-clicked", ->
|
|
it "toggles the directory expansion state and does not change the focus to the editor", ->
|
|
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
|
subdir = treeView.root.find('.directory:first').view()
|
|
subdir.trigger clickEvent(originalEvent: { detail: 1 })
|
|
expect(subdir).toHaveClass 'selected'
|
|
subdir.trigger clickEvent(originalEvent: { detail: 2 })
|
|
expect(subdir).toHaveClass 'expanded'
|
|
expect(rootView.activeEditor().isFocused).toBeFalsy()
|
|
|
|
describe "when a new file is opened in the active editor", ->
|
|
it "is selected in the tree view if the file's entry visible", ->
|
|
sampleJs.click()
|
|
rootView.open(require.resolve('fixtures/sample.txt'))
|
|
|
|
expect(sampleTxt).toHaveClass 'selected'
|
|
expect(treeView.find('.selected').length).toBe 1
|
|
|
|
it "selected a file's parent dir if the file's entry is not visible", ->
|
|
# treeView.attachToDom()
|
|
rootView.open(require.resolve('fixtures/dir/a-dir/oh-git'))
|
|
|
|
dirView = treeView.root.find('.directory:contains(dir)').view()
|
|
expect(dirView).toHaveClass 'selected'
|
|
|
|
# dirView.expand()
|
|
# aDirView = dirView.find('.directory:contains(a-dir)').view()
|
|
# expect(aDirView).toHaveClass 'selected'
|
|
|
|
describe "when a different editor becomes active", ->
|
|
it "selects the file in that is open in that editor", ->
|
|
sampleJs.click()
|
|
leftEditor = rootView.activeEditor()
|
|
rightEditor = leftEditor.splitRight()
|
|
sampleTxt.click()
|
|
|
|
expect(sampleTxt).toHaveClass('selected')
|
|
leftEditor.focus()
|
|
expect(sampleJs).toHaveClass('selected')
|
|
|
|
describe "keyboard navigation", ->
|
|
afterEach ->
|
|
expect(treeView.find('.selected').length).toBeLessThan 2
|
|
|
|
describe "move-down", ->
|
|
describe "when a collapsed directory is selected", ->
|
|
it "skips to the next directory", ->
|
|
treeView.root.find('.directory:eq(0)').click()
|
|
treeView.trigger 'move-down'
|
|
expect(treeView.root.find('.directory:eq(1)')).toHaveClass 'selected'
|
|
|
|
describe "when an expanded directory is selected", ->
|
|
it "selects the first entry of the directory", ->
|
|
subdir = treeView.root.find('.directory:eq(1)').view()
|
|
subdir.expand()
|
|
subdir.click()
|
|
|
|
treeView.trigger 'move-down'
|
|
|
|
expect(subdir.entries.find('.entry:first')).toHaveClass 'selected'
|
|
|
|
describe "when the last entry of an expanded directory is selected", ->
|
|
it "selects the entry after its parent directory", ->
|
|
subdir1 = treeView.root.find('.directory:eq(1)').view()
|
|
subdir1.expand()
|
|
subdir1.entries.find('.entry:last').click()
|
|
|
|
treeView.trigger 'move-down'
|
|
|
|
expect(treeView.root.find('.entries > .entry:eq(2)')).toHaveClass 'selected'
|
|
|
|
describe "when the last entry of the last directory is selected", ->
|
|
it "does not change the selection", ->
|
|
lastEntry = treeView.root.find('> .entries .entry:last')
|
|
lastEntry.click()
|
|
|
|
treeView.trigger 'move-down'
|
|
|
|
expect(lastEntry).toHaveClass 'selected'
|
|
|
|
describe "move-up", ->
|
|
describe "when there is an expanded directory before the currently selected entry", ->
|
|
it "selects the last entry in the expanded directory", ->
|
|
lastDir = treeView.root.find('.directory:last').view()
|
|
fileAfterDir = lastDir.next().view()
|
|
lastDir.expand()
|
|
fileAfterDir.click()
|
|
|
|
treeView.trigger 'move-up'
|
|
expect(lastDir.find('.entry:last')).toHaveClass 'selected'
|
|
|
|
describe "when there is an entry before the currently selected entry", ->
|
|
it "selects the previous entry", ->
|
|
lastEntry = treeView.root.find('.entry:last')
|
|
lastEntry.click()
|
|
|
|
treeView.trigger 'move-up'
|
|
|
|
expect(lastEntry.prev()).toHaveClass 'selected'
|
|
|
|
describe "when there is no entry before the currently selected entry, but there is a parent directory", ->
|
|
it "selects the parent directory", ->
|
|
subdir = treeView.root.find('.directory:first').view()
|
|
subdir.expand()
|
|
subdir.find('> .entries > .entry:first').click()
|
|
|
|
treeView.trigger 'move-up'
|
|
|
|
expect(subdir).toHaveClass 'selected'
|
|
|
|
describe "when there is no parent directory or previous entry", ->
|
|
it "does not change the selection", ->
|
|
treeView.root.click()
|
|
treeView.trigger 'move-up'
|
|
expect(treeView.root).toHaveClass 'selected'
|
|
|
|
describe "movement outside of viewable region", ->
|
|
it "scrolls the tree view to the selected item", ->
|
|
treeView.height(100)
|
|
treeView.attachToDom()
|
|
$(element).view().expand() for element in treeView.find('.directory')
|
|
expect(treeView.prop('scrollHeight')).toBeGreaterThan treeView.outerHeight()
|
|
|
|
treeView.moveDown()
|
|
expect(treeView.scrollTop()).toBe 0
|
|
|
|
entryCount = treeView.find(".entry").length
|
|
_.times entryCount, -> treeView.moveDown()
|
|
expect(treeView.scrollBottom()).toBe treeView.prop('scrollHeight')
|
|
|
|
_.times entryCount, -> treeView.moveUp()
|
|
expect(treeView.scrollTop()).toBe 0
|
|
|
|
describe "tree-view:expand-directory", ->
|
|
describe "when a directory entry is selected", ->
|
|
it "expands the current directory", ->
|
|
subdir = treeView.root.find('.directory:first')
|
|
subdir.click()
|
|
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
treeView.trigger 'tree-view:expand-directory'
|
|
expect(subdir).toHaveClass 'expanded'
|
|
|
|
describe "when a file entry is selected", ->
|
|
it "does nothing", ->
|
|
treeView.root.find('.file').click()
|
|
treeView.trigger 'tree-view:expand-directory'
|
|
|
|
describe "tree-view:collapse-directory", ->
|
|
subdir = null
|
|
|
|
beforeEach ->
|
|
subdir = treeView.root.find('> .entries > .directory').eq(0).view()
|
|
subdir.expand()
|
|
|
|
describe "when an expanded directory is selected", ->
|
|
it "collapses the selected directory", ->
|
|
expect(subdir).toHaveClass 'expanded'
|
|
|
|
subdir.click()
|
|
treeView.trigger 'tree-view:collapse-directory'
|
|
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
expect(treeView.root).toHaveClass 'expanded'
|
|
|
|
describe "when a collapsed directory is selected", ->
|
|
it "collapses and selects the selected directory's parent directory", ->
|
|
subdir.find('.directory').click()
|
|
treeView.trigger 'tree-view:collapse-directory'
|
|
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
expect(subdir).toHaveClass 'selected'
|
|
expect(treeView.root).toHaveClass 'expanded'
|
|
|
|
describe "when collapsed root directory is selected", ->
|
|
it "does not raise an error", ->
|
|
treeView.root.collapse()
|
|
treeView.selectEntry(treeView.root)
|
|
|
|
treeView.trigger 'tree-view:collapse-directory'
|
|
|
|
describe "when a file is selected", ->
|
|
it "collapses and selects the selected file's parent directory", ->
|
|
subdir.find('.file').click()
|
|
treeView.trigger 'tree-view:collapse-directory'
|
|
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
expect(subdir).toHaveClass 'selected'
|
|
expect(treeView.root).toHaveClass 'expanded'
|
|
|
|
describe "tree-view:open-selected-entry", ->
|
|
describe "when a file is selected", ->
|
|
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')
|
|
|
|
describe "when a directory is selected", ->
|
|
it "expands or collapses the directory", ->
|
|
subdir = treeView.root.find('.directory').first()
|
|
subdir.click()
|
|
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
treeView.root.trigger 'tree-view:open-selected-entry'
|
|
expect(subdir).toHaveClass 'expanded'
|
|
treeView.root.trigger 'tree-view:open-selected-entry'
|
|
expect(subdir).not.toHaveClass 'expanded'
|
|
|
|
describe "when nothing is selected", ->
|
|
it "does nothing", ->
|
|
treeView.root.trigger 'tree-view:open-selected-entry'
|
|
expect(rootView.activeEditor()).toBeUndefined()
|
|
|
|
describe "file modification", ->
|
|
[dirView, fileView, rootDirPath, dirPath, filePath] = []
|
|
|
|
beforeEach ->
|
|
treeView.deactivate()
|
|
|
|
rootDirPath = "/tmp/atom-tests"
|
|
fs.remove(rootDirPath) if fs.exists(rootDirPath)
|
|
|
|
dirPath = fs.join(rootDirPath, "test-dir")
|
|
filePath = fs.join(dirPath, "test-file.txt")
|
|
fs.makeDirectory(rootDirPath)
|
|
fs.makeDirectory(dirPath)
|
|
fs.write(filePath, "doesn't matter")
|
|
|
|
rootView = new RootView(rootDirPath)
|
|
project = rootView.project
|
|
treeView = new TreeView(rootView)
|
|
treeView.root = treeView.root
|
|
dirView = treeView.root.entries.find('.directory:contains(test-dir)').view()
|
|
dirView.expand()
|
|
fileView = treeView.find('.file:contains(test-file.txt)').view()
|
|
|
|
afterEach ->
|
|
fs.remove(rootDirPath) if fs.exists(rootDirPath)
|
|
|
|
describe "tree-view:add", ->
|
|
addDialog = null
|
|
|
|
beforeEach ->
|
|
fileView.click()
|
|
treeView.trigger "tree-view:add"
|
|
addDialog = rootView.find(".tree-view-dialog").view()
|
|
|
|
describe "when a file is selected", ->
|
|
it "opens an add dialog with the file's current directory path populated", ->
|
|
expect(addDialog).toExist()
|
|
expect(addDialog.prompt.text()).toBeTruthy()
|
|
expect(project.relativize(dirPath)).toMatch(/[^\/]$/)
|
|
expect(addDialog.miniEditor.getText()).toBe(project.relativize(dirPath) + "/")
|
|
expect(addDialog.miniEditor.getCursorBufferPosition().column).toBe addDialog.miniEditor.getText().length
|
|
expect(addDialog.miniEditor.isFocused).toBeTruthy()
|
|
|
|
describe "when parent directory of the selected file changes", ->
|
|
it "active file is still shown as selected in the tree view", ->
|
|
directoryChangeHandler = jasmine.createSpy("directory-change")
|
|
dirView.on "tree-view:directory-modified", directoryChangeHandler
|
|
|
|
dirView.directory.trigger 'contents-change'
|
|
expect(directoryChangeHandler).toHaveBeenCalled()
|
|
expect(treeView.find('.selected').text()).toBe fs.base(filePath)
|
|
|
|
describe "when the path without a trailing '/' is changed and confirmed", ->
|
|
describe "when no file exists at that location", ->
|
|
it "add a file, closes the dialog and selects the file in the tree-view", ->
|
|
newPath = fs.join(dirPath, "new-test-file.txt")
|
|
addDialog.miniEditor.insertText(fs.base(newPath))
|
|
addDialog.trigger 'tree-view:confirm'
|
|
expect(fs.exists(newPath)).toBeTruthy()
|
|
expect(fs.isFile(newPath)).toBeTruthy()
|
|
expect(addDialog.parent()).not.toExist()
|
|
expect(rootView.activeEditor().buffer.path).toBe newPath
|
|
|
|
waitsFor "tree view to be updated", ->
|
|
dirView.entries.find("> .file").length > 1
|
|
|
|
runs ->
|
|
expect(treeView.find('.selected').text()).toBe fs.base(newPath)
|
|
|
|
describe "when a file already exists at that location", ->
|
|
it "shows an error message and does not close the dialog", ->
|
|
newPath = fs.join(dirPath, "new-test-file.txt")
|
|
fs.write(newPath, '')
|
|
addDialog.miniEditor.insertText(fs.base(newPath))
|
|
addDialog.trigger 'tree-view:confirm'
|
|
|
|
expect(addDialog.prompt.text()).toContain 'Error'
|
|
expect(addDialog.prompt.text()).toContain 'already exists'
|
|
expect(addDialog.prompt).toHaveClass('error')
|
|
expect(addDialog.hasParent()).toBeTruthy()
|
|
|
|
describe "when the path with a trailing '/' is changed and confirmed", ->
|
|
describe "when no file or directory exists at the given path", ->
|
|
it "adds a directory and closes the dialog", ->
|
|
newPath = fs.join(dirPath, "new-dir")
|
|
addDialog.miniEditor.insertText("new-dir/")
|
|
addDialog.trigger 'tree-view:confirm'
|
|
expect(fs.exists(newPath)).toBeTruthy()
|
|
expect(fs.isDirectory(newPath)).toBeTruthy()
|
|
expect(addDialog.parent()).not.toExist()
|
|
expect(rootView.activeEditor().buffer.path).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", ->
|
|
newPath = fs.join(dirPath, "new-dir")
|
|
fs.makeDirectory(newPath)
|
|
addDialog.miniEditor.insertText("new-dir/")
|
|
addDialog.trigger 'tree-view:confirm'
|
|
|
|
expect(addDialog.prompt.text()).toContain 'Error'
|
|
expect(addDialog.prompt.text()).toContain 'already exists'
|
|
expect(addDialog.prompt).toHaveClass('error')
|
|
expect(addDialog.hasParent()).toBeTruthy()
|
|
|
|
describe "when 'tree-view:cancel' is triggered on the add dialog", ->
|
|
it "removes the dialog and focuses the tree view", ->
|
|
treeView.attachToDom()
|
|
addDialog.trigger 'tree-view:cancel'
|
|
expect(addDialog.parent()).not.toExist()
|
|
expect(treeView).toMatchSelector(':focus')
|
|
|
|
describe "when the add dialog's editor loses focus", ->
|
|
it "removes the dialog and focuses root view", ->
|
|
rootView.attachToDom()
|
|
rootView.focus()
|
|
expect(addDialog.parent()).not.toExist()
|
|
expect(rootView.activeEditor().isFocused).toBeTruthy()
|
|
|
|
describe "when a directory is selected", ->
|
|
it "opens an add dialog with the directory's path populated", ->
|
|
addDialog.cancel()
|
|
dirView.click()
|
|
treeView.trigger "tree-view:add"
|
|
addDialog = rootView.find(".tree-view-dialog").view()
|
|
|
|
expect(addDialog).toExist()
|
|
expect(addDialog.prompt.text()).toBeTruthy()
|
|
expect(project.relativize(dirPath)).toMatch(/[^\/]$/)
|
|
expect(addDialog.miniEditor.getText()).toBe(project.relativize(dirPath) + "/")
|
|
expect(addDialog.miniEditor.getCursorBufferPosition().column).toBe addDialog.miniEditor.getText().length
|
|
expect(addDialog.miniEditor.isFocused).toBeTruthy()
|
|
|
|
describe "when the root directory is selected", ->
|
|
it "opens an add dialog with no path populated", ->
|
|
addDialog.cancel()
|
|
treeView.root.click()
|
|
treeView.trigger "tree-view:add"
|
|
addDialog = rootView.find(".tree-view-dialog").view()
|
|
|
|
expect(addDialog.miniEditor.getText().length).toBe 0
|
|
|
|
describe "tree-view:move", ->
|
|
describe "when a file is selected", ->
|
|
moveDialog = null
|
|
|
|
beforeEach ->
|
|
fileView.click()
|
|
treeView.trigger "tree-view:move"
|
|
moveDialog = rootView.find(".tree-view-dialog").view()
|
|
|
|
it "opens a move dialog with the file's current path (excluding extension) populated", ->
|
|
extension = fs.extension(filePath)
|
|
fileNameWithoutExtension = fs.base(filePath, extension)
|
|
expect(moveDialog).toExist()
|
|
expect(moveDialog.prompt.text()).toBe "Enter the new path for the file:"
|
|
expect(moveDialog.miniEditor.getText()).toBe(project.relativize(filePath))
|
|
expect(moveDialog.miniEditor.getSelectedText()).toBe fs.base(fileNameWithoutExtension)
|
|
expect(moveDialog.miniEditor.isFocused).toBeTruthy()
|
|
|
|
describe "when the path is changed and confirmed", ->
|
|
describe "when all the directories along the new path exist", ->
|
|
it "moves the file, updates the tree view, and closes the dialog", ->
|
|
runs ->
|
|
newPath = fs.join(rootDirPath, 'renamed-test-file.txt')
|
|
moveDialog.miniEditor.setText(newPath)
|
|
|
|
moveDialog.trigger 'tree-view:confirm'
|
|
|
|
expect(fs.exists(newPath)).toBeTruthy()
|
|
expect(fs.exists(filePath)).toBeFalsy()
|
|
expect(moveDialog.parent()).not.toExist()
|
|
|
|
waitsFor "tree view to update", ->
|
|
treeView.root.find('> .entries > .file:contains(renamed-test-file.txt)').length > 0
|
|
|
|
runs ->
|
|
dirView = treeView.root.entries.find('.directory:contains(test-dir)').view()
|
|
dirView.expand()
|
|
expect(dirView.entries.children().length).toBe 0
|
|
|
|
describe "when the directories along the new path don't exist", ->
|
|
it "creates the target directory before moving the file", ->
|
|
runs ->
|
|
newPath = fs.join(rootDirPath, 'new-directory', 'renamed-test-file.txt')
|
|
moveDialog.miniEditor.setText(newPath)
|
|
|
|
moveDialog.trigger 'tree-view:confirm'
|
|
|
|
expect(fs.exists(newPath)).toBeTruthy()
|
|
expect(fs.exists(filePath)).toBeFalsy()
|
|
|
|
describe "when a file or directory already exists at the target path", ->
|
|
it "shows an error message and does not close the dialog", ->
|
|
runs ->
|
|
fs.write(fs.join(rootDirPath, 'target.txt'), '')
|
|
newPath = fs.join(rootDirPath, 'target.txt')
|
|
moveDialog.miniEditor.setText(newPath)
|
|
|
|
moveDialog.trigger 'tree-view:confirm'
|
|
|
|
expect(moveDialog.prompt.text()).toContain 'Error'
|
|
expect(moveDialog.prompt.text()).toContain 'already exists'
|
|
expect(moveDialog.prompt).toHaveClass('error')
|
|
expect(moveDialog.hasParent()).toBeTruthy()
|
|
|
|
describe "when 'tree-view:cancel' is triggered on the move dialog", ->
|
|
it "removes the dialog and focuses the tree view", ->
|
|
treeView.attachToDom()
|
|
moveDialog.trigger 'tree-view:cancel'
|
|
expect(moveDialog.parent()).not.toExist()
|
|
expect(treeView).toMatchSelector(':focus')
|
|
|
|
describe "when the move dialog's editor loses focus", ->
|
|
it "removes the dialog and focuses root view", ->
|
|
rootView.attachToDom()
|
|
rootView.focus()
|
|
expect(moveDialog.parent()).not.toExist()
|
|
expect(rootView.activeEditor().isFocused).toBeTruthy()
|
|
|
|
describe "tree-view:remove", ->
|
|
it "shows the native alert dialog", ->
|
|
fileView.click()
|
|
spyOn(Native, 'alert')
|
|
treeView.trigger 'tree-view:remove'
|
|
expect(Native.alert).toHaveBeenCalled()
|
|
|
|
describe "file system events", ->
|
|
temporaryFilePath = null
|
|
|
|
beforeEach ->
|
|
temporaryFilePath = fs.join(require.resolve('fixtures'), 'temporary')
|
|
if fs.exists(temporaryFilePath)
|
|
fs.remove(temporaryFilePath)
|
|
waits(20)
|
|
|
|
afterEach ->
|
|
fs.remove(temporaryFilePath) if fs.exists(temporaryFilePath)
|
|
|
|
describe "when a file is added or removed in an expanded directory", ->
|
|
it "updates the directory view to display the directory's new contents", ->
|
|
entriesCountBefore = null
|
|
|
|
runs ->
|
|
expect(fs.exists(temporaryFilePath)).toBeFalsy()
|
|
entriesCountBefore = treeView.root.entries.find('.entry').length
|
|
fs.write temporaryFilePath, 'hi'
|
|
|
|
waitsFor "directory view contens to refresh", ->
|
|
treeView.root.entries.find('.entry').length == entriesCountBefore + 1
|
|
|
|
runs ->
|
|
expect(treeView.root.entries.find('.entry').length).toBe entriesCountBefore + 1
|
|
expect(treeView.root.entries.find('.file:contains(temporary)')).toExist()
|
|
fs.remove(temporaryFilePath)
|
|
|
|
waitsFor "directory view contens to refresh", ->
|
|
treeView.root.entries.find('.entry').length == entriesCountBefore
|