pulsar/spec/workspace-element-spec.js
Antonio Scandurra 8077f46fdf Programmatically detect when mouse approaches the edge of a dock
Previously, we would assign dock elements a minimum width/height of 2
pixels so that we could detect when the mouse approached the edge of a
hidden dock in order to show the chevron buttons. This, however, was
causing confusion for users, who expected that extra space to be
clickable in order to scroll editors located in the center dock.

With this commit we will instead register a global `mousemove` event on
the window right when attaching the workspace element to the DOM (the
event handler is debounced, so this shouldn't have any performance
consequence). Then, when mouse moves, we will programmatically detect
when it is approaching to the edge of a dock and show the chevron button
accordingly. This allows us to remove the `min-width` property from the
dock container element, which eliminates the confusing behavior
described above.
2018-01-12 17:12:55 +01:00

898 lines
36 KiB
JavaScript

/** @babel */
const {ipcRenderer} = require('electron')
const path = require('path')
const temp = require('temp').track()
const {Disposable} = require('event-kit')
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers')
describe('WorkspaceElement', () => {
afterEach(() => {
try {
temp.cleanupSync()
} catch (e) {
// Do nothing
}
})
describe('when the workspace element is focused', () => {
it('transfers focus to the active pane', () => {
const workspaceElement = atom.workspace.getElement()
jasmine.attachToDOM(workspaceElement)
const activePaneElement = atom.workspace.getActivePane().getElement()
document.body.focus()
expect(document.activeElement).not.toBe(activePaneElement)
workspaceElement.focus()
expect(document.activeElement).toBe(activePaneElement)
})
})
describe('when the active pane of an inactive pane container is focused', () => {
it('changes the active pane container', () => {
const dock = atom.workspace.getLeftDock()
dock.show()
jasmine.attachToDOM(atom.workspace.getElement())
expect(atom.workspace.getActivePaneContainer()).toBe(atom.workspace.getCenter())
dock.getActivePane().getElement().focus()
expect(atom.workspace.getActivePaneContainer()).toBe(dock)
})
})
describe('finding the nearest visible pane in a specific direction', () => {
let pane1, pane2, pane3, pane4, pane5, pane6, pane7, pane8, pane9,
leftDockPane, rightDockPane, bottomDockPane, workspace, workspaceElement
beforeEach(function () {
atom.config.set('core.destroyEmptyPanes', false)
expect(document.hasFocus()).toBe(true, 'Document needs to be focused to run this test')
workspace = atom.workspace
// Set up a workspace center with a grid of 9 panes, in the following
// arrangement, where the numbers correspond to the variable names below.
//
// -------
// |1|2|3|
// -------
// |4|5|6|
// -------
// |7|8|9|
// -------
const container = workspace.getActivePaneContainer()
expect(container.getLocation()).toEqual('center')
expect(container.getPanes().length).toEqual(1)
pane1 = container.getActivePane()
pane4 = pane1.splitDown()
pane7 = pane4.splitDown()
pane2 = pane1.splitRight()
pane3 = pane2.splitRight()
pane5 = pane4.splitRight()
pane6 = pane5.splitRight()
pane8 = pane7.splitRight()
pane9 = pane8.splitRight()
const leftDock = workspace.getLeftDock()
const rightDock = workspace.getRightDock()
const bottomDock = workspace.getBottomDock()
expect(leftDock.isVisible()).toBe(false)
expect(rightDock.isVisible()).toBe(false)
expect(bottomDock.isVisible()).toBe(false)
expect(leftDock.getPanes().length).toBe(1)
expect(rightDock.getPanes().length).toBe(1)
expect(bottomDock.getPanes().length).toBe(1)
leftDockPane = leftDock.getPanes()[0]
rightDockPane = rightDock.getPanes()[0]
bottomDockPane = bottomDock.getPanes()[0]
workspaceElement = atom.workspace.getElement()
workspaceElement.style.height = '400px'
workspaceElement.style.width = '400px'
jasmine.attachToDOM(workspaceElement)
})
describe('finding the nearest pane above', () => {
describe('when there are multiple rows above the pane', () => {
it('returns the pane in the adjacent row above', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('above', pane8)
expect(nearestPaneElement).toBe(pane5.getElement())
})
})
describe('when there are no rows above the pane', () => {
it('returns null', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('above', pane2)
expect(nearestPaneElement).toBeUndefined() // TODO Expect toBeNull()
})
})
describe('when the bottom dock contains the pane', () => {
it('returns the pane in the adjacent row above', () => {
workspace.getBottomDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('above', bottomDockPane)
expect(nearestPaneElement).toBe(pane7.getElement())
})
})
})
describe('finding the nearest pane below', () => {
describe('when there are multiple rows below the pane', () => {
it('returns the pane in the adjacent row below', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('below', pane2)
expect(nearestPaneElement).toBe(pane5.getElement())
})
})
describe('when there are no rows below the pane', () => {
it('returns null', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('below', pane8)
expect(nearestPaneElement).toBeUndefined() // TODO Expect toBeNull()
})
})
describe('when the bottom dock is visible', () => {
describe("when the workspace center's bottommost row contains the pane", () => {
it("returns the pane in the bottom dock's adjacent row below", () => {
workspace.getBottomDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('below', pane8)
expect(nearestPaneElement).toBe(bottomDockPane.getElement())
})
})
})
})
describe('finding the nearest pane to the left', () => {
describe('when there are multiple columns to the left of the pane', () => {
it('returns the pane in the adjacent column to the left', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('left', pane6)
expect(nearestPaneElement).toBe(pane5.getElement())
})
})
describe('when there are no columns to the left of the pane', () => {
it('returns null', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('left', pane4)
expect(nearestPaneElement).toBeUndefined() // TODO Expect toBeNull()
})
})
describe('when the right dock contains the pane', () => {
it('returns the pane in the adjacent column to the left', () => {
workspace.getRightDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('left', rightDockPane)
expect(nearestPaneElement).toBe(pane3.getElement())
})
})
describe('when the left dock is visible', () => {
describe("when the workspace center's leftmost column contains the pane", () => {
it("returns the pane in the left dock's adjacent column to the left", () => {
workspace.getLeftDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('left', pane4)
expect(nearestPaneElement).toBe(leftDockPane.getElement())
})
})
describe('when the bottom dock contains the pane', () => {
it("returns the pane in the left dock's adjacent column to the left", () => {
workspace.getLeftDock().show()
workspace.getBottomDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('left', bottomDockPane)
expect(nearestPaneElement).toBe(leftDockPane.getElement())
})
})
})
})
describe('finding the nearest pane to the right', () => {
describe('when there are multiple columns to the right of the pane', () => {
it('returns the pane in the adjacent column to the right', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('right', pane4)
expect(nearestPaneElement).toBe(pane5.getElement())
})
})
describe('when there are no columns to the right of the pane', () => {
it('returns null', () => {
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('right', pane6)
expect(nearestPaneElement).toBeUndefined() // TODO Expect toBeNull()
})
})
describe('when the left dock contains the pane', () => {
it('returns the pane in the adjacent column to the right', () => {
workspace.getLeftDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('right', leftDockPane)
expect(nearestPaneElement).toBe(pane1.getElement())
})
})
describe('when the right dock is visible', () => {
describe("when the workspace center's rightmost column contains the pane", () => {
it("returns the pane in the right dock's adjacent column to the right", () => {
workspace.getRightDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('right', pane6)
expect(nearestPaneElement).toBe(rightDockPane.getElement())
})
})
describe('when the bottom dock contains the pane', () => {
it("returns the pane in the right dock's adjacent column to the right", () => {
workspace.getRightDock().show()
workspace.getBottomDock().show()
nearestPaneElement = workspaceElement.nearestVisiblePaneInDirection('right', bottomDockPane)
expect(nearestPaneElement).toBe(rightDockPane.getElement())
})
})
})
})
})
describe('changing focus, copying, and moving items directionally between panes', function () {
let workspace, workspaceElement, startingPane
beforeEach(function () {
atom.config.set('core.destroyEmptyPanes', false)
expect(document.hasFocus()).toBe(true, 'Document needs to be focused to run this test')
workspace = atom.workspace
expect(workspace.getLeftDock().isVisible()).toBe(false)
expect(workspace.getRightDock().isVisible()).toBe(false)
expect(workspace.getBottomDock().isVisible()).toBe(false)
const panes = workspace.getCenter().getPanes()
expect(panes.length).toEqual(1)
startingPane = panes[0]
workspaceElement = atom.workspace.getElement()
workspaceElement.style.height = '400px'
workspaceElement.style.width = '400px'
jasmine.attachToDOM(workspaceElement)
})
describe('::focusPaneViewAbove()', function () {
describe('when there is a row above the focused pane', () =>
it('focuses up to the adjacent row', function () {
const paneAbove = startingPane.splitUp()
startingPane.activate()
workspaceElement.focusPaneViewAbove()
expect(document.activeElement).toBe(paneAbove.getElement())
})
)
describe('when there are no rows above the focused pane', () =>
it('keeps the current pane focused', function () {
startingPane.activate()
workspaceElement.focusPaneViewAbove()
expect(document.activeElement).toBe(startingPane.getElement())
})
)
})
describe('::focusPaneViewBelow()', function () {
describe('when there is a row below the focused pane', () =>
it('focuses down to the adjacent row', function () {
const paneBelow = startingPane.splitDown()
startingPane.activate()
workspaceElement.focusPaneViewBelow()
expect(document.activeElement).toBe(paneBelow.getElement())
})
)
describe('when there are no rows below the focused pane', () =>
it('keeps the current pane focused', function () {
startingPane.activate()
workspaceElement.focusPaneViewBelow()
expect(document.activeElement).toBe(startingPane.getElement())
})
)
})
describe('::focusPaneViewOnLeft()', function () {
describe('when there is a column to the left of the focused pane', () =>
it('focuses left to the adjacent column', function () {
const paneOnLeft = startingPane.splitLeft()
startingPane.activate()
workspaceElement.focusPaneViewOnLeft()
expect(document.activeElement).toBe(paneOnLeft.getElement())
})
)
describe('when there are no columns to the left of the focused pane', () =>
it('keeps the current pane focused', function () {
startingPane.activate()
workspaceElement.focusPaneViewOnLeft()
expect(document.activeElement).toBe(startingPane.getElement())
})
)
})
describe('::focusPaneViewOnRight()', function () {
describe('when there is a column to the right of the focused pane', () =>
it('focuses right to the adjacent column', function () {
const paneOnRight = startingPane.splitRight()
startingPane.activate()
workspaceElement.focusPaneViewOnRight()
expect(document.activeElement).toBe(paneOnRight.getElement())
})
)
describe('when there are no columns to the right of the focused pane', () =>
it('keeps the current pane focused', function () {
startingPane.activate()
workspaceElement.focusPaneViewOnRight()
expect(document.activeElement).toBe(startingPane.getElement())
})
)
})
describe('::moveActiveItemToPaneAbove(keepOriginal)', function () {
describe('when there is a row above the focused pane', () =>
it('moves the active item up to the adjacent row', function () {
const item = document.createElement('div')
const paneAbove = startingPane.splitUp()
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneAbove()
expect(workspace.paneForItem(item)).toBe(paneAbove)
expect(paneAbove.getActiveItem()).toBe(item)
})
)
describe('when there are no rows above the focused pane', () =>
it('keeps the active pane focused', function () {
const item = document.createElement('div')
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneAbove()
expect(workspace.paneForItem(item)).toBe(startingPane)
})
)
describe('when `keepOriginal: true` is passed in the params', () =>
it('keeps the item and adds a copy of it to the adjacent pane', function () {
const itemA = document.createElement('div')
const itemB = document.createElement('div')
itemA.copy = () => itemB
const paneAbove = startingPane.splitUp()
startingPane.activate()
startingPane.activateItem(itemA)
workspaceElement.moveActiveItemToPaneAbove({keepOriginal: true})
expect(workspace.paneForItem(itemA)).toBe(startingPane)
expect(paneAbove.getActiveItem()).toBe(itemB)
})
)
})
describe('::moveActiveItemToPaneBelow(keepOriginal)', function () {
describe('when there is a row below the focused pane', () =>
it('moves the active item down to the adjacent row', function () {
const item = document.createElement('div')
const paneBelow = startingPane.splitDown()
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneBelow()
expect(workspace.paneForItem(item)).toBe(paneBelow)
expect(paneBelow.getActiveItem()).toBe(item)
})
)
describe('when there are no rows below the focused pane', () =>
it('keeps the active item in the focused pane', function () {
const item = document.createElement('div')
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneBelow()
expect(workspace.paneForItem(item)).toBe(startingPane)
})
)
describe('when `keepOriginal: true` is passed in the params', () =>
it('keeps the item and adds a copy of it to the adjacent pane', function () {
const itemA = document.createElement('div')
const itemB = document.createElement('div')
itemA.copy = () => itemB
const paneBelow = startingPane.splitDown()
startingPane.activate()
startingPane.activateItem(itemA)
workspaceElement.moveActiveItemToPaneBelow({keepOriginal: true})
expect(workspace.paneForItem(itemA)).toBe(startingPane)
expect(paneBelow.getActiveItem()).toBe(itemB)
})
)
})
describe('::moveActiveItemToPaneOnLeft(keepOriginal)', function () {
describe('when there is a column to the left of the focused pane', () =>
it('moves the active item left to the adjacent column', function () {
const item = document.createElement('div')
const paneOnLeft = startingPane.splitLeft()
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneOnLeft()
expect(workspace.paneForItem(item)).toBe(paneOnLeft)
expect(paneOnLeft.getActiveItem()).toBe(item)
})
)
describe('when there are no columns to the left of the focused pane', () =>
it('keeps the active item in the focused pane', function () {
const item = document.createElement('div')
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneOnLeft()
expect(workspace.paneForItem(item)).toBe(startingPane)
})
)
describe('when `keepOriginal: true` is passed in the params', () =>
it('keeps the item and adds a copy of it to the adjacent pane', function () {
const itemA = document.createElement('div')
const itemB = document.createElement('div')
itemA.copy = () => itemB
const paneOnLeft = startingPane.splitLeft()
startingPane.activate()
startingPane.activateItem(itemA)
workspaceElement.moveActiveItemToPaneOnLeft({keepOriginal: true})
expect(workspace.paneForItem(itemA)).toBe(startingPane)
expect(paneOnLeft.getActiveItem()).toBe(itemB)
})
)
})
describe('::moveActiveItemToPaneOnRight(keepOriginal)', function () {
describe('when there is a column to the right of the focused pane', () =>
it('moves the active item right to the adjacent column', function () {
const item = document.createElement('div')
const paneOnRight = startingPane.splitRight()
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneOnRight()
expect(workspace.paneForItem(item)).toBe(paneOnRight)
expect(paneOnRight.getActiveItem()).toBe(item)
})
)
describe('when there are no columns to the right of the focused pane', () =>
it('keeps the active item in the focused pane', function () {
const item = document.createElement('div')
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToPaneOnRight()
expect(workspace.paneForItem(item)).toBe(startingPane)
})
)
describe('when `keepOriginal: true` is passed in the params', () =>
it('keeps the item and adds a copy of it to the adjacent pane', function () {
const itemA = document.createElement('div')
const itemB = document.createElement('div')
itemA.copy = () => itemB
const paneOnRight = startingPane.splitRight()
startingPane.activate()
startingPane.activateItem(itemA)
workspaceElement.moveActiveItemToPaneOnRight({keepOriginal: true})
expect(workspace.paneForItem(itemA)).toBe(startingPane)
expect(paneOnRight.getActiveItem()).toBe(itemB)
})
)
})
describe('::moveActiveItemToNearestPaneInDirection(direction, params)', () => {
describe('when the item is not allowed in nearest pane in the given direction', () => {
it('does not move or copy the active item', function () {
const item = {
element: document.createElement('div'),
getAllowedLocations: () => ['left', 'right']
}
workspace.getBottomDock().show()
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.moveActiveItemToNearestPaneInDirection('below', {keepOriginal: false})
expect(workspace.paneForItem(item)).toBe(startingPane)
workspaceElement.moveActiveItemToNearestPaneInDirection('below', {keepOriginal: true})
expect(workspace.paneForItem(item)).toBe(startingPane)
})
})
describe("when the item doesn't implement a `copy` function", () => {
it('does not copy the active item', function () {
const item = document.createElement('div')
const paneBelow = startingPane.splitDown()
expect(paneBelow.getItems().length).toEqual(0)
startingPane.activate()
startingPane.activateItem(item)
workspaceElement.focusPaneViewAbove()
workspaceElement.moveActiveItemToNearestPaneInDirection('below', {keepOriginal: true})
expect(workspace.paneForItem(item)).toBe(startingPane)
expect(paneBelow.getItems().length).toEqual(0)
})
})
})
})
describe('mousing over docks', () => {
let workspaceElement
beforeEach(() => {
workspaceElement = atom.workspace.getElement()
workspaceElement.style.width = '600px'
workspaceElement.style.height = '300px'
jasmine.attachToDOM(workspaceElement)
})
it('shows the toggle button when the dock is open', async () => {
await Promise.all([
atom.workspace.open({
element: document.createElement('div'),
getDefaultLocation() { return 'left' },
getPreferredWidth() { return 150 }
}),
atom.workspace.open({
element: document.createElement('div'),
getDefaultLocation() { return 'right' },
getPreferredWidth() { return 150 }
}),
atom.workspace.open({
element: document.createElement('div'),
getDefaultLocation() { return 'bottom' },
getPreferredHeight() { return 100 }
})
])
const leftDock = atom.workspace.getLeftDock()
const rightDock = atom.workspace.getRightDock()
const bottomDock = atom.workspace.getBottomDock()
expect(leftDock.isVisible()).toBe(true)
expect(rightDock.isVisible()).toBe(true)
expect(bottomDock.isVisible()).toBe(true)
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// --- Right Dock ---
// Mouse over where the toggle button would be if the dock were hovered
moveMouse({clientX: 440, clientY: 150})
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// Mouse over the dock
moveMouse({clientX: 460, clientY: 150})
expectToggleButtonHidden(leftDock)
expectToggleButtonVisible(rightDock, 'icon-chevron-right')
expectToggleButtonHidden(bottomDock)
// Mouse over the toggle button
moveMouse({clientX: 440, clientY: 150})
expectToggleButtonHidden(leftDock)
expectToggleButtonVisible(rightDock, 'icon-chevron-right')
expectToggleButtonHidden(bottomDock)
// Click the toggle button
rightDock.toggleButton.innerElement.click()
expect(rightDock.isVisible()).toBe(false)
expectToggleButtonHidden(rightDock)
// Mouse to edge of the window
moveMouse({clientX: 575, clientY: 150})
expectToggleButtonHidden(rightDock)
moveMouse({clientX: 598, clientY: 150})
expectToggleButtonVisible(rightDock, 'icon-chevron-left')
// Click the toggle button again
rightDock.toggleButton.innerElement.click()
expect(rightDock.isVisible()).toBe(true)
expectToggleButtonVisible(rightDock, 'icon-chevron-right')
// --- Left Dock ---
// Mouse over where the toggle button would be if the dock were hovered
moveMouse({clientX: 160, clientY: 150})
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// Mouse over the dock
moveMouse({clientX: 140, clientY: 150})
expectToggleButtonVisible(leftDock, 'icon-chevron-left')
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// Mouse over the toggle button
moveMouse({clientX: 160, clientY: 150})
expectToggleButtonVisible(leftDock, 'icon-chevron-left')
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// Click the toggle button
leftDock.toggleButton.innerElement.click()
expect(leftDock.isVisible()).toBe(false)
expectToggleButtonHidden(leftDock)
// Mouse to edge of the window
moveMouse({clientX: 25, clientY: 150})
expectToggleButtonHidden(leftDock)
moveMouse({clientX: 2, clientY: 150})
expectToggleButtonVisible(leftDock, 'icon-chevron-right')
// Click the toggle button again
leftDock.toggleButton.innerElement.click()
expect(leftDock.isVisible()).toBe(true)
expectToggleButtonVisible(leftDock, 'icon-chevron-left')
// --- Bottom Dock ---
// Mouse over where the toggle button would be if the dock were hovered
moveMouse({clientX: 300, clientY: 190})
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonHidden(bottomDock)
// Mouse over the dock
moveMouse({clientX: 300, clientY: 210})
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonVisible(bottomDock, 'icon-chevron-down')
// Mouse over the toggle button
moveMouse({clientX: 300, clientY: 195})
expectToggleButtonHidden(leftDock)
expectToggleButtonHidden(rightDock)
expectToggleButtonVisible(bottomDock, 'icon-chevron-down')
// Click the toggle button
bottomDock.toggleButton.innerElement.click()
expect(bottomDock.isVisible()).toBe(false)
expectToggleButtonHidden(bottomDock)
// Mouse to edge of the window
moveMouse({clientX: 300, clientY: 290})
expectToggleButtonHidden(leftDock)
moveMouse({clientX: 300, clientY: 299})
expectToggleButtonVisible(bottomDock, 'icon-chevron-up')
// Click the toggle button again
bottomDock.toggleButton.innerElement.click()
expect(bottomDock.isVisible()).toBe(true)
expectToggleButtonVisible(bottomDock, 'icon-chevron-down')
})
function moveMouse(coordinates) {
window.dispatchEvent(new MouseEvent('mousemove', coordinates))
advanceClock(100)
}
function expectToggleButtonHidden(dock) {
expect(dock.toggleButton.element).not.toHaveClass('atom-dock-toggle-button-visible')
}
function expectToggleButtonVisible(dock, iconClass) {
expect(dock.toggleButton.element).toHaveClass('atom-dock-toggle-button-visible')
expect(dock.toggleButton.iconElement).toHaveClass(iconClass)
}
})
describe('the scrollbar visibility class', () => {
it('has a class based on the style of the scrollbar', () => {
let observeCallback
const scrollbarStyle = require('scrollbar-style')
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake(cb => {
observeCallback = cb
return new Disposable(() => {})
})
const workspaceElement = atom.workspace.getElement()
observeCallback('legacy')
expect(workspaceElement.className).toMatch('scrollbars-visible-always')
observeCallback('overlay')
expect(workspaceElement).toHaveClass('scrollbars-visible-when-scrolling')
})
})
describe('editor font styling', () => {
let editor, editorElement, workspaceElement
beforeEach(async () => {
await atom.workspace.open('sample.js')
workspaceElement = atom.workspace.getElement()
jasmine.attachToDOM(workspaceElement)
editor = atom.workspace.getActiveTextEditor()
editorElement = editor.getElement()
})
it("updates the font-size based on the 'editor.fontSize' config value", async () => {
const initialCharWidth = editor.getDefaultCharWidth()
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
await editorElement.component.getNextUpdatePromise()
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
expect(editor.getDefaultCharWidth()).toBeGreaterThan(initialCharWidth)
})
it("updates the font-family based on the 'editor.fontFamily' config value", async () => {
const initialCharWidth = editor.getDefaultCharWidth()
let fontFamily = atom.config.get('editor.fontFamily')
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
atom.config.set('editor.fontFamily', 'sans-serif')
fontFamily = atom.config.get('editor.fontFamily')
await editorElement.component.getNextUpdatePromise()
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
expect(editor.getDefaultCharWidth()).not.toBe(initialCharWidth)
})
it("updates the line-height based on the 'editor.lineHeight' config value", async () => {
const initialLineHeight = editor.getLineHeightInPixels()
atom.config.set('editor.lineHeight', '30px')
await editorElement.component.getNextUpdatePromise()
expect(getComputedStyle(editorElement).lineHeight).toBe(atom.config.get('editor.lineHeight'))
expect(editor.getLineHeightInPixels()).not.toBe(initialLineHeight)
})
it('increases or decreases the font size when a ctrl-mousewheel event occurs', () => {
atom.config.set('editor.zoomFontWhenCtrlScrolling', true)
atom.config.set('editor.fontSize', 12)
// Zoom out
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
wheelDeltaY: -10,
ctrlKey: true
}))
expect(atom.config.get('editor.fontSize')).toBe(11)
// Zoom in
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
wheelDeltaY: 10,
ctrlKey: true
}))
expect(atom.config.get('editor.fontSize')).toBe(12)
// Not on an atom-text-editor
workspaceElement.dispatchEvent(new WheelEvent('mousewheel', {
wheelDeltaY: 10,
ctrlKey: true
}))
expect(atom.config.get('editor.fontSize')).toBe(12)
// No ctrl key
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
wheelDeltaY: 10
}))
expect(atom.config.get('editor.fontSize')).toBe(12)
atom.config.set('editor.zoomFontWhenCtrlScrolling', false)
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
wheelDeltaY: 10,
ctrlKey: true
}))
expect(atom.config.get('editor.fontSize')).toBe(12)
})
})
describe('panel containers', () => {
it('inserts panel container elements in the correct places in the DOM', () => {
const workspaceElement = atom.workspace.getElement()
const leftContainer = workspaceElement.querySelector('atom-panel-container.left')
const rightContainer = workspaceElement.querySelector('atom-panel-container.right')
expect(leftContainer.nextSibling).toBe(workspaceElement.verticalAxis)
expect(rightContainer.previousSibling).toBe(workspaceElement.verticalAxis)
const topContainer = workspaceElement.querySelector('atom-panel-container.top')
const bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
expect(topContainer.nextSibling).toBe(workspaceElement.paneContainer)
expect(bottomContainer.previousSibling).toBe(workspaceElement.paneContainer)
const headerContainer = workspaceElement.querySelector('atom-panel-container.header')
const footerContainer = workspaceElement.querySelector('atom-panel-container.footer')
expect(headerContainer.nextSibling).toBe(workspaceElement.horizontalAxis)
expect(footerContainer.previousSibling).toBe(workspaceElement.horizontalAxis)
const modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
expect(modalContainer.parentNode).toBe(workspaceElement)
})
it('stretches header/footer panels to the workspace width', () => {
const workspaceElement = atom.workspace.getElement()
jasmine.attachToDOM(workspaceElement)
expect(workspaceElement.offsetWidth).toBeGreaterThan(0)
const headerItem = document.createElement('div')
atom.workspace.addHeaderPanel({item: headerItem})
expect(headerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
const footerItem = document.createElement('div')
atom.workspace.addFooterPanel({item: footerItem})
expect(footerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
})
it('shrinks horizontal axis according to header/footer panels height', () => {
const workspaceElement = atom.workspace.getElement()
workspaceElement.style.height = '100px'
const horizontalAxisElement = workspaceElement.querySelector('atom-workspace-axis.horizontal')
jasmine.attachToDOM(workspaceElement)
const originalHorizontalAxisHeight = horizontalAxisElement.offsetHeight
expect(workspaceElement.offsetHeight).toBeGreaterThan(0)
expect(originalHorizontalAxisHeight).toBeGreaterThan(0)
const headerItem = document.createElement('div')
headerItem.style.height = '10px'
atom.workspace.addHeaderPanel({item: headerItem})
expect(headerItem.offsetHeight).toBeGreaterThan(0)
const footerItem = document.createElement('div')
footerItem.style.height = '15px'
atom.workspace.addFooterPanel({item: footerItem})
expect(footerItem.offsetHeight).toBeGreaterThan(0)
expect(horizontalAxisElement.offsetHeight).toEqual(originalHorizontalAxisHeight - headerItem.offsetHeight - footerItem.offsetHeight)
})
})
describe("the 'window:toggle-invisibles' command", () => {
it('shows/hides invisibles in all open and future editors', () => {
const workspaceElement = atom.workspace.getElement()
expect(atom.config.get('editor.showInvisibles')).toBe(false)
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
expect(atom.config.get('editor.showInvisibles')).toBe(true)
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
expect(atom.config.get('editor.showInvisibles')).toBe(false)
})
})
describe("the 'window:run-package-specs' command", () => {
it("runs the package specs for the active item's project path, or the first project path", () => {
const workspaceElement = atom.workspace.getElement()
spyOn(ipcRenderer, 'send')
// No project paths. Don't try to run specs.
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
expect(ipcRenderer.send).not.toHaveBeenCalledWith('run-package-specs')
const projectPaths = [temp.mkdirSync('dir1-'), temp.mkdirSync('dir2-')]
atom.project.setPaths(projectPaths)
// No active item. Use first project directory.
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
ipcRenderer.send.reset()
// Active item doesn't implement ::getPath(). Use first project directory.
const item = document.createElement('div')
atom.workspace.getActivePane().activateItem(item)
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
ipcRenderer.send.reset()
// Active item has no path. Use first project directory.
item.getPath = () => null
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
ipcRenderer.send.reset()
// Active item has path. Use project path for item path.
item.getPath = () => path.join(projectPaths[1], 'a-file.txt')
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[1], 'spec'))
ipcRenderer.send.reset()
})
})
})