mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
268 lines
10 KiB
JavaScript
268 lines
10 KiB
JavaScript
/** @babel */
|
|
|
|
import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
|
|
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
|
|
|
|
const ReopenProjectMenuManager = require('../src/reopen-project-menu-manager')
|
|
|
|
numberRange = (low, high) => {
|
|
const size = high - low
|
|
const result = new Array(size)
|
|
for (var i = 0; i < size; i++)
|
|
result[i] = low + i
|
|
return result
|
|
}
|
|
|
|
describe("ReopenProjectMenuManager", () => {
|
|
let menuManager, commandRegistry, config, historyManager, reopenProjects
|
|
let commandDisposable, configDisposable, historyDisposable
|
|
|
|
beforeEach(() => {
|
|
menuManager = jasmine.createSpyObj('MenuManager', ['add'])
|
|
menuManager.add.andReturn(new Disposable())
|
|
|
|
commandRegistry = jasmine.createSpyObj('CommandRegistry', ['add'])
|
|
commandDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
|
commandRegistry.add.andReturn(commandDisposable)
|
|
|
|
config = jasmine.createSpyObj('Config', ['onDidChange', 'get'])
|
|
config.get.andReturn(10)
|
|
configDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
|
config.didChangeListener = { }
|
|
config.onDidChange.andCallFake((key, fn) => {
|
|
config.didChangeListener[key] = fn
|
|
return configDisposable
|
|
})
|
|
|
|
historyManager = jasmine.createSpyObj('historyManager', ['getProjects','onDidChangeProjects'])
|
|
historyManager.getProjects.andReturn([])
|
|
historyDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
|
historyManager.onDidChangeProjects.andCallFake((fn) => {
|
|
historyManager.changeProjectsListener = fn
|
|
return historyDisposable
|
|
})
|
|
|
|
openFunction = jasmine.createSpy()
|
|
reopenProjects = new ReopenProjectMenuManager({menu:menuManager, commands: commandRegistry, history: historyManager, config, open:openFunction})
|
|
})
|
|
|
|
describe("constructor", () => {
|
|
it("registers the 'reopen-project' command function", () => {
|
|
expect(commandRegistry.add).toHaveBeenCalled()
|
|
const cmdCall = commandRegistry.add.calls[0]
|
|
expect(cmdCall.args.length).toBe(2)
|
|
expect(cmdCall.args[0]).toBe('atom-workspace')
|
|
expect(typeof cmdCall.args[1]['application:reopen-project']).toBe('function')
|
|
})
|
|
})
|
|
|
|
describe("dispose", () => {
|
|
it("disposes of the history, command and config disposables", () => {
|
|
reopenProjects.dispose()
|
|
expect(historyDisposable.dispose).toHaveBeenCalled()
|
|
expect(configDisposable.dispose).toHaveBeenCalled()
|
|
expect(commandDisposable.dispose).toHaveBeenCalled()
|
|
})
|
|
|
|
it("disposes of the menu disposable once used", () => {
|
|
const menuDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
|
menuManager.add.andReturn(menuDisposable)
|
|
reopenProjects.update()
|
|
expect(menuDisposable.dispose).not.toHaveBeenCalled()
|
|
reopenProjects.dispose()
|
|
expect(menuDisposable.dispose).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe("the command", () => {
|
|
it("calls open with the paths of the project specified by the detail index", () => {
|
|
historyManager.getProjects.andReturn([ { paths: ['/a'] }, { paths: ['/b', 'c:\\'] }])
|
|
reopenProjects.update()
|
|
|
|
reopenProjectCommand = commandRegistry.add.calls[0].args[1]['application:reopen-project']
|
|
reopenProjectCommand({ detail: { index: 1 } })
|
|
|
|
expect(openFunction).toHaveBeenCalled()
|
|
expect(openFunction.calls[0].args[0]).toEqual(['/b', 'c:\\'])
|
|
})
|
|
|
|
it("does not call open when no command detail is supplied", () => {
|
|
reopenProjectCommand = commandRegistry.add.calls[0].args[1]['application:reopen-project']
|
|
reopenProjectCommand({})
|
|
|
|
expect(openFunction).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it("does not call open when no command detail index is supplied", () => {
|
|
reopenProjectCommand = commandRegistry.add.calls[0].args[1]['application:reopen-project']
|
|
reopenProjectCommand({ detail: { anything: 'here' } })
|
|
|
|
expect(openFunction).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe("update", () => {
|
|
it("adds menu items to MenuManager based on projects from HistoryManager", () => {
|
|
historyManager.getProjects.andReturn([ { paths: ['/a'] }, { paths: ['/b', 'c:\\'] }])
|
|
reopenProjects.update()
|
|
expect(historyManager.getProjects).toHaveBeenCalled()
|
|
expect(menuManager.add).toHaveBeenCalled()
|
|
const menuArg = menuManager.add.calls[0].args[0]
|
|
expect(menuArg.length).toBe(1)
|
|
expect(menuArg[0].label).toBe('File')
|
|
expect(menuArg[0].submenu.length).toBe(1)
|
|
const projectsMenu = menuArg[0].submenu[0]
|
|
expect(projectsMenu.label).toBe('Reopen Project')
|
|
expect(projectsMenu.submenu.length).toBe(2)
|
|
|
|
const first = projectsMenu.submenu[0]
|
|
expect(first.label).toBe('/a')
|
|
expect(first.command).toBe('application:reopen-project')
|
|
expect(first.commandDetail).toEqual({ index: 0 })
|
|
|
|
const second = projectsMenu.submenu[1]
|
|
expect(second.label).toBe('b, c:\\')
|
|
expect(second.command).toBe('application:reopen-project')
|
|
expect(second.commandDetail).toEqual({ index: 1 })
|
|
})
|
|
|
|
it("adds only the number of menu items specified in the 'core.reopenProjectMenuCount' config", () => {
|
|
historyManager.getProjects.andReturn(numberRange(1, 100).map(i => ({ paths: [ '/test/' + i ] })))
|
|
reopenProjects.update()
|
|
expect(menuManager.add).toHaveBeenCalled()
|
|
const menu = menuManager.add.calls[0].args[0][0]
|
|
expect(menu.label).toBe('File')
|
|
expect(menu.submenu.length).toBe(1)
|
|
expect(menu.submenu[0].label).toBe('Reopen Project')
|
|
expect(menu.submenu[0].submenu.length).toBe(10)
|
|
})
|
|
|
|
it("disposes the previously menu built", () => {
|
|
const menuDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
|
menuManager.add.andReturn(menuDisposable)
|
|
reopenProjects.update()
|
|
expect(menuDisposable.dispose).not.toHaveBeenCalled()
|
|
reopenProjects.update()
|
|
expect(menuDisposable.dispose).toHaveBeenCalled()
|
|
})
|
|
|
|
it("is called when the Config changes for 'core.reopenProjectMenuCount'", () => {
|
|
historyManager.getProjects.andReturn(numberRange(1, 100).map(i => ({ paths: [ '/test/' + i ] })))
|
|
reopenProjects.update()
|
|
config.get.andReturn(25)
|
|
config.didChangeListener['core.reopenProjectMenuCount']({oldValue:10, newValue: 25})
|
|
|
|
const finalArgs = menuManager.add.calls[1].args[0]
|
|
const projectsMenu = finalArgs[0].submenu[0].submenu
|
|
|
|
expect(projectsMenu.length).toBe(25)
|
|
})
|
|
|
|
it("is called when the HistoryManager's projects change", () => {
|
|
reopenProjects.update()
|
|
historyManager.getProjects.andReturn([ { paths: ['/a'] }, { paths: ['/b', 'c:\\'] } ])
|
|
historyManager.changeProjectsListener()
|
|
expect(menuManager.add.calls.length).toBe(2)
|
|
|
|
const finalArgs = menuManager.add.calls[1].args[0]
|
|
const projectsMenu = finalArgs[0].submenu[0]
|
|
|
|
const first = projectsMenu.submenu[0]
|
|
expect(first.label).toBe('/a')
|
|
expect(first.command).toBe('application:reopen-project')
|
|
expect(first.commandDetail).toEqual({ index: 0 })
|
|
|
|
const second = projectsMenu.submenu[1]
|
|
expect(second.label).toBe('b, c:\\')
|
|
expect(second.command).toBe('application:reopen-project')
|
|
expect(second.commandDetail).toEqual({ index: 1 })
|
|
})
|
|
})
|
|
|
|
describe("updateProjects", () => {
|
|
it("creates correct menu items commands for recent projects", () => {
|
|
const projects = [
|
|
{ paths: [ '/users/neila' ] },
|
|
{ paths: [ '/users/buzza', 'users/michaelc' ] }
|
|
]
|
|
|
|
const menu = ReopenProjectMenuManager.createProjectsMenu(projects)
|
|
expect(menu.label).toBe('File')
|
|
expect(menu.submenu.length).toBe(1)
|
|
|
|
const recentMenu = menu.submenu[0]
|
|
expect(recentMenu.label).toBe('Reopen Project')
|
|
expect(recentMenu.submenu.length).toBe(2)
|
|
|
|
const first = recentMenu.submenu[0]
|
|
expect(first.label).toBe('/users/neila')
|
|
expect(first.command).toBe('application:reopen-project')
|
|
expect(first.commandDetail).toEqual({index: 0})
|
|
|
|
const second = recentMenu.submenu[1]
|
|
expect(second.label).toBe('buzza, michaelc')
|
|
expect(second.command).toBe('application:reopen-project')
|
|
expect(second.commandDetail).toEqual({index: 1})
|
|
})
|
|
})
|
|
|
|
describe("createLabel", () => {
|
|
it("returns the Unix path unchanged if there is only one", () => {
|
|
const label = ReopenProjectMenuManager.createLabel({ paths: ['/a/b/c/d/e/f'] })
|
|
expect(label).toBe('/a/b/c/d/e/f')
|
|
})
|
|
|
|
it("returns the Windows path unchanged if there is only one", () => {
|
|
const label = ReopenProjectMenuManager.createLabel({ paths: ['c:\\missions\\apollo11'] })
|
|
expect(label).toBe('c:\\missions\\apollo11')
|
|
})
|
|
|
|
it("returns the URL unchanged if there is only one", () => {
|
|
const label = ReopenProjectMenuManager.createLabel({ paths: ['https://launch.pad/apollo/11'] })
|
|
expect(label).toBe('https://launch.pad/apollo/11')
|
|
})
|
|
|
|
it("returns a comma-seperated list of base names if there are multiple", () => {
|
|
const project = { paths: [ '/var/one', '/usr/bin/two', '/etc/mission/control/three' ] }
|
|
const label = ReopenProjectMenuManager.createLabel(project)
|
|
expect(label).toBe('one, two, three')
|
|
})
|
|
|
|
describe("betterBaseName", () => {
|
|
it("returns the standard base name for an absolute Unix path", () => {
|
|
const name = ReopenProjectMenuManager.betterBaseName('/one/to/three')
|
|
expect(name).toBe('three')
|
|
})
|
|
|
|
it("returns the standard base name for a relative Windows path", () => {
|
|
if (process.platform === 'win32') {
|
|
const name = ReopenProjectMenuManager.betterBaseName('.\\one\\two')
|
|
expect(name).toBe('two')
|
|
}
|
|
})
|
|
|
|
it("returns the standard base name for an absolute Windows path", () => {
|
|
if (process.platform === 'win32') {
|
|
const name = ReopenProjectMenuManager.betterBaseName('c:\\missions\\apollo\\11')
|
|
expect(name).toBe('11')
|
|
}
|
|
})
|
|
|
|
it("returns the drive root for a Windows drive name", () => {
|
|
const name = ReopenProjectMenuManager.betterBaseName('d:')
|
|
expect(name).toBe('d:\\')
|
|
})
|
|
|
|
it("returns the drive root for a Windows drive root", () => {
|
|
const name = ReopenProjectMenuManager.betterBaseName('e:\\')
|
|
expect(name).toBe('e:\\')
|
|
})
|
|
|
|
it("returns the final path for a URI", () => {
|
|
const name = ReopenProjectMenuManager.betterBaseName('https://something/else')
|
|
expect(name).toBe('else')
|
|
})
|
|
})
|
|
})
|
|
})
|