Merge remote-tracking branch 'origin/master' into cefode

Conflicts:
	native/v8_extensions/native.mm
	spec/app/config-spec.coffee
	spec/app/window-spec.coffee
	spec/spec-helper.coffee
	spec/stdlib/fs-utils-spec.coffee
	src/app/atom-package.coffee
	src/app/config.coffee
	src/app/window.coffee
	src/packages/fuzzy-finder/lib/load-paths-handler.coffee
	src/packages/markdown-preview/lib/markdown-preview-view.coffee
	src/packages/tree-view/spec/tree-view-spec.coffee
	src/stdlib/require.coffee
This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-03-20 10:46:50 -06:00
104 changed files with 6970 additions and 1164 deletions

View File

@@ -3,18 +3,31 @@ AtomPackage = require 'atom-package'
fs = require 'fs-utils'
describe "AtomPackage", ->
[packageMainModule, pack] = []
beforeEach ->
pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-activation-events'))
pack.load()
describe ".load()", ->
describe "if the package's metadata has a `deferredDeserializers` array", ->
it "requires the package's main module attempting to use deserializers named in the array", ->
expect(pack.mainModule).toBeNull()
object = deserialize(deserializer: 'Foo', data: "Hello")
expect(object.constructor.name).toBe 'Foo'
expect(object.data).toBe 'Hello'
expect(pack.mainModule).toBeDefined()
expect(pack.mainModule.activateCallCount).toBe 0
describe ".activate()", ->
beforeEach ->
window.rootView = new RootView
packageMainModule = require 'fixtures/packages/package-with-activation-events/main'
spyOn(packageMainModule, 'activate').andCallThrough()
describe "when the package metadata includes activation events", ->
[packageMainModule, pack] = []
beforeEach ->
pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-activation-events'))
packageMainModule = require 'fixtures/packages/package-with-activation-events/main'
spyOn(packageMainModule, 'activate').andCallThrough()
pack.load()
pack.activate()
it "defers activating the package until an activation event bubbles to the root view", ->
expect(packageMainModule.activate).not.toHaveBeenCalled()
@@ -44,12 +57,13 @@ describe "AtomPackage", ->
expect(packageMainModule.activate).not.toHaveBeenCalled()
pack.load()
pack.activate()
expect(packageMainModule.activate).toHaveBeenCalled()
describe "when the package doesn't have an index.coffee", ->
it "does not throw an exception or log an error", ->
spyOn(console, "error")
spyOn(console, "warn")
spyOn(console, "warn").andCallThrough()
pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-keymaps-manifest'))
expect(-> pack.load()).not.toThrow()

View File

@@ -85,26 +85,26 @@ describe "the `atom` global", ->
describe "activation", ->
it "calls activate on the package main with its previous state", ->
pack = window.loadPackage('package-with-module')
spyOn(pack.packageMain, 'activate')
spyOn(pack.mainModule, 'activate')
serializedState = rootView.serialize()
rootView.deactivate()
RootView.deserialize(serializedState)
window.loadPackage('package-with-module')
expect(pack.packageMain.activate).toHaveBeenCalledWith(someNumber: 1)
expect(pack.mainModule.activate).toHaveBeenCalledWith(someNumber: 1)
describe "deactivation", ->
it "deactivates and removes the package module from the package module map", ->
pack = window.loadPackage('package-with-module')
expect(atom.activatedAtomPackages.length).toBe 1
spyOn(pack.packageMain, "deactivate").andCallThrough()
spyOn(pack.mainModule, "deactivate").andCallThrough()
atom.deactivateAtomPackages()
expect(pack.packageMain.deactivate).toHaveBeenCalled()
expect(pack.mainModule.deactivate).toHaveBeenCalled()
expect(atom.activatedAtomPackages.length).toBe 0
describe "serialization", ->
it "uses previous serialization state on unactivated packages", ->
it "uses previous serialization state on packages whose activation has been deferred", ->
atom.atomPackageStates['package-with-activation-events'] = {previousData: 'exists'}
unactivatedPackage = window.loadPackage('package-with-activation-events')
activatedPackage = window.loadPackage('package-with-module')
@@ -116,7 +116,8 @@ describe "the `atom` global", ->
'previousData': 'exists'
# ensure serialization occurs when the packageis activated
unactivatedPackage.activatePackageMain()
unactivatedPackage.deferActivation = false
unactivatedPackage.activate()
expect(atom.serializeAtomPackages()).toEqual
'package-with-module':
'someNumber': 1
@@ -125,8 +126,8 @@ describe "the `atom` global", ->
it "absorbs exceptions that are thrown by the package module's serialize methods", ->
spyOn(console, 'error')
window.loadPackage('package-with-module')
window.loadPackage('package-with-serialize-error', activateImmediately: true)
window.loadPackage('package-with-module', activateImmediately: true)
window.loadPackage('package-with-serialize-error', activateImmediately: true)
packageStates = atom.serializeAtomPackages()
expect(packageStates['package-with-module']).toEqual someNumber: 1

View File

@@ -133,3 +133,21 @@ describe "Config", ->
expect(fs.isFile(fs.join(config.configDirPath, 'themes/atom-light-ui/package.cson'))).toBeTruthy()
expect(fs.isFile(fs.join(config.configDirPath, 'themes/atom-dark-syntax.css'))).toBeTruthy()
expect(fs.isFile(fs.join(config.configDirPath, 'themes/atom-light-syntax.css'))).toBeTruthy()
describe "when the config file is not parseable", ->
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configFilePath = fs.join(config.configDirPath, "config.cson")
expect(fs.exists(config.configDirPath)).toBeFalsy()
afterEach ->
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
it "logs an error to the console and does not overwrite the config file", ->
config.save.reset()
spyOn(console, 'error')
fs.write(config.configFilePath, "{{{{{")
config.loadUserConfig()
config.set("hair", "blonde") # trigger a save
expect(console.error).toHaveBeenCalled()
expect(config.save).not.toHaveBeenCalled()

View File

@@ -136,6 +136,43 @@ describe "PaneContainer", ->
for item in pane.getItems()
expect(item.saved).toBeTruthy()
describe ".confirmClose()", ->
it "resolves the returned promise after modified files are saved", ->
pane1.itemAtIndex(0).isModified = -> true
pane2.itemAtIndex(0).isModified = -> true
spyOn(atom, "confirm").andCallFake (a, b, c, d, e, f, g, noSaveFn) -> noSaveFn()
promiseHandler = jasmine.createSpy("promiseHandler")
failedPromiseHandler = jasmine.createSpy("failedPromiseHandler")
promise = container.confirmClose()
promise.done promiseHandler
promise.fail failedPromiseHandler
waitsFor ->
promiseHandler.wasCalled
runs ->
expect(failedPromiseHandler).not.toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "rejects the returned promise if the user cancels saving", ->
pane1.itemAtIndex(0).isModified = -> true
pane2.itemAtIndex(0).isModified = -> true
spyOn(atom, "confirm").andCallFake (a, b, c, d, e, cancelFn, f, g) -> cancelFn()
promiseHandler = jasmine.createSpy("promiseHandler")
failedPromiseHandler = jasmine.createSpy("failedPromiseHandler")
promise = container.confirmClose()
promise.done promiseHandler
promise.fail failedPromiseHandler
waitsFor ->
failedPromiseHandler.wasCalled
runs ->
expect(promiseHandler).not.toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
describe "serialization", ->
it "can be serialized and deserialized, and correctly adjusts dimensions of deserialized panes after attach", ->
newContainer = deserialize(container.serialize())
@@ -146,3 +183,10 @@ describe "PaneContainer", ->
newContainer.height(200).width(300).attachToDom()
expect(newContainer.find('.row > :contains(1)').width()).toBe 150
expect(newContainer.find('.row > .column > :contains(2)').height()).toBe 100
it "removes empty panes on deserialization", ->
# only deserialize pane 1's view successfully
TestView.deserialize = ({name}) -> new TestView(name) if name is '1'
newContainer = deserialize(container.serialize())
expect(newContainer.find('.row, .column')).not.toExist()
expect(newContainer.find('> :contains(1)')).toExist()

View File

@@ -450,6 +450,14 @@ describe "Pane", ->
pane.remove()
expect(rootView.focus).not.toHaveBeenCalled()
describe ".getNextPane()", ->
it "returns the next pane if one exists, wrapping around from the last pane to the first", ->
pane.showItem(editSession1)
expect(pane.getNextPane()).toBeUndefined
pane2 = pane.splitRight()
expect(pane.getNextPane()).toBe pane2
expect(pane2.getNextPane()).toBe pane
describe "when the pane is focused", ->
it "focuses the active item view", ->
focusHandler = jasmine.createSpy("focusHandler")

View File

@@ -134,8 +134,8 @@ describe "Project", ->
project.getFilePaths().done (foundPaths) -> paths = foundPaths
runs ->
expect(paths).not.toContain('a')
expect(paths).toContain('b')
expect(paths).not.toContain(project.resolve('a'))
expect(paths).toContain(project.resolve('b'))
describe "when config.core.hideGitIgnoredFiles is true", ->
it "ignores files that are present in .gitignore if the project is a git repo", ->

View File

@@ -20,8 +20,21 @@ describe "@load(name)", ->
expect($(".editor").css("background-color")).toBe("rgb(20, 20, 20)")
describe "AtomTheme", ->
describe "when the theme is a file", ->
it "loads and applies css", ->
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
themePath = project.resolve('themes/theme-stylesheet.css')
theme = Theme.load(themePath)
expect($(".editor").css("padding-top")).toBe "1234px"
it "parses, loads and applies less", ->
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
themePath = project.resolve('themes/theme-stylesheet.less')
theme = Theme.load(themePath)
expect($(".editor").css("padding-top")).toBe "4321px"
describe "when the theme contains a package.json file", ->
it "loads and applies css from package.json in the correct order", ->
it "loads and applies stylesheets from package.json in the correct order", ->
expect($(".editor").css("padding-top")).not.toBe("101px")
expect($(".editor").css("padding-right")).not.toBe("102px")
expect($(".editor").css("padding-bottom")).not.toBe("103px")
@@ -32,16 +45,8 @@ describe "@load(name)", ->
expect($(".editor").css("padding-right")).toBe("102px")
expect($(".editor").css("padding-bottom")).toBe("103px")
describe "when the theme is a CSS file", ->
it "loads and applies the stylesheet", ->
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
themePath = project.resolve('themes/theme-stylesheet.css')
theme = Theme.load(themePath)
expect($(".editor").css("padding-top")).toBe "1234px"
describe "when the theme does not contain a package.json file and is a directory", ->
it "loads all CSS files in the directory", ->
it "loads all stylesheet files in the directory", ->
expect($(".editor").css("padding-top")).not.toBe "10px"
expect($(".editor").css("padding-right")).not.toBe "20px"
expect($(".editor").css("padding-bottom")).not.toBe "30px"

View File

@@ -1,5 +1,6 @@
$ = require 'jquery'
fs = require 'fs-utils'
{less} = require 'less'
describe "Window", ->
projectPath = null
@@ -34,16 +35,31 @@ describe "Window", ->
$(window).trigger 'focus'
expect($("body")).not.toHaveClass("is-blurred")
describe ".close()", ->
it "is triggered by the 'core:close' event", ->
spyOn window, 'close'
$(window).trigger 'core:close'
expect(window.close).toHaveBeenCalled()
describe "window:close event", ->
describe "when no pane items are modified", ->
it "calls window.close", ->
spyOn window, 'close'
$(window).trigger 'window:close'
expect(window.close).toHaveBeenCalled()
it "is triggered by the 'window:close event'", ->
spyOn window, 'close'
$(window).trigger 'window:close'
expect(window.close).toHaveBeenCalled()
describe "when pane items are are modified", ->
it "prompts user to save and and calls window.close", ->
spyOn(window, 'close')
spyOn(atom, "confirm").andCallFake (a, b, c, d, e, f, g, noSave) -> noSave()
editSession = rootView.open("sample.js")
editSession.insertText("I look different, I feel different.")
$(window).trigger 'window:close'
expect(window.close).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and aborts if dialog is canceled", ->
spyOn(window, 'close')
spyOn(atom, "confirm").andCallFake (a, b, c, d, e, cancel) -> cancel()
editSession = rootView.open("sample.js")
editSession.insertText("I look different, I feel different.")
$(window).trigger 'window:close'
expect(window.close).not.toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
describe ".reload()", ->
beforeEach ->
@@ -62,22 +78,46 @@ describe "Window", ->
expect(atom.confirm).toHaveBeenCalled()
describe "requireStylesheet(path)", ->
it "synchronously loads the stylesheet at the given path and installs a style tag for it in the head", ->
$('head style[id*="atom.css"]').remove()
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
cssPath = project.resolve('css.css')
lengthBefore = $('head style').length
requireStylesheet('atom.css')
requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
styleElt = $('head style[id*="atom.css"]')
fullPath = require.resolve('atom.css')
expect(styleElt.attr('id')).toBe fullPath
expect(styleElt.text()).toBe fs.read(fullPath)
element = $('head style[id*="css.css"]')
expect(element.attr('id')).toBe cssPath
expect(element.text()).toBe fs.read(cssPath)
# doesn't append twice
requireStylesheet('atom.css')
requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
$('head style[id*="css.css"]').remove()
it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", ->
lessPath = project.resolve('sample.less')
lengthBefore = $('head style').length
requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
element = $('head style[id*="sample.less"]')
expect(element.attr('id')).toBe lessPath
expect(element.text()).toBe """
#header {
color: #4d926f;
}
h2 {
color: #4d926f;
}
"""
# doesn't append twice
requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
$('head style[id*="sample.less"]').remove()
describe ".disableStyleSheet(path)", ->
it "removes styling applied by given stylesheet path", ->
cssPath = require.resolve(fs.join("fixtures", "css.css"))