Skip to content
This repository was archived by the owner on Apr 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions browser/src/Editor/NeovimEditor/NeovimPopupMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,15 @@ export class NeovimPopupMenu {
}

private _renderCompletionMenu(selectedIndex: number): void {
let itemsToRender: IContextMenuItem[] = []
let adjustedIndex = selectedIndex

if (selectedIndex < 10) {
itemsToRender = this._lastItems.slice(0, 10)
} else {
itemsToRender = this._lastItems.slice(selectedIndex - 9, selectedIndex + 1)
adjustedIndex = itemsToRender.length - 1
}

const itemsToRender: IContextMenuItem[] = this._lastItems
const highlightColor = this._colors.getColor("contextMenu.highlight")

const completionElement = (
<ContextMenuView
visible={true}
base={""}
entries={itemsToRender}
selectedIndex={adjustedIndex}
selectedIndex={selectedIndex}
backgroundColor={"black"}
borderColor={"black"}
highlightColor={highlightColor}
Expand Down
20 changes: 12 additions & 8 deletions browser/src/Services/ContextMenu/ContextMenuComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* ContextMenu.tsx
*/

import * as take from "lodash/take"
import * as React from "react"
import * as types from "vscode-languageserver-types"

Expand Down Expand Up @@ -46,11 +45,19 @@ export class ContextMenuView extends React.PureComponent<IContextMenuProps, {}>
return null
}

let entriesToRender: IContextMenuItem[] = []
let adjustedIndex = this.props.selectedIndex

// TODO: sync max display items (10) with value in Reducer.autoCompletionReducer() (Reducer.ts)
const firstTenEntries = take(this.props.entries, 10)
if (adjustedIndex < 10) {
entriesToRender = this.props.entries.slice(0, 10)
} else {
entriesToRender = this.props.entries.slice(adjustedIndex - 9, adjustedIndex + 1)
adjustedIndex = entriesToRender.length - 1
}

const entries = firstTenEntries.map((s, i) => {
const isSelected = i === this.props.selectedIndex
const entries = entriesToRender.map((s, i) => {
const isSelected = i === adjustedIndex

return (
<ContextMenuItem
Expand All @@ -63,10 +70,7 @@ export class ContextMenuView extends React.PureComponent<IContextMenuProps, {}>
)
})

const selectedItemDocumentation = getDocumentationFromItems(
firstTenEntries,
this.props.selectedIndex,
)
const selectedItemDocumentation = getDocumentationFromItems(entriesToRender, adjustedIndex)
return (
<div className="autocompletion enable-mouse">
<div className="entries">{entries}</div>
Expand Down
105 changes: 105 additions & 0 deletions ui-tests/ContextMenuComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { mount, ReactWrapper } from "enzyme"
import * as React from "react"
import {
ContextMenuItem,
ContextMenuView,
IContextMenuItem,
IContextMenuItemProps,
} from "./../browser/src/Services/ContextMenu/ContextMenuComponent"

describe("<ContextMenuView />", () => {
it("shows less than 10 items", () => {
const itemsToRender: IContextMenuItem[] = createItems(8)

const wrapper = mount(
<ContextMenuView
visible={true}
base={""}
entries={itemsToRender}
selectedIndex={5}
backgroundColor={"black"}
borderColor={"black"}
highlightColor={"grey"}
foregroundColor={"white"}
/>,
)

// expect(wrapper.html()).toEqual("")
const renderedItems = wrapper.find(ContextMenuItem)
expect(renderedItems).toHaveLength(8)

expectRenderedItem(renderedItems.at(0), false, "label_0", "detail of item 0")
expectRenderedItem(renderedItems.at(1), false, "label_1", "detail of item 1")
expectRenderedItem(renderedItems.at(2), false, "label_2", "detail of item 2")
expectRenderedItem(renderedItems.at(3), false, "label_3", "detail of item 3")
expectRenderedItem(renderedItems.at(4), false, "label_4", "detail of item 4")
expectRenderedItem(renderedItems.at(5), true, "label_5", "detail of item 5")
expectRenderedItem(renderedItems.at(6), false, "label_6", "detail of item 6")
expectRenderedItem(renderedItems.at(7), false, "label_7", "detail of item 7")
})

it("scrolls when displaying more than 10 items", () => {
const itemsToRender: IContextMenuItem[] = createItems(18)

const wrapper = mount(
<ContextMenuView
visible={true}
base={""}
entries={itemsToRender}
selectedIndex={14}
backgroundColor={"black"}
borderColor={"black"}
highlightColor={"grey"}
foregroundColor={"white"}
/>,
)

const renderedItems = wrapper.find(ContextMenuItem)
expect(renderedItems).toHaveLength(10)

expectRenderedItem(renderedItems.at(0), false, "label_5", "detail of item 5")
expectRenderedItem(renderedItems.at(1), false, "label_6", "detail of item 6")
expectRenderedItem(renderedItems.at(2), false, "label_7", "detail of item 7")
expectRenderedItem(renderedItems.at(3), false, "label_8", "detail of item 8")
expectRenderedItem(renderedItems.at(4), false, "label_9", "detail of item 9")
expectRenderedItem(renderedItems.at(5), false, "label_10", "detail of item 10")
expectRenderedItem(renderedItems.at(6), false, "label_11", "detail of item 11")
expectRenderedItem(renderedItems.at(7), false, "label_12", "detail of item 12")
expectRenderedItem(renderedItems.at(8), false, "label_13", "detail of item 13")
expectRenderedItem(renderedItems.at(9), true, "label_14", "detail of item 14")
})
})

function createItems(count: number): IContextMenuItem[] {
const items: IContextMenuItem[] = []

for (let i = 0; i < count; i++) {
items.push({
label: "label_" + i,
detail: "detail of item " + i,
})
}

return items
}

function expectRenderedItem(
item: ReactWrapper<IContextMenuItemProps, any>,
selected: boolean,
label: string,
detail: string,
) {
expect(item.prop("isSelected")).toBe(selected)
expect(
item
.find(".label")
.first()
.text(),
).toEqual(label)
expect(
item
.find(".detail")
.first()
.text(),
).toEqual(detail)
}