Don't use atom.{notifications,config,deserializers,confirm} in Pane

Still need to get rid of one use of showSaveDialogSync
This commit is contained in:
Max Brunsfeld
2015-10-09 17:18:26 -07:00
parent b467c83e76
commit 369f3d2648
8 changed files with 127 additions and 138 deletions

View File

@@ -2,6 +2,16 @@ PaneContainer = require '../src/pane-container'
Pane = require '../src/pane'
describe "PaneContainer", ->
[confirm, params] = []
beforeEach ->
confirm = jasmine.createSpy('confirm').andReturn(0)
params = {
config: atom.config,
confirm: confirm,
deserializerManager: atom.deserializers
}
describe "serialization", ->
[containerA, pane1A, pane2A, pane3A] = []
@@ -12,7 +22,7 @@ describe "PaneContainer", ->
@deserialize: -> new this
serialize: -> deserializer: 'Item'
containerA = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerA = new PaneContainer(params)
pane1A = containerA.getActivePane()
pane1A.addItem(new Item)
pane2A = pane1A.splitRight(items: [new Item])
@@ -22,7 +32,7 @@ describe "PaneContainer", ->
it "preserves the focused pane across serialization", ->
expect(pane3A.focused).toBe true
containerB = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerB = new PaneContainer(params)
containerB.deserialize(containerA.serialize(), atom.deserializers)
[pane1B, pane2B, pane3B] = containerB.getPanes()
expect(pane3B.focused).toBe true
@@ -31,7 +41,7 @@ describe "PaneContainer", ->
pane3A.activate()
expect(containerA.getActivePane()).toBe pane3A
containerB = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerB = new PaneContainer(params)
containerB.deserialize(containerA.serialize(), atom.deserializers)
[pane1B, pane2B, pane3B] = containerB.getPanes()
expect(containerB.getActivePane()).toBe pane3B
@@ -40,7 +50,7 @@ describe "PaneContainer", ->
pane3A.activate()
state = containerA.serialize()
state.activePaneId = -22
containerB = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerB = new PaneContainer(params)
containerB.deserialize(state, atom.deserializers)
expect(containerB.getActivePane()).toBe containerB.getPanes()[0]
@@ -51,7 +61,7 @@ describe "PaneContainer", ->
describe "if the 'core.destroyEmptyPanes' config option is false (the default)", ->
it "leaves the empty panes intact", ->
state = containerA.serialize()
containerB = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerB = new PaneContainer(params)
containerB.deserialize(state, atom.deserializers)
[leftPane, column] = containerB.getRoot().getChildren()
[topPane, bottomPane] = column.getChildren()
@@ -65,7 +75,7 @@ describe "PaneContainer", ->
atom.config.set('core.destroyEmptyPanes', true)
state = containerA.serialize()
containerB = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
containerB = new PaneContainer(params)
containerB.deserialize(state, atom.deserializers)
[leftPane, rightPane] = containerB.getRoot().getChildren()
@@ -73,7 +83,7 @@ describe "PaneContainer", ->
expect(rightPane.getItems().length).toBe 1
it "does not allow the root pane to be destroyed", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
container.getRoot().destroy()
expect(container.getRoot()).toBeDefined()
expect(container.getRoot().isDestroyed()).toBe false
@@ -82,7 +92,7 @@ describe "PaneContainer", ->
[container, pane1, pane2] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
pane1 = container.getRoot()
it "returns the first pane if no pane has been made active", ->
@@ -111,7 +121,7 @@ describe "PaneContainer", ->
[container, pane1, pane2, observed] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
container.getRoot().addItems([new Object, new Object])
container.getRoot().splitRight(items: [new Object, new Object])
[pane1, pane2] = container.getPanes()
@@ -131,7 +141,7 @@ describe "PaneContainer", ->
describe "::observePanes()", ->
it "invokes observers with all current and future panes", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
container.getRoot().splitRight()
[pane1, pane2] = container.getPanes()
@@ -145,7 +155,7 @@ describe "PaneContainer", ->
describe "::observePaneItems()", ->
it "invokes observers with all current and future pane items", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
container.getRoot().addItems([new Object, new Object])
container.getRoot().splitRight(items: [new Object])
[pane1, pane2] = container.getPanes()
@@ -165,27 +175,27 @@ describe "PaneContainer", ->
shouldPromptToSave: -> true
getURI: -> 'test'
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
container.getRoot().splitRight()
[pane1, pane2] = container.getPanes()
pane1.addItem(new TestItem)
pane2.addItem(new TestItem)
it "returns true if the user saves all modified files when prompted", ->
spyOn(atom, "confirm").andReturn(0)
confirm.andReturn(0)
saved = container.confirmClose()
expect(saved).toBeTruthy()
expect(atom.confirm).toHaveBeenCalled()
expect(confirm).toHaveBeenCalled()
it "returns false if the user cancels saving any modified file", ->
spyOn(atom, "confirm").andReturn(1)
confirm.andReturn(1)
saved = container.confirmClose()
expect(saved).toBeFalsy()
expect(atom.confirm).toHaveBeenCalled()
expect(confirm).toHaveBeenCalled()
describe "::onDidAddPane(callback)", ->
it "invokes the given callback when panes are added", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
events = []
container.onDidAddPane (event) -> events.push(event)
@@ -202,7 +212,7 @@ describe "PaneContainer", ->
destroy: -> @_isDestroyed = true
isDestroyed: -> @_isDestroyed
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
events = []
container.onWillDestroyPane (event) ->
itemsDestroyed = (item.isDestroyed() for item in event.pane.getItems())
@@ -218,7 +228,7 @@ describe "PaneContainer", ->
describe "::onDidDestroyPane(callback)", ->
it "invokes the given callback when panes are destroyed", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
events = []
container.onDidDestroyPane (event) -> events.push(event)
@@ -233,7 +243,7 @@ describe "PaneContainer", ->
describe "::onWillDestroyPaneItem() and ::onDidDestroyPaneItem", ->
it "invokes the given callbacks when an item will be destroyed on any pane", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
pane1 = container.getRoot()
item1 = new Object
item2 = new Object
@@ -260,7 +270,7 @@ describe "PaneContainer", ->
describe "::saveAll()", ->
it "saves all open pane items", ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(params)
pane1 = container.getRoot()
pane2 = pane1.splitRight()

View File

@@ -1,10 +1,11 @@
{extend} = require 'underscore-plus'
{Emitter} = require 'event-kit'
Pane = require '../src/pane'
PaneAxis = require '../src/pane-axis'
PaneContainer = require '../src/pane-container'
describe "Pane", ->
deserializerDisposable = null
[confirm, deserializerDisposable] = []
class Item
@deserialize: ({name, uri}) -> new this(name, uri)
@@ -19,18 +20,27 @@ describe "Pane", ->
isDestroyed: -> @destroyed
beforeEach ->
confirm = jasmine.createSpy('confirm')
deserializerDisposable = atom.deserializers.add(Item)
afterEach ->
deserializerDisposable.dispose()
paneParams = (params) ->
extend({
confirm: confirm,
config: atom.config,
deserializerManager: atom.deserializers,
notificationManager: atom.notifications
}, params)
describe "construction", ->
it "sets the active item to the first item", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
it "compacts the items array", ->
pane = new Pane(items: [undefined, new Item("A"), null, new Item("B")])
pane = new Pane(paneParams(items: [undefined, new Item("A"), null, new Item("B")]))
expect(pane.getItems().length).toBe 2
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
@@ -38,7 +48,7 @@ describe "Pane", ->
[container, pane1, pane2] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(config: atom.config, confirm: confirm)
container.getActivePane().splitRight()
[pane1, pane2] = container.getPanes()
@@ -76,14 +86,14 @@ describe "Pane", ->
describe "::addItem(item, index)", ->
it "adds the item at the given index", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
[item1, item2] = pane.getItems()
item3 = new Item("C")
pane.addItem(item3, 1)
expect(pane.getItems()).toEqual [item1, item3, item2]
it "adds the item after the active item if no index is provided", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.activateItem(item2)
item4 = new Item("D")
@@ -91,13 +101,13 @@ describe "Pane", ->
expect(pane.getItems()).toEqual [item1, item2, item4, item3]
it "sets the active item after adding the first item", ->
pane = new Pane
pane = new Pane(paneParams())
item = new Item("A")
pane.addItem(item)
expect(pane.getActiveItem()).toBe item
it "invokes ::onDidAddItem() observers", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
events = []
pane.onDidAddItem (event) -> events.push(event)
@@ -107,14 +117,14 @@ describe "Pane", ->
it "throws an exception if the item is already present on a pane", ->
item = new Item("A")
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(config: atom.config, confirm: confirm)
pane1 = container.getActivePane()
pane1.addItem(item)
pane2 = pane1.splitRight()
expect(-> pane2.addItem(item)).toThrow()
it "throws an exception if the item isn't an object", ->
pane = new Pane(items: [])
pane = new Pane(paneParams(items: []))
expect(-> pane.addItem(null)).toThrow()
expect(-> pane.addItem('foo')).toThrow()
expect(-> pane.addItem(1)).toThrow()
@@ -123,7 +133,7 @@ describe "Pane", ->
pane = null
beforeEach ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
it "changes the active item to the current item", ->
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
@@ -144,7 +154,7 @@ describe "Pane", ->
describe "::activateNextItem() and ::activatePreviousItem()", ->
it "sets the active item to the next/previous item, looping around at either end", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
expect(pane.getActiveItem()).toBe item1
@@ -159,7 +169,7 @@ describe "Pane", ->
describe "::moveItemRight() and ::moveItemLeft()", ->
it "moves the active item to the right and left, without looping around at either end", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.activateItemAtIndex(0)
@@ -177,7 +187,7 @@ describe "Pane", ->
describe "::activateItemAtIndex(index)", ->
it "activates the item at the given index", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.activateItemAtIndex(2)
expect(pane.getActiveItem()).toBe item3
@@ -196,7 +206,7 @@ describe "Pane", ->
[pane, item1, item2, item3] = []
beforeEach ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
it "removes the item from the items list and destroyes it", ->
@@ -260,7 +270,7 @@ describe "Pane", ->
describe "when the item has a uri", ->
it "saves the item before destroying it", ->
itemURI = "test"
spyOn(atom, 'confirm').andReturn(0)
confirm.andReturn(0)
pane.destroyItem(item1)
expect(item1.save).toHaveBeenCalled()
@@ -272,7 +282,7 @@ describe "Pane", ->
itemURI = null
spyOn(atom, 'showSaveDialogSync').andReturn("/selected/path")
spyOn(atom, 'confirm').andReturn(0)
confirm.andReturn(0)
pane.destroyItem(item1)
expect(atom.showSaveDialogSync).toHaveBeenCalled()
@@ -282,7 +292,7 @@ describe "Pane", ->
describe "if the [Don't Save] option is selected", ->
it "removes and destroys the item without saving it", ->
spyOn(atom, 'confirm').andReturn(2)
confirm.andReturn(2)
pane.destroyItem(item1)
expect(item1.save).not.toHaveBeenCalled()
@@ -291,7 +301,7 @@ describe "Pane", ->
describe "if the [Cancel] option is selected", ->
it "does not save, remove, or destroy the item", ->
spyOn(atom, 'confirm').andReturn(1)
confirm.andReturn(1)
pane.destroyItem(item1)
expect(item1.save).not.toHaveBeenCalled()
@@ -316,19 +326,19 @@ describe "Pane", ->
describe "::destroyActiveItem()", ->
it "destroys the active item", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
activeItem = pane.getActiveItem()
pane.destroyActiveItem()
expect(activeItem.isDestroyed()).toBe true
expect(activeItem in pane.getItems()).toBe false
it "does not throw an exception if there are no more items", ->
pane = new Pane
pane = new Pane(paneParams())
pane.destroyActiveItem()
describe "::destroyItems()", ->
it "destroys all items", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.destroyItems()
expect(item1.isDestroyed()).toBe true
@@ -338,7 +348,7 @@ describe "Pane", ->
describe "::observeItems()", ->
it "invokes the observer with all current and future items", ->
pane = new Pane(items: [new Item, new Item])
pane = new Pane(paneParams(items: [new Item, new Item]))
[item1, item2] = pane.getItems()
observed = []
@@ -351,14 +361,14 @@ describe "Pane", ->
describe "when an item emits a destroyed event", ->
it "removes it from the list of items", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.itemAtIndex(1).destroy()
expect(pane.getItems()).toEqual [item1, item3]
describe "::destroyInactiveItems()", ->
it "destroys all items but the active item", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")]))
[item1, item2, item3] = pane.getItems()
pane.activateItem(item2)
pane.destroyInactiveItems()
@@ -368,7 +378,7 @@ describe "Pane", ->
pane = null
beforeEach ->
pane = new Pane(items: [new Item("A")])
pane = new Pane(paneParams(items: [new Item("A")]))
spyOn(atom, 'showSaveDialogSync').andReturn('/selected/path')
describe "when the active item has a uri", ->
@@ -423,7 +433,7 @@ describe "Pane", ->
pane = null
beforeEach ->
pane = new Pane(items: [new Item("A")])
pane = new Pane(paneParams(items: [new Item("A")]))
spyOn(atom, 'showSaveDialogSync').andReturn('/selected/path')
describe "when the current item has a saveAs method", ->
@@ -461,7 +471,7 @@ describe "Pane", ->
describe "::itemForURI(uri)", ->
it "returns the item for which a call to .getURI() returns the given uri", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")]))
[item1, item2, item3] = pane.getItems()
item1.uri = "a"
item2.uri = "b"
@@ -473,7 +483,7 @@ describe "Pane", ->
[pane, item1, item2, item3, item4] = []
beforeEach ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")]))
[item1, item2, item3, item4] = pane.getItems()
it "moves the item to the given index and invokes ::onDidMoveItem observers", ->
@@ -502,7 +512,7 @@ describe "Pane", ->
[item1, item2, item3, item4, item5] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(config: atom.config, confirm: confirm)
pane1 = container.getActivePane()
pane1.addItems([new Item("A"), new Item("B"), new Item("C")])
pane2 = pane1.splitRight(items: [new Item("D"), new Item("E")])
@@ -555,7 +565,7 @@ describe "Pane", ->
[pane1, container] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(config: atom.config, confirm: confirm, deserializerManager: atom.deserializers)
pane1 = container.getActivePane()
pane1.addItem(new Item("A"))
@@ -655,32 +665,32 @@ describe "Pane", ->
describe "::close()", ->
it "prompts to save unsaved items before destroying the pane", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getURI = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(0)
confirm.andReturn(0)
pane.close()
expect(atom.confirm).toHaveBeenCalled()
expect(confirm).toHaveBeenCalled()
expect(item1.save).toHaveBeenCalled()
expect(pane.isDestroyed()).toBe true
it "does not destroy the pane if cancel is called", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
pane = new Pane(paneParams(items: [new Item("A"), new Item("B")]))
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getURI = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(1)
confirm.andReturn(1)
pane.close()
expect(atom.confirm).toHaveBeenCalled()
expect(confirm).toHaveBeenCalled()
expect(item1.save).not.toHaveBeenCalled()
expect(pane.isDestroyed()).toBe false
@@ -688,7 +698,7 @@ describe "Pane", ->
[container, pane1, pane2] = []
beforeEach ->
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
container = new PaneContainer(config: atom.config, confirm: confirm)
pane1 = container.root
pane1.addItems([new Item("A"), new Item("B")])
pane2 = pane1.splitRight()
@@ -735,10 +745,10 @@ describe "Pane", ->
pane = null
beforeEach ->
params =
pane = new Pane(paneParams(
items: [new Item("A", "a"), new Item("B", "b"), new Item("C", "c")]
flexScale: 2
pane = new Pane(params)
))
it "can serialize and deserialize the pane and all its items", ->
newPane = Pane.deserialize(pane.serialize(), atom)

View File

@@ -4,6 +4,7 @@ fs = require 'fs-plus'
temp = require 'temp'
TextEditor = require '../src/text-editor'
WindowEventHandler = require '../src/window-event-handler'
ipc = require 'ipc'
describe "WindowEventHandler", ->
[projectPath, windowEventHandler] = []
@@ -50,64 +51,25 @@ describe "WindowEventHandler", ->
describe "beforeunload event", ->
beforeEach ->
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
spyOn(ipc, 'send')
describe "when pane items are modified", ->
it "prompts user to save and calls atom.workspace.confirmClose", ->
editor = null
spyOn(atom.workspace, 'confirmClose').andCallThrough()
spyOn(atom, "confirm").andReturn(2)
editor = null
beforeEach ->
waitsForPromise -> atom.workspace.open("sample.js").then (o) -> editor = o
runs -> editor.insertText("I look different, I feel different.")
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
it "prompts the user to save them, and allows the unload to continue if they confirm", ->
spyOn(atom.workspace, 'confirmClose').andReturn(true)
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.workspace.confirmClose).toHaveBeenCalled()
expect(ipc.send).not.toHaveBeenCalledWith('cancel-window-close')
runs ->
editor.insertText("I look different, I feel different.")
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.workspace.confirmClose).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns true if don't save", ->
editor = null
spyOn(atom, "confirm").andReturn(2)
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
runs ->
editor.insertText("I look different, I feel different.")
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns false if dialog is canceled", ->
editor = null
spyOn(atom, "confirm").andReturn(1)
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
runs ->
editor.insertText("I look different, I feel different.")
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.confirm).toHaveBeenCalled()
describe "when the same path is modified in multiple panes", ->
it "prompts to save the item", ->
return
editor = null
filePath = path.join(temp.mkdirSync('atom-file'), 'file.txt')
fs.writeFileSync(filePath, 'hello')
spyOn(atom.workspace, 'confirmClose').andCallThrough()
spyOn(atom, 'confirm').andReturn(0)
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> editor = o
runs ->
atom.workspace.getActivePane().splitRight(copyActiveItem: true)
editor.setText('world')
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.workspace.confirmClose).toHaveBeenCalled()
expect(atom.confirm.callCount).toBe 1
expect(fs.readFileSync(filePath, 'utf8')).toBe 'world'
it "cancels the unload if the user selects cancel", ->
spyOn(atom.workspace, 'confirmClose').andReturn(false)
window.dispatchEvent(new CustomEvent('beforeunload'))
expect(atom.workspace.confirmClose).toHaveBeenCalled()
expect(ipc.send).toHaveBeenCalledWith('cancel-window-close')
describe "when a link is clicked", ->
it "opens the http/https links in an external application", ->

View File

@@ -18,7 +18,7 @@ describe "Workspace", ->
atom.project.setPaths([atom.project.getDirectories()[0]?.resolve('dir')])
atom.workspace = workspace = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
@@ -36,7 +36,7 @@ describe "Workspace", ->
atom.project.deserialize(projectState, atom.deserializers)
atom.workspace = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, assert: atom.assert.bind(atom)
@@ -635,8 +635,8 @@ describe "Workspace", ->
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications, clipboard: atom.clipboard,
viewRegistry: atom.views, grammarRegistry: atom.grammars,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
assert: atom.assert.bind(atom)
@@ -695,8 +695,8 @@ describe "Workspace", ->
document.title = null
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications, clipboard: atom.clipboard,
viewRegistry: atom.views, grammarRegistry: atom.grammars,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
assert: atom.assert.bind(atom)

View File

@@ -172,7 +172,7 @@ class AtomEnvironment extends Model
@commandInstaller = new CommandInstaller(@getVersion(), @confirm.bind(this))
@workspace = new Workspace({
@config, @project, packageManager: @packages, grammarRegistry: @grammars,
@config, @project, packageManager: @packages, grammarRegistry: @grammars, deserializerManager: @deserializers,
notificationManager: @notifications, setRepresentedFilename: @setRepresentedFilename.bind(this),
setDocumentEdited: @setDocumentEdited.bind(this), @clipboard, viewRegistry: @views, assert: @assert.bind(this), confirm: @confirm.bind(this)
})

View File

@@ -13,12 +13,12 @@ class PaneContainer extends Model
constructor: (params) ->
super
{@config, @confirm} = params
{@config, notificationManager, deserializerManager, confirm} = params
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@itemRegistry = new ItemRegistry
@setRoot(new Pane({container: this, @config, @confirm}))
@setRoot(new Pane({container: this, @config, notificationManager, deserializerManager, confirm}))
@setActivePane(@getRoot())
@monitorActivePaneItem()
@monitorPaneItems()

View File

@@ -14,7 +14,7 @@ class Pane extends Model
activeItem: undefined
focused: false
@deserialize: (state, {deserializers}) ->
@deserialize: (state, {deserializers, config, notifications, confirm}) ->
{items, activeItemURI, activeItemUri} = state
activeItemURI ?= activeItemUri
state.items = compact(items.map (itemState) -> deserializers.deserialize(itemState))
@@ -22,13 +22,20 @@ class Pane extends Model
if typeof item.getURI is 'function'
itemURI = item.getURI()
itemURI is activeItemURI
new this(state)
new Pane(extend(state, {
deserializerManager: deserializers,
notificationManager: notifications,
confirm: confirm,
config: config
}))
constructor: (params) ->
super
@activeItem = params?.activeItem
@focused = params?.focused
{
@activeItem, @focused, @confirm, @notificationManager, @config,
@deserializerManager
} = params
@emitter = new Emitter
@itemSubscriptions = new WeakMap
@@ -390,7 +397,7 @@ class Pane extends Model
@items.splice(index, 1)
@emitter.emit 'did-remove-item', {item, index, destroyed: not moved, moved}
@container?.didDestroyPaneItem({item, index, pane: this}) unless moved
@destroy() if @items.length is 0 and atom.config.get('core.destroyEmptyPanes')
@destroy() if @items.length is 0 and @config.get('core.destroyEmptyPanes')
# Public: Move the given item to the given index.
#
@@ -456,7 +463,7 @@ class Pane extends Model
else
return true
chosen = atom.confirm
chosen = @confirm
message: "'#{item.getTitle?() ? uri}' has changes, do you want to save them?"
detailedMessage: "Your changes will be lost if you close this item without saving."
buttons: ["Save", "Cancel", "Don't Save"]
@@ -549,7 +556,7 @@ class Pane extends Model
copyActiveItem: ->
if @activeItem?
@activeItem.copy?() ? atom.deserializers.deserialize(@activeItem.serialize())
@activeItem.copy?() ? @deserializerManager.deserialize(@activeItem.serialize())
###
Section: Lifecycle
@@ -641,7 +648,7 @@ class Pane extends Model
@parent.replaceChild(this, new PaneAxis({@container, orientation, children: [this], @flexScale}))
@setFlexScale(1)
newPane = new @constructor(params)
newPane = new Pane(extend({@confirm, @deserializerManager, @config}, params))
switch side
when 'before' then @parent.insertChildBefore(this, newPane)
when 'after' then @parent.insertChildAfter(this, newPane)
@@ -683,12 +690,12 @@ class Pane extends Model
handleSaveError: (error, item) ->
itemPath = error.path ? item?.getPath?()
addWarningWithPath = (message, options) ->
addWarningWithPath = (message, options) =>
message = "#{message} '#{itemPath}'" if itemPath
atom.notifications.addWarning(message, options)
@notificationManager.addWarning(message, options)
if error.code is 'EISDIR' or error.message?.endsWith?('is a directory')
atom.notifications.addWarning("Unable to save file: #{error.message}")
@notificationManager.addWarning("Unable to save file: #{error.message}")
else if error.code is 'EACCES'
addWarningWithPath('Unable to save file: Permission denied')
else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN', 'EEXIST']
@@ -711,6 +718,6 @@ class Pane extends Model
addWarningWithPath('Unable to save file: Invalid seek')
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
fileName = errorMatch[1]
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
@notificationManager.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
else
throw error

View File

@@ -29,14 +29,14 @@ class Workspace extends Model
{
@packageManager, @config, @project, @grammarRegistry, @notificationManager,
@clipboard, @viewRegistry, @grammarRegistry, @setRepresentedFilename,
@setDocumentEdited, @assert, @confirm
@setDocumentEdited, @assert, @confirm, deserializerManager
} = params
@emitter = new Emitter
@openers = []
@destroyedItemURIs = []
@paneContainer = new PaneContainer({@config, @confirm})
@paneContainer = new PaneContainer({@config, @confirm, @notificationManager, deserializerManager})
@paneContainer.onDidDestroyPaneItem(@didDestroyPaneItem)
@directorySearchers = []