mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
159 lines
5.6 KiB
CoffeeScript
159 lines
5.6 KiB
CoffeeScript
ContextMenuManager = require '../src/context-menu-manager'
|
|
|
|
describe "ContextMenuManager", ->
|
|
[contextMenu, parent, child, grandchild] = []
|
|
|
|
beforeEach ->
|
|
{resourcePath} = atom.getLoadSettings()
|
|
contextMenu = new ContextMenuManager({resourcePath, keymapManager: atom.keymaps})
|
|
|
|
parent = document.createElement("div")
|
|
child = document.createElement("div")
|
|
grandchild = document.createElement("div")
|
|
parent.classList.add('parent')
|
|
child.classList.add('child')
|
|
grandchild.classList.add('grandchild')
|
|
child.appendChild(grandchild)
|
|
parent.appendChild(child)
|
|
|
|
describe "::add(itemsBySelector)", ->
|
|
it "can add top-level menu items that can be removed with the returned disposable", ->
|
|
disposable = contextMenu.add
|
|
'.parent': [{label: 'A', command: 'a'}]
|
|
'.child': [{label: 'B', command: 'b'}]
|
|
'.grandchild': [{label: 'C', command: 'c'}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
|
{label: 'C', command: 'c'}
|
|
{label: 'B', command: 'b'}
|
|
{label: 'A', command: 'a'}
|
|
]
|
|
|
|
disposable.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
|
|
|
it "can add submenu items to existing menus that can be removed with the returned disposable", ->
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', submenu: [{label: 'B', command: 'b'}]}]
|
|
disposable2 = contextMenu.add
|
|
'.grandchild': [{label: 'A', submenu: [{label: 'C', command: 'c'}]}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
|
label: 'A',
|
|
submenu: [
|
|
{label: 'B', command: 'b'}
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
}]
|
|
|
|
disposable2.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
|
label: 'A',
|
|
submenu: [
|
|
{label: 'B', command: 'b'}
|
|
]
|
|
}]
|
|
|
|
disposable1.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
|
|
|
it "favors the most specific / recently added item in the case of a duplicate label", ->
|
|
grandchild.classList.add('foo')
|
|
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'a'}]
|
|
disposable2 = contextMenu.add
|
|
'.grandchild.foo': [{label: 'A', command: 'b'}]
|
|
disposable3 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'c'}]
|
|
disposable4 = contextMenu.add
|
|
'.child': [{label: 'A', command: 'd'}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'b'}]
|
|
|
|
disposable2.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'c'}]
|
|
|
|
disposable3.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}]
|
|
|
|
disposable1.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'd'}]
|
|
|
|
it "allows multiple separators, but not adjacent to each other", ->
|
|
contextMenu.add
|
|
'.grandchild': [
|
|
{label: 'A', command: 'a'},
|
|
{type: 'separator'},
|
|
{type: 'separator'},
|
|
{label: 'B', command: 'b'},
|
|
{type: 'separator'},
|
|
{type: 'separator'},
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
|
{label: 'A', command: 'a'},
|
|
{type: 'separator'},
|
|
{label: 'B', command: 'b'},
|
|
{type: 'separator'},
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
|
|
it "excludes items marked for display in devMode unless in dev mode", ->
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'a', devMode: true}, {label: 'B', command: 'b', devMode: false}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'B', command: 'b'}]
|
|
|
|
contextMenu.devMode = true
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}, {label: 'B', command: 'b'}]
|
|
|
|
it "allows items to be associated with `created` hooks which are invoked on template construction with the item and event", ->
|
|
createdEvent = null
|
|
|
|
item = {
|
|
label: 'A',
|
|
command: 'a',
|
|
created: (event) ->
|
|
@command = 'b'
|
|
createdEvent = event
|
|
}
|
|
|
|
contextMenu.add('.grandchild': [item])
|
|
|
|
dispatchedEvent = {target: grandchild}
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'b'}]
|
|
expect(item.command).toBe 'a' # doesn't modify original item template
|
|
expect(createdEvent).toBe dispatchedEvent
|
|
|
|
it "allows items to be associated with `shouldDisplay` hooks which are invoked on construction to determine whether the item should be included", ->
|
|
shouldDisplayEvent = null
|
|
shouldDisplay = true
|
|
|
|
item = {
|
|
label: 'A',
|
|
command: 'a',
|
|
shouldDisplay: (event) ->
|
|
@foo = 'bar'
|
|
shouldDisplayEvent = event
|
|
shouldDisplay
|
|
}
|
|
contextMenu.add('.grandchild': [item])
|
|
|
|
dispatchedEvent = {target: grandchild}
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'a'}]
|
|
expect(item.foo).toBeUndefined() # doesn't modify original item template
|
|
expect(shouldDisplayEvent).toBe dispatchedEvent
|
|
|
|
shouldDisplay = false
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
|
|
|
|
it "throws an error when the selector is invalid", ->
|
|
addError = null
|
|
try
|
|
contextMenu.add '<>': [{label: 'A', command: 'a'}]
|
|
catch error
|
|
addError = error
|
|
expect(addError.message).toContain('<>')
|