Skip to content

Commit

Permalink
Merge pull request #1299 from HerrEmil/procedure-backticks
Browse files Browse the repository at this point in the history
strip backticks around procedure completion items, correct insertion …
  • Loading branch information
HerrEmil authored Mar 2, 2021
2 parents fd73079 + 1a9a26e commit 7714b55
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 56 deletions.
3 changes: 2 additions & 1 deletion e2e_tests/integration/play-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ describe('Play command', () => {
.should('have.length', 1)
.should('contain', 'No guide')
})
it('populates editor on code click', () => {
// Temporary skip of flaky test
it.skip('populates editor on code click', () => {
cy.executeCommand(':clear')
cy.executeCommand(':play movies')

Expand Down
15 changes: 13 additions & 2 deletions src/browser/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,23 @@ declare module 'cypher-editor-support' {
commands?: ConsoleCommand[]
}

interface FunctionSchema {
name: string
signature: string
}

interface ProcedureSchema {
name: string
signature: string
returnItems: FunctionSchema[]
}

export interface EditorSupportSchema {
labels?: string[]
relationshipTypes?: string[]
propertyKeys?: string[]
functions?: string[]
procedures?: string[]
functions?: FunctionSchema[]
procedures?: ProcedureSchema[]
consoleCommands?: ConsoleCommand[]
parameters?: string[]
}
Expand Down
28 changes: 27 additions & 1 deletion src/shared/modules/editor/editorDuck.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import { createBus, createReduxMiddleware } from 'suber'
import {
populateEditorFromUrlEpic,
SET_CONTENT,
NOT_SUPPORTED_URL_PARAM_COMMAND
NOT_SUPPORTED_URL_PARAM_COMMAND,
getText
} from './editorDuck'
import { APP_START, URL_ARGUMENTS_CHANGE } from '../app/appDuck'
import { COMMAND_QUEUED, executeCommand } from '../commands/commandsDuck'
import { EditorSupportCompletionItem } from 'cypher-editor-support'

describe('editorDuck Epics', () => {
let store: any
Expand Down Expand Up @@ -190,3 +192,27 @@ describe('editorDuck Epics', () => {
store.dispatch(action)
})
})

describe('getting expected text from cypher-editor-support', () => {
test('item with procedure type strips surrounding backticks', () => {
const item: EditorSupportCompletionItem = {
type: 'procedure',
view: '',
content: '`apoc.coll.avg`',
postfix: null
}

expect(getText(item)).toEqual('apoc.coll.avg')
})

test('item with non procedure or function type retains backticks', () => {
const item: EditorSupportCompletionItem = {
type: 'label',
view: '',
content: '`a label name wrapped in backticks`',
postfix: null
}

expect(getText(item)).toEqual(item.content)
})
})
141 changes: 89 additions & 52 deletions src/shared/modules/editor/editorDuck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from 'cypher-editor-support'
import { editor, languages } from 'monaco-editor'
import { Action } from 'redux'
import { ActionsObservable, Epic } from 'redux-observable'
import { Epic } from 'redux-observable'
import Rx from 'rxjs/Rx'

import {
Expand All @@ -35,6 +35,7 @@ import { CypherTokensProvider } from 'browser/modules/Editor/CypherTokensProvide
import cypherFunctions from 'browser/modules/Editor/cypher/functions'
import consoleCommands from 'browser/modules/Editor/language/consoleCommands'
import { getUrlParamValue } from 'services/utils'
import { GlobalState } from 'shared/globalState'
import { APP_START, URL_ARGUMENTS_CHANGE } from 'shared/modules/app/appDuck'
import {
commandSources,
Expand All @@ -54,50 +55,71 @@ import {
toRelationshipType
} from 'browser/modules/Editor/editorSchemaConverter'

const NAME = 'editor'
export const SET_CONTENT = `${NAME}/SET_CONTENT`
export const EDIT_CONTENT = `${NAME}/EDIT_CONTENT`
export const FOCUS = `${NAME}/FOCUS`
export const EXPAND = `${NAME}/EXPAND`
export const NOT_SUPPORTED_URL_PARAM_COMMAND = `${NAME}/NOT_SUPPORTED_URL_PARAM_COMMAND`
export const SET_CONTENT = 'editor/SET_CONTENT'
export const EDIT_CONTENT = 'editor/EDIT_CONTENT'
export const FOCUS = 'editor/FOCUS'
export const EXPAND = 'editor/EXPAND'
export const NOT_SUPPORTED_URL_PARAM_COMMAND =
'editor/NOT_SUPPORTED_URL_PARAM_COMMAND'

// Supported commands
const validCommandTypes: any = {
play: (args: any) => `:play ${args.join(' ')}`,
edit: (args: any) => args.join('\n'),
param: (args: any) => `:param ${args.join(' ')}`,
params: (args: any) => `:params ${args.join(' ')}`
const validCommandTypes: { [key: string]: (args: string[]) => string } = {
play: args => `:play ${args.join(' ')}`,
edit: args => args.join('\n'),
param: args => `:param ${args.join(' ')}`,
params: args => `:params ${args.join(' ')}`
}

export const setContent = (newContent: any) => ({
interface SetContentAction {
type: typeof SET_CONTENT
message: string
}

export const setContent = (message: string): SetContentAction => ({
type: SET_CONTENT,
message: newContent
message
})

interface EditContentAction {
type: typeof EDIT_CONTENT
message: string
id: string
isProjectFile: boolean
isStatic: boolean
name: null | string
directory: null
}

interface EditContentOptions {
name?: string | null
isStatic?: boolean
isProjectFile?: boolean
}

export const editContent = (
id: any,
message: any,
id = '',
message: string,
{
directory = null,
name = null,
isStatic = false,
isProjectFile = false
}: any = {}
) => ({
}: EditContentOptions = {}
): EditContentAction => ({
type: EDIT_CONTENT,
message,
id,
isProjectFile,
isStatic,
name,
directory
directory: null
})

export const populateEditorFromUrlEpic = (some$: any, _store: any) => {
export const populateEditorFromUrlEpic: Epic<any, GlobalState> = some$ => {
return some$
.ofType(APP_START)
.merge(some$.ofType(URL_ARGUMENTS_CHANGE))
.delay(1) // Timing issue. Needs to be detached like this
.mergeMap((action: any) => {
.mergeMap(action => {
if (!action.url) {
return Rx.Observable.never()
}
Expand Down Expand Up @@ -139,11 +161,24 @@ export const populateEditorFromUrlEpic = (some$: any, _store: any) => {
})
}

// CypherEditorSupport returns the content attributes of procedures with dots wrapped in backticks, e.g. "`apoc.coll.avg`"
// This function strips any surrounding backticks before we use the .content value in the completion item provider
const stripSurroundingBackticks = (str: string) =>
str.charAt(0) === '`' && str.charAt(str.length - 1) === '`'
? str.substr(1, str.length - 2)
: str

export const getText = (item: EditorSupportCompletionItem): string =>
['function', 'procedure'].includes(item.type)
? stripSurroundingBackticks(item.content)
: item.content

const editorSupport = new CypherEditorSupport('')

export const initializeCypherEditorEpic = (
actions$: ActionsObservable<{ type: typeof APP_START }>
) => {
export const initializeCypherEditorEpic: Epic<
{ type: typeof APP_START },
GlobalState
> = actions$ => {
return actions$
.ofType(APP_START)
.take(1)
Expand Down Expand Up @@ -209,26 +244,30 @@ export const initializeCypherEditorEpic = (
column: position.column - 1
})

const getRange = (type: string, text: string) =>
['consoleCommand', 'label', 'relationshipType'].includes(type)
? { ...range, startColumn: range.startColumn - 1 }
: ['function', 'procedure'].includes(type)
? {
...range,
startColumn:
range.startColumn -
(text.lastIndexOf(word) + word.length + 1)
}
: range

return {
suggestions: items.map((item, index) => ({
label: item.view || item.content,
kind: completionTypes[item.type],
insertText: item.content,
range: ['consoleCommand', 'label', 'relationshipType'].includes(
item.type
)
? { ...range, startColumn: range.startColumn - 1 }
: item.type === 'procedure'
? {
...range,
startColumn:
range.startColumn -
(item.view.lastIndexOf(word) + word.length + 1)
}
: range,
detail: item.postfix || undefined,
sortText: encodeNumberAsSortableString(index)
}))
suggestions: items.map((item, index) => {
const label = getText(item)
return {
label,
kind: completionTypes[item.type],
insertText: label,
range: getRange(item.type, label),
detail: item.postfix || undefined,
sortText: encodeNumberAsSortableString(index)
}
})
}
}
})
Expand All @@ -251,7 +290,7 @@ function encodeNumberAsSortableString(number: number): string {
return `${prefix}${number}`
}

export const updateEditorSupportSchemaEpic: Epic<Action, any> = (
export const updateEditorSupportSchemaEpic: Epic<Action, GlobalState> = (
actions$,
store
) =>
Expand All @@ -261,16 +300,14 @@ export const updateEditorSupportSchemaEpic: Epic<Action, any> = (
const schema = {
consoleCommands,
parameters: Object.keys(state.params),
labels: state.meta.labels.map(toLabel) as string[],
relationshipTypes: state.meta.relationshipTypes.map(
toRelationshipType
) as string[],
propertyKeys: state.meta.properties.map(toPropertyKey) as string[],
labels: state.meta.labels.map(toLabel),
relationshipTypes: state.meta.relationshipTypes.map(toRelationshipType),
propertyKeys: state.meta.properties.map(toPropertyKey),
functions: [
...cypherFunctions,
...state.meta.functions.map(toFunction)
] as string[],
procedures: state.meta.procedures.map(toProcedure) as string[]
],
procedures: state.meta.procedures.map(toProcedure)
}
editorSupport.setSchema(schema)
})
Expand Down

0 comments on commit 7714b55

Please sign in to comment.