pulsar/spec/app/window-spec.coffee

309 lines
11 KiB
CoffeeScript
Raw Normal View History

$ = require 'jquery'
{$$} = require 'space-pen'
fsUtils = require 'fs-utils'
path = require 'path'
2013-03-04 23:12:20 +04:00
{less} = require 'less'
WindowEventHandler = require 'window-event-handler'
describe "Window", ->
[projectPath, windowEventHandler] = []
beforeEach ->
2013-06-12 02:48:11 +04:00
atom.getLoadSettings().initialPath = project.getPath()
windowEventHandler = new WindowEventHandler()
window.deserializeEditorWindow()
projectPath = project.getPath()
afterEach ->
windowEventHandler.unsubscribe()
$(window).off 'beforeunload'
2013-02-06 00:03:56 +04:00
describe "when the window is loaded", ->
it "doesn't have .is-blurred on the body tag", ->
2013-02-06 00:03:56 +04:00
expect($("body")).not.toHaveClass("is-blurred")
2013-02-06 00:59:26 +04:00
describe "when the window is blurred", ->
2013-02-06 00:03:56 +04:00
beforeEach ->
$(window).trigger 'blur'
afterEach ->
$('body').removeClass('is-blurred')
it "adds the .is-blurred class on the body", ->
expect($("body")).toHaveClass("is-blurred")
describe "when the window is focused again", ->
it "removes the .is-blurred class from the body", ->
$(window).trigger 'focus'
expect($("body")).not.toHaveClass("is-blurred")
2013-03-13 02:54:07 +04:00
describe "window:close event", ->
describe "when no pane items are modified", ->
it "calls window.closeWithoutConfirm", ->
spyOn window, 'closeWithoutConfirm'
2013-03-13 02:54:07 +04:00
$(window).trigger 'window:close'
expect(window.closeWithoutConfirm).toHaveBeenCalled()
2013-01-08 01:15:33 +04:00
2013-03-13 02:54:07 +04:00
describe "when pane items are are modified", ->
it "prompts user to save and and calls window.closeWithoutConfirm", ->
spyOn(window, 'closeWithoutConfirm')
2013-03-13 02:54:07 +04:00
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.closeWithoutConfirm).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
2013-03-13 02:54:07 +04:00
it "prompts user to save and aborts if dialog is canceled", ->
spyOn(window, 'closeWithoutConfirm')
2013-03-13 02:54:07 +04:00
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.closeWithoutConfirm).not.toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
2013-01-08 01:15:33 +04:00
describe "requireStylesheet(path)", ->
2013-03-06 05:03:28 +04:00
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
2013-03-06 05:03:28 +04:00
requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
2013-03-06 05:03:28 +04:00
element = $('head style[id*="css.css"]')
expect(element.attr('id')).toBe cssPath
expect(element.text()).toBe fsUtils.read(cssPath)
# doesn't append twice
2013-03-06 05:03:28 +04:00
requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
2013-03-06 05:03:28 +04:00
$('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", ->
2013-03-06 05:03:28 +04:00
lessPath = project.resolve('sample.less')
lengthBefore = $('head style').length
2013-03-06 05:03:28 +04:00
requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
2013-03-06 05:03:28 +04:00
element = $('head style[id*="sample.less"]')
expect(element.attr('id')).toBe lessPath
expect(element.text()).toBe """
#header {
color: #4d926f;
}
h2 {
color: #4d926f;
}
2013-03-06 05:03:28 +04:00
"""
# doesn't append twice
2013-03-06 05:03:28 +04:00
requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
2013-03-06 05:03:28 +04:00
$('head style[id*="sample.less"]').remove()
it "supports requiring css and less stylesheets without an explicit extension", ->
requireStylesheet 'fixtures/css'
expect($('head style[id*="css.css"]').attr('id')).toBe project.resolve('css.css')
requireStylesheet 'fixtures/sample'
expect($('head style[id*="sample.less"]').attr('id')).toBe project.resolve('sample.less')
$('head style[id*="css.css"]').remove()
$('head style[id*="sample.less"]').remove()
describe ".removeStylesheet(path)", ->
2012-12-27 05:35:19 +04:00
it "removes styling applied by given stylesheet path", ->
cssPath = require.resolve(path.join("fixtures", "css.css"))
2012-12-27 05:35:19 +04:00
expect($(document.body).css('font-weight')).not.toBe("bold")
requireStylesheet(cssPath)
expect($(document.body).css('font-weight')).toBe("bold")
removeStylesheet(cssPath)
expect($(document.body).css('font-weight')).not.toBe("bold")
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
2013-05-23 03:44:09 +04:00
windowState = {}
jasmine.unspy(atom, 'setWindowState')
spyOn(atom, 'setWindowState').andCallFake (key, value) -> windowState[key] = value
# JSON.stringify removes keys with undefined values
2013-05-23 03:44:09 +04:00
rootViewState = rootView.serialize()
syntaxState = syntax.serialize()
window.unloadEditorWindow()
expect(windowState.rootView).toEqual rootViewState
expect(windowState.syntax).toEqual syntaxState
it "unsubscribes from all buffers", ->
2012-08-31 02:19:38 +04:00
rootView.open('sample.js')
buffer = rootView.getActivePaneItem().buffer
rootView.getActivePane().splitRight()
expect(window.rootView.find('.editor').length).toBe 2
window.unloadEditorWindow()
expect(buffer.subscriptionCount()).toBe 0
describe ".deserialize(state)", ->
class Foo
@deserialize: ({name}) -> new Foo(name)
constructor: (@name) ->
beforeEach ->
registerDeserializer(Foo)
afterEach ->
unregisterDeserializer(Foo)
it "calls deserialize on the deserializer for the given state object, or returns undefined if one can't be found", ->
object = deserialize({ deserializer: 'Foo', name: 'Bar' })
expect(object.name).toBe 'Bar'
expect(deserialize({ deserializer: 'Bogus' })).toBeUndefined()
describe "when the deserializer has a version", ->
beforeEach ->
Foo.version = 2
describe "when the deserialized state has a matching version", ->
it "attempts to deserialize the state", ->
object = deserialize({ deserializer: 'Foo', version: 2, name: 'Bar' })
expect(object.name).toBe 'Bar'
describe "when the deserialized state has a non-matching version", ->
it "returns undefined", ->
expect(deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
expect(deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
expect(deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
2013-04-08 16:17:40 +04:00
describe "drag and drop", ->
buildDragEvent = (type, files) ->
dataTransfer =
files: files
data: {}
setData: (key, value) -> @data[key] = value
getData: (key) -> @data[key]
event = $.Event(type)
event.originalEvent = { dataTransfer }
event.preventDefault = ->
event.stopPropagation = ->
event
describe "when a file is dragged to window", ->
it "opens it", ->
spyOn(atom, "open")
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
window.onDrop(event)
expect(atom.open.callCount).toBe 2
describe "when a non-file is dragged to window", ->
it "does nothing", ->
spyOn(atom, "open")
event = buildDragEvent("drop", [])
window.onDrop(event)
expect(atom.open).not.toHaveBeenCalled()
describe "when a link is clicked", ->
it "opens the http/https links in an external application", ->
shell = require 'shell'
spyOn(shell, 'openExternal')
$("<a href='http://github.com'>the website</a>").appendTo(document.body).click().remove()
expect(shell.openExternal).toHaveBeenCalled()
expect(shell.openExternal.argsForCall[0][0]).toBe "http://github.com"
shell.openExternal.reset()
$("<a href='https://github.com'>the website</a>").appendTo(document.body).click().remove()
expect(shell.openExternal).toHaveBeenCalled()
expect(shell.openExternal.argsForCall[0][0]).toBe "https://github.com"
shell.openExternal.reset()
$("<a href=''>the website</a>").appendTo(document.body).click().remove()
expect(shell.openExternal).not.toHaveBeenCalled()
shell.openExternal.reset()
$("<a href='#scroll-me'>link</a>").appendTo(document.body).click().remove()
expect(shell.openExternal).not.toHaveBeenCalled()
describe "core:focus-next and core:focus-previous", ->
describe "when there is no currently focused element", ->
it "focuses the element with the lowest/highest tabindex", ->
elements = $$ ->
@div =>
@button tabindex: 2
@input tabindex: 1
elements.attachToDom()
elements.trigger "core:focus-next"
expect(elements.find("[tabindex=1]:focus")).toExist()
$(":focus").blur()
elements.trigger "core:focus-previous"
expect(elements.find("[tabindex=2]:focus")).toExist()
describe "when a tabindex is set on the currently focused element", ->
it "focuses the element with the next highest tabindex", ->
elements = $$ ->
@div =>
@input tabindex: 1
@button tabindex: 2
@button tabindex: 5
@input tabindex: -1
@input tabindex: 3
@button tabindex: 7
elements.attachToDom()
elements.find("[tabindex=1]").focus()
elements.trigger "core:focus-next"
expect(elements.find("[tabindex=2]:focus")).toExist()
elements.trigger "core:focus-next"
expect(elements.find("[tabindex=3]:focus")).toExist()
elements.focus().trigger "core:focus-next"
expect(elements.find("[tabindex=5]:focus")).toExist()
elements.focus().trigger "core:focus-next"
expect(elements.find("[tabindex=7]:focus")).toExist()
elements.focus().trigger "core:focus-next"
expect(elements.find("[tabindex=1]:focus")).toExist()
elements.trigger "core:focus-previous"
expect(elements.find("[tabindex=7]:focus")).toExist()
elements.trigger "core:focus-previous"
expect(elements.find("[tabindex=5]:focus")).toExist()
elements.focus().trigger "core:focus-previous"
expect(elements.find("[tabindex=3]:focus")).toExist()
elements.focus().trigger "core:focus-previous"
expect(elements.find("[tabindex=2]:focus")).toExist()
elements.focus().trigger "core:focus-previous"
expect(elements.find("[tabindex=1]:focus")).toExist()
it "skips disabled elements", ->
elements = $$ ->
@div =>
@input tabindex: 1
@button tabindex: 2, disabled: 'disabled'
@input tabindex: 3
elements.attachToDom()
elements.find("[tabindex=1]").focus()
elements.trigger "core:focus-next"
expect(elements.find("[tabindex=3]:focus")).toExist()
elements.trigger "core:focus-previous"
expect(elements.find("[tabindex=1]:focus")).toExist()