pulsar/spec/workspace-spec.coffee

503 lines
19 KiB
CoffeeScript
Raw Normal View History

path = require 'path'
temp = require 'temp'
Workspace = require '../src/workspace'
2014-09-17 03:44:03 +04:00
{View} = require '../src/space-pen-extensions'
2014-10-04 02:23:54 +04:00
describe "Workspace", ->
workspace = null
beforeEach ->
atom.project.setPaths([atom.project.resolve('dir')])
atom.workspace = workspace = new Workspace
describe "::open(uri, options)", ->
openEvents = null
beforeEach ->
openEvents = []
workspace.onDidOpen (event) -> openEvents.push(event)
spyOn(workspace.getActivePane(), 'activate').andCallThrough()
describe "when the 'searchAllPanes' option is false (default)", ->
describe "when called without a uri", ->
it "adds and activates an empty editor on the active pane", ->
[editor1, editor2] = []
waitsForPromise ->
workspace.open().then (editor) -> editor1 = editor
runs ->
expect(editor1.getPath()).toBeUndefined()
expect(workspace.getActivePane().items).toEqual [editor1]
expect(workspace.getActivePaneItem()).toBe editor1
expect(workspace.getActivePane().activate).toHaveBeenCalled()
expect(openEvents).toEqual [{uri: undefined, pane: workspace.getActivePane(), item: editor1, index: 0}]
openEvents = []
waitsForPromise ->
workspace.open().then (editor) -> editor2 = editor
runs ->
expect(editor2.getPath()).toBeUndefined()
expect(workspace.getActivePane().items).toEqual [editor1, editor2]
expect(workspace.getActivePaneItem()).toBe editor2
expect(workspace.getActivePane().activate).toHaveBeenCalled()
expect(openEvents).toEqual [{uri: undefined, pane: workspace.getActivePane(), item: editor2, index: 1}]
describe "when called with a uri", ->
describe "when the active pane already has an editor for the given uri", ->
it "activates the existing editor on the active pane", ->
editor = null
editor1 = null
editor2 = null
waitsForPromise ->
workspace.open('a').then (o) ->
editor1 = o
workspace.open('b').then (o) ->
editor2 = o
workspace.open('a').then (o) ->
editor = o
runs ->
expect(editor).toBe editor1
expect(workspace.getActivePaneItem()).toBe editor
expect(workspace.getActivePane().activate).toHaveBeenCalled()
expect(openEvents).toEqual [
{
uri: atom.project.resolve('a')
item: editor1
pane: atom.workspace.getActivePane()
index: 0
}
{
uri: atom.project.resolve('b')
item: editor2
pane: atom.workspace.getActivePane()
index: 1
}
{
uri: atom.project.resolve('a')
item: editor1
pane: atom.workspace.getActivePane()
index: 0
}
]
describe "when the active pane does not have an editor for the given uri", ->
it "adds and activates a new editor for the given path on the active pane", ->
editor = null
waitsForPromise ->
workspace.open('a').then (o) -> editor = o
runs ->
2014-02-19 06:57:45 +04:00
expect(editor.getUri()).toBe atom.project.resolve('a')
expect(workspace.getActivePaneItem()).toBe editor
expect(workspace.getActivePane().items).toEqual [editor]
expect(workspace.getActivePane().activate).toHaveBeenCalled()
describe "when the 'searchAllPanes' option is true", ->
describe "when an editor for the given uri is already open on an inactive pane", ->
2014-04-24 03:19:43 +04:00
it "activates the existing editor on the inactive pane, then activates that pane", ->
editor1 = null
editor2 = null
pane1 = workspace.getActivePane()
pane2 = workspace.getActivePane().splitRight()
waitsForPromise ->
pane1.activate()
workspace.open('a').then (o) -> editor1 = o
waitsForPromise ->
pane2.activate()
workspace.open('b').then (o) -> editor2 = o
runs ->
expect(workspace.getActivePaneItem()).toBe editor2
waitsForPromise ->
workspace.open('a', searchAllPanes: true)
runs ->
expect(workspace.getActivePane()).toBe pane1
expect(workspace.getActivePaneItem()).toBe editor1
describe "when no editor for the given uri is open in any pane", ->
it "opens an editor for the given uri in the active pane", ->
editor = null
waitsForPromise ->
workspace.open('a', searchAllPanes: true).then (o) -> editor = o
runs ->
expect(workspace.getActivePaneItem()).toBe editor
describe "when the 'split' option is set", ->
describe "when the 'split' option is 'left'", ->
it "opens the editor in the leftmost pane of the current pane axis", ->
pane1 = workspace.getActivePane()
pane2 = pane1.splitRight()
expect(workspace.getActivePane()).toBe pane2
editor = null
waitsForPromise ->
workspace.open('a', split: 'left').then (o) -> editor = o
runs ->
expect(workspace.getActivePane()).toBe pane1
expect(pane1.items).toEqual [editor]
expect(pane2.items).toEqual []
2014-02-04 22:07:17 +04:00
# Focus right pane and reopen the file on the left
waitsForPromise ->
pane2.focus()
workspace.open('a', split: 'left').then (o) -> editor = o
runs ->
expect(workspace.getActivePane()).toBe pane1
2014-02-04 22:07:17 +04:00
expect(pane1.items).toEqual [editor]
expect(pane2.items).toEqual []
2014-05-05 20:16:40 +04:00
describe "when a pane axis is the leftmost sibling of the current pane", ->
it "opens the new item in the current pane", ->
editor = null
pane1 = workspace.getActivePane()
pane2 = pane1.splitLeft()
pane3 = pane2.splitDown()
pane1.activate()
expect(workspace.getActivePane()).toBe pane1
waitsForPromise ->
workspace.open('a', split: 'left').then (o) -> editor = o
runs ->
expect(workspace.getActivePane()).toBe pane1
expect(pane1.items).toEqual [editor]
2014-02-04 22:07:17 +04:00
describe "when the 'split' option is 'right'", ->
it "opens the editor in the rightmost pane of the current pane axis", ->
editor = null
pane1 = workspace.getActivePane()
2014-02-04 22:07:17 +04:00
pane2 = null
waitsForPromise ->
workspace.open('a', split: 'right').then (o) -> editor = o
runs ->
2014-02-04 22:07:17 +04:00
pane2 = workspace.getPanes().filter((p) -> p != pane1)[0]
expect(workspace.getActivePane()).toBe pane2
expect(pane1.items).toEqual []
2014-02-04 22:07:17 +04:00
expect(pane2.items).toEqual [editor]
2014-02-04 22:07:17 +04:00
# Focus right pane and reopen the file on the right
waitsForPromise ->
2014-02-04 22:07:17 +04:00
pane1.focus()
workspace.open('a', split: 'right').then (o) -> editor = o
runs ->
expect(workspace.getActivePane()).toBe pane2
expect(pane1.items).toEqual []
2014-02-04 22:07:17 +04:00
expect(pane2.items).toEqual [editor]
2014-05-05 20:16:40 +04:00
describe "when a pane axis is the rightmost sibling of the current pane", ->
it "opens the new item in a new pane split to the right of the current pane", ->
editor = null
pane1 = workspace.getActivePane()
pane2 = pane1.splitRight()
pane3 = pane2.splitDown()
pane1.activate()
expect(workspace.getActivePane()).toBe pane1
pane4 = null
waitsForPromise ->
workspace.open('a', split: 'right').then (o) -> editor = o
runs ->
pane4 = workspace.getPanes().filter((p) -> p != pane1)[0]
expect(workspace.getActivePane()).toBe pane4
expect(pane4.items).toEqual [editor]
expect(workspace.paneContainer.root.children[0]).toBe pane1
expect(workspace.paneContainer.root.children[1]).toBe pane4
2014-02-13 04:56:00 +04:00
describe "when passed a path that matches a custom opener", ->
it "returns the resource returned by the custom opener", ->
fooOpener = (pathToOpen, options) -> { foo: pathToOpen, options } if pathToOpen?.match(/\.foo/)
barOpener = (pathToOpen) -> { bar: pathToOpen } if pathToOpen?.match(/^bar:\/\//)
workspace.addOpener(fooOpener)
workspace.addOpener(barOpener)
2014-02-13 04:56:00 +04:00
waitsForPromise ->
2014-02-14 01:55:37 +04:00
pathToOpen = atom.project.resolve('a.foo')
2014-02-13 04:56:00 +04:00
workspace.open(pathToOpen, hey: "there").then (item) ->
expect(item).toEqual { foo: pathToOpen, options: {hey: "there"} }
waitsForPromise ->
workspace.open("bar://baz").then (item) ->
expect(item).toEqual { bar: "bar://baz" }
it "notifies ::onDidAddTextEditor observers", ->
absolutePath = require.resolve('./fixtures/dir/a')
newEditorHandler = jasmine.createSpy('newEditorHandler')
workspace.onDidAddTextEditor newEditorHandler
editor = null
waitsForPromise ->
workspace.open(absolutePath).then (e) -> editor = e
runs ->
expect(newEditorHandler.argsForCall[0][0].textEditor).toBe editor
describe "::reopenItem()", ->
it "opens the uri associated with the last closed pane that isn't currently open", ->
pane = workspace.getActivePane()
waitsForPromise ->
workspace.open('a').then ->
workspace.open('b').then ->
workspace.open('file1').then ->
workspace.open()
runs ->
# does not reopen items with no uri
expect(workspace.getActivePaneItem().getUri()).toBeUndefined()
pane.destroyActiveItem()
waitsForPromise ->
workspace.reopenItem()
runs ->
expect(workspace.getActivePaneItem().getUri()).not.toBeUndefined()
# destroy all items
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('file1')
pane.destroyActiveItem()
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('b')
pane.destroyActiveItem()
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('a')
pane.destroyActiveItem()
# reopens items with uris
expect(workspace.getActivePaneItem()).toBeUndefined()
waitsForPromise ->
workspace.reopenItem()
runs ->
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('a')
# does not reopen items that are already open
waitsForPromise ->
workspace.open('b')
runs ->
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('b')
waitsForPromise ->
workspace.reopenItem()
runs ->
expect(workspace.getActivePaneItem().getUri()).toBe atom.project.resolve('file1')
describe "::increase/decreaseFontSize()", ->
it "increases/decreases the font size without going below 1", ->
atom.config.set('editor.fontSize', 1)
workspace.increaseFontSize()
expect(atom.config.get('editor.fontSize')).toBe 2
workspace.increaseFontSize()
expect(atom.config.get('editor.fontSize')).toBe 3
workspace.decreaseFontSize()
expect(atom.config.get('editor.fontSize')).toBe 2
workspace.decreaseFontSize()
expect(atom.config.get('editor.fontSize')).toBe 1
workspace.decreaseFontSize()
expect(atom.config.get('editor.fontSize')).toBe 1
describe "::openLicense()", ->
it "opens the license as plain-text in a buffer", ->
waitsForPromise -> workspace.openLicense()
runs -> expect(workspace.getActivePaneItem().getText()).toMatch /Copyright/
describe "::observeTextEditors()", ->
it "invokes the observer with current and future text editors", ->
observed = []
waitsForPromise -> workspace.open()
waitsForPromise -> workspace.open()
waitsForPromise -> workspace.openLicense()
runs ->
workspace.observeTextEditors (editor) -> observed.push(editor)
waitsForPromise -> workspace.open()
expect(observed).toEqual workspace.getTextEditors()
describe "when an editor is destroyed", ->
it "removes the editor", ->
editor = null
waitsForPromise ->
workspace.open("a").then (e) -> editor = e
runs ->
expect(workspace.getTextEditors()).toHaveLength 1
editor.destroy()
expect(workspace.getTextEditors()).toHaveLength 0
it "stores the active grammars used by all the open editors", ->
2014-06-24 03:55:44 +04:00
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
waitsForPromise ->
atom.packages.activatePackage('language-todo')
waitsForPromise ->
atom.workspace.open('sample.coffee')
2014-06-24 03:55:44 +04:00
runs ->
atom.workspace.getActiveEditor().setText """
i = /test/; #FIXME
"""
2014-06-24 03:55:44 +04:00
state = atom.workspace.serialize()
expect(state.packagesWithActiveGrammars).toEqual ['language-coffee-script', 'language-javascript', 'language-todo']
jsPackage = atom.packages.getLoadedPackage('language-javascript')
coffeePackage = atom.packages.getLoadedPackage('language-coffee-script')
spyOn(jsPackage, 'loadGrammarsSync')
spyOn(coffeePackage, 'loadGrammarsSync')
workspace2 = Workspace.deserialize(state)
2014-06-24 04:41:33 +04:00
expect(jsPackage.loadGrammarsSync.callCount).toBe 1
expect(coffeePackage.loadGrammarsSync.callCount).toBe 1
describe "document.title", ->
describe "when the project has no path", ->
it "sets the title to 'untitled'", ->
atom.project.setPath(undefined)
2014-10-14 04:48:06 +04:00
expect(document.title).toBe 'untitled - Atom'
describe "when the project has a path", ->
beforeEach ->
waitsForPromise ->
atom.workspace.open('b')
describe "when there is an active pane item", ->
it "sets the title to the pane item's title plus the project path", ->
item = atom.workspace.getActivePaneItem()
2014-10-14 04:48:06 +04:00
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
describe "when the title of the active pane item changes", ->
it "updates the window title based on the item's new title", ->
editor = atom.workspace.getActivePaneItem()
editor.buffer.setPath(path.join(temp.dir, 'hi'))
2014-10-14 04:48:06 +04:00
expect(document.title).toBe "#{editor.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
describe "when the active pane's item changes", ->
it "updates the title to the new item's title plus the project path", ->
atom.workspace.getActivePane().activateNextItem()
item = atom.workspace.getActivePaneItem()
2014-10-14 04:48:06 +04:00
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
describe "when the last pane item is removed", ->
it "updates the title to contain the project's path", ->
atom.workspace.getActivePane().destroy()
expect(atom.workspace.getActivePaneItem()).toBeUndefined()
2014-10-14 04:48:06 +04:00
expect(document.title).toBe "#{atom.project.getPaths()[0]} - Atom"
describe "when an inactive pane's item changes", ->
it "does not update the title", ->
pane = atom.workspace.getActivePane()
pane.splitRight()
initialTitle = document.title
pane.activateNextItem()
expect(document.title).toBe initialTitle
describe "when the workspace is deserialized", ->
beforeEach ->
waitsForPromise -> atom.workspace.open('a')
it "updates the title to contain the project's path", ->
document.title = null
workspace2 = atom.workspace.testSerialization()
item = atom.workspace.getActivePaneItem()
2014-10-14 04:48:06 +04:00
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
workspace2.destroy()
describe "document edited status", ->
[item1, item2] = []
beforeEach ->
waitsForPromise -> atom.workspace.open('a')
waitsForPromise -> atom.workspace.open('b')
runs ->
[item1, item2] = atom.workspace.getPaneItems()
spyOn(atom, 'setDocumentEdited')
it "calls atom.setDocumentEdited when the active item changes", ->
expect(atom.workspace.getActivePaneItem()).toBe item2
item1.insertText('a')
expect(item1.isModified()).toBe true
atom.workspace.getActivePane().activateNextItem()
expect(atom.setDocumentEdited).toHaveBeenCalledWith(true)
it "calls atom.setDocumentEdited when the active item's modified status changes", ->
expect(atom.workspace.getActivePaneItem()).toBe item2
item2.insertText('a')
advanceClock(item2.getBuffer().getStoppedChangingDelay())
expect(item2.isModified()).toBe true
expect(atom.setDocumentEdited).toHaveBeenCalledWith(true)
item2.undo()
advanceClock(item2.getBuffer().getStoppedChangingDelay())
expect(item2.isModified()).toBe false
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
describe "adding panels", ->
class TestPanel
constructior: ->
describe '::addLeftPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addLeftPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addRightPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addRightPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addTopPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addTopPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addBottomPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addBottomPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
2014-11-04 22:43:51 +03:00
describe '::addModalPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addModalPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})