@neo4j-cypher/react-codemirror 2.0.0-next.3 → 2.0.0-next.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/{types/CypherEditor.d.ts → CypherEditor.d.ts} +10 -1
- package/dist/CypherEditor.js +206 -0
- package/dist/CypherEditor.js.map +1 -0
- package/dist/e2e_tests/auto-completion.spec.js +129 -0
- package/dist/e2e_tests/auto-completion.spec.js.map +1 -0
- package/dist/e2e_tests/e2e-utils.js +52 -0
- package/dist/e2e_tests/e2e-utils.js.map +1 -0
- package/dist/e2e_tests/extra-keybindings.spec.js +44 -0
- package/dist/e2e_tests/extra-keybindings.spec.js.map +1 -0
- package/dist/e2e_tests/history-navigation.spec.js +136 -0
- package/dist/e2e_tests/history-navigation.spec.js.map +1 -0
- package/dist/e2e_tests/performance-test.spec.d.ts +6 -0
- package/dist/e2e_tests/performance-test.spec.js +96 -0
- package/dist/e2e_tests/performance-test.spec.js.map +1 -0
- package/dist/e2e_tests/sanity-checks.spec.js +65 -0
- package/dist/e2e_tests/sanity-checks.spec.js.map +1 -0
- package/dist/e2e_tests/signature-help.spec.js +151 -0
- package/dist/e2e_tests/signature-help.spec.js.map +1 -0
- package/dist/e2e_tests/syntax-highlighting.spec.js +91 -0
- package/dist/e2e_tests/syntax-highlighting.spec.js.map +1 -0
- package/dist/e2e_tests/syntax-validation.spec.js +79 -0
- package/dist/e2e_tests/syntax-validation.spec.js.map +1 -0
- package/dist/history-navigation.js +163 -0
- package/dist/history-navigation.js.map +1 -0
- package/dist/{types/icons.d.ts → icons.d.ts} +1 -1
- package/dist/icons.js +62 -0
- package/dist/icons.js.map +1 -0
- package/dist/{types/index.d.ts → index.d.ts} +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lang-cypher/autocomplete.js +56 -0
- package/dist/lang-cypher/autocomplete.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/constants.d.ts +9 -0
- package/dist/lang-cypher/constants.js +65 -0
- package/dist/lang-cypher/constants.js.map +1 -0
- package/dist/lang-cypher/contants.test.js +102 -0
- package/dist/lang-cypher/contants.test.js.map +1 -0
- package/dist/lang-cypher/create-cypher-theme.js +144 -0
- package/dist/lang-cypher/create-cypher-theme.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/lang-cypher.d.ts +3 -1
- package/dist/lang-cypher/lang-cypher.js +24 -0
- package/dist/lang-cypher/lang-cypher.js.map +1 -0
- package/dist/lang-cypher/lint-worker.d.ts +8 -0
- package/dist/lang-cypher/lint-worker.js +4 -0
- package/dist/lang-cypher/lint-worker.js.map +1 -0
- package/dist/lang-cypher/parser-adapter.d.ts +19 -0
- package/dist/lang-cypher/parser-adapter.js +113 -0
- package/dist/lang-cypher/parser-adapter.js.map +1 -0
- package/dist/lang-cypher/signature-help.d.ts +4 -0
- package/dist/lang-cypher/signature-help.js +77 -0
- package/dist/lang-cypher/signature-help.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/syntax-validation.d.ts +2 -0
- package/dist/lang-cypher/syntax-validation.js +68 -0
- package/dist/lang-cypher/syntax-validation.js.map +1 -0
- package/dist/lang-cypher/theme-icons.js +22 -0
- package/dist/lang-cypher/theme-icons.js.map +1 -0
- package/dist/ndl-tokens-copy.js +380 -0
- package/dist/ndl-tokens-copy.js.map +1 -0
- package/dist/ndl-tokens-copy.test.js +11 -0
- package/dist/ndl-tokens-copy.test.js.map +1 -0
- package/dist/neo4j-setup.js +86 -0
- package/dist/neo4j-setup.js.map +1 -0
- package/dist/themes.js +114 -0
- package/dist/themes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +15 -18
- package/src/CypherEditor.tsx +38 -6
- package/src/e2e_tests/performance-test.spec.tsx +100 -13
- package/src/e2e_tests/sanity-checks.spec.tsx +8 -3
- package/src/e2e_tests/signature-help.spec.tsx +312 -0
- package/src/icons.ts +3 -0
- package/src/index.ts +1 -1
- package/src/lang-cypher/autocomplete.ts +6 -1
- package/src/lang-cypher/constants.ts +23 -0
- package/src/lang-cypher/create-cypher-theme.ts +4 -0
- package/src/lang-cypher/lang-cypher.ts +16 -7
- package/src/lang-cypher/lint-worker.ts +14 -0
- package/src/lang-cypher/parser-adapter.ts +145 -0
- package/src/lang-cypher/signature-help.ts +102 -0
- package/src/lang-cypher/syntax-validation.ts +70 -4
- package/src/themes.ts +2 -0
- package/dist/cjs/index.cjs +0 -1440
- package/dist/cjs/index.cjs.map +0 -7
- package/dist/esm/index.mjs +0 -1463
- package/dist/esm/index.mjs.map +0 -7
- package/dist/types/e2e_tests/mock-data.d.ts +0 -3779
- package/dist/types/lang-cypher/ParserAdapter.d.ts +0 -14
- package/dist/types/tsconfig.tsbuildinfo +0 -1
- package/src/e2e_tests/mock-data.ts +0 -4310
- package/src/lang-cypher/ParserAdapter.ts +0 -92
- /package/dist/{types/e2e_tests → e2e_tests}/auto-completion.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/e2e-utils.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/extra-keybindings.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/history-navigation.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/sanity-checks.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests/performance-test.spec.d.ts → e2e_tests/signature-help.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/syntax-highlighting.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/syntax-validation.spec.d.ts +0 -0
- /package/dist/{types/history-navigation.d.ts → history-navigation.d.ts} +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/autocomplete.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/contants.test.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/create-cypher-theme.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/theme-icons.d.ts +0 -0
- /package/dist/{types/ndl-tokens-copy.d.ts → ndl-tokens-copy.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.test.d.ts → ndl-tokens-copy.test.d.ts} +0 -0
- /package/dist/{types/neo4j-setup.d.ts → neo4j-setup.d.ts} +0 -0
- /package/dist/{types/themes.d.ts → themes.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @neo4j-cypher/react-codemirror
|
|
2
2
|
|
|
3
|
+
## 2.0.0-next.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8cc77c6: Add support for console commands
|
|
8
|
+
- 1e210cb: Moves semantic analysis to a separate worker file
|
|
9
|
+
- Updated dependencies [8cc77c6]
|
|
10
|
+
- Updated dependencies [1e210cb]
|
|
11
|
+
- Updated dependencies [f6d20b2]
|
|
12
|
+
- @neo4j-cypher/language-support@2.0.0-next.3
|
|
13
|
+
|
|
14
|
+
## 2.0.0-next.4
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 8de605b: Improved history prop change detection
|
|
19
|
+
- Updated dependencies [17909e3]
|
|
20
|
+
- @neo4j-cypher/language-support@2.0.0-next.2
|
|
21
|
+
|
|
3
22
|
## 2.0.0-next.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -38,6 +38,10 @@ export interface CypherEditorProps {
|
|
|
38
38
|
* @default false
|
|
39
39
|
*/
|
|
40
40
|
autofocus?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Where to place the cursor in the query. Cannot be enabled at the same time than autofocus
|
|
43
|
+
*/
|
|
44
|
+
offset?: number;
|
|
41
45
|
/**
|
|
42
46
|
* Whether the editor should wrap lines.
|
|
43
47
|
*
|
|
@@ -78,7 +82,10 @@ export interface CypherEditorProps {
|
|
|
78
82
|
*/
|
|
79
83
|
onChange?(value: string, viewUpdate: ViewUpdate): void;
|
|
80
84
|
}
|
|
81
|
-
|
|
85
|
+
type CypherEditorState = {
|
|
86
|
+
cypherSupportEnabled: boolean;
|
|
87
|
+
};
|
|
88
|
+
export declare class CypherEditor extends Component<CypherEditorProps, CypherEditorState> {
|
|
82
89
|
/**
|
|
83
90
|
* The codemirror editor container.
|
|
84
91
|
*/
|
|
@@ -106,8 +113,10 @@ export declare class CypherEditor extends Component<CypherEditorProps> {
|
|
|
106
113
|
*/
|
|
107
114
|
setValueAndFocus(value?: string): void;
|
|
108
115
|
static defaultProps: CypherEditorProps;
|
|
116
|
+
private debouncedOnChange;
|
|
109
117
|
componentDidMount(): void;
|
|
110
118
|
componentDidUpdate(prevProps: CypherEditorProps): void;
|
|
111
119
|
componentWillUnmount(): void;
|
|
112
120
|
render(): React.ReactNode;
|
|
113
121
|
}
|
|
122
|
+
export {};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Annotation, Compartment, EditorState, } from '@codemirror/state';
|
|
3
|
+
import { EditorView, keymap, lineNumbers, } from '@codemirror/view';
|
|
4
|
+
import debounce from 'lodash.debounce';
|
|
5
|
+
import { Component, createRef } from 'react';
|
|
6
|
+
import { replaceHistory, replMode as historyNavigation, } from './history-navigation';
|
|
7
|
+
import { cypher } from './lang-cypher/lang-cypher';
|
|
8
|
+
import { cleanupWorkers } from './lang-cypher/syntax-validation';
|
|
9
|
+
import { basicNeo4jSetup } from './neo4j-setup';
|
|
10
|
+
import { getThemeExtension } from './themes';
|
|
11
|
+
const executeKeybinding = (onExecute) => onExecute
|
|
12
|
+
? [
|
|
13
|
+
{
|
|
14
|
+
key: 'Ctrl-Enter',
|
|
15
|
+
mac: 'Mod-Enter',
|
|
16
|
+
preventDefault: true,
|
|
17
|
+
run: (view) => {
|
|
18
|
+
const doc = view.state.doc.toString();
|
|
19
|
+
if (doc.trim() !== '') {
|
|
20
|
+
onExecute(doc);
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
: [];
|
|
27
|
+
const themeCompartment = new Compartment();
|
|
28
|
+
const keyBindingCompartment = new Compartment();
|
|
29
|
+
const ExternalEdit = Annotation.define();
|
|
30
|
+
export class CypherEditor extends Component {
|
|
31
|
+
/**
|
|
32
|
+
* The codemirror editor container.
|
|
33
|
+
*/
|
|
34
|
+
editorContainer = createRef();
|
|
35
|
+
/**
|
|
36
|
+
* The codemirror editor state.
|
|
37
|
+
*/
|
|
38
|
+
editorState = createRef();
|
|
39
|
+
/**
|
|
40
|
+
* The codemirror editor view.
|
|
41
|
+
*/
|
|
42
|
+
editorView = createRef();
|
|
43
|
+
schemaRef = createRef();
|
|
44
|
+
/**
|
|
45
|
+
* Focus the editor
|
|
46
|
+
*/
|
|
47
|
+
focus() {
|
|
48
|
+
this.editorView.current?.focus();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Move the cursor to the supplied position.
|
|
52
|
+
* For example, to move the cursor to the end of the editor, use `value.length`
|
|
53
|
+
*/
|
|
54
|
+
updateCursorPosition(position) {
|
|
55
|
+
this.editorView.current?.dispatch({
|
|
56
|
+
selection: { anchor: position, head: position },
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Externally set the editor value and focus the editor.
|
|
61
|
+
*/
|
|
62
|
+
setValueAndFocus(value = '') {
|
|
63
|
+
const currentCmValue = this.editorView.current.state?.doc.toString() ?? '';
|
|
64
|
+
this.editorView.current.dispatch({
|
|
65
|
+
changes: {
|
|
66
|
+
from: 0,
|
|
67
|
+
to: currentCmValue.length,
|
|
68
|
+
insert: value,
|
|
69
|
+
},
|
|
70
|
+
selection: { anchor: value.length, head: value.length },
|
|
71
|
+
});
|
|
72
|
+
this.editorView.current?.focus();
|
|
73
|
+
}
|
|
74
|
+
static defaultProps = {
|
|
75
|
+
lint: true,
|
|
76
|
+
schema: {},
|
|
77
|
+
overrideThemeBackgroundColor: false,
|
|
78
|
+
lineWrap: false,
|
|
79
|
+
extraKeybindings: [],
|
|
80
|
+
history: [],
|
|
81
|
+
theme: 'light',
|
|
82
|
+
};
|
|
83
|
+
debouncedOnChange = this.props.onChange
|
|
84
|
+
? debounce(this.props.onChange, 200)
|
|
85
|
+
: undefined;
|
|
86
|
+
componentDidMount() {
|
|
87
|
+
const { theme, extraKeybindings, lineWrap, overrideThemeBackgroundColor, schema, lint, onExecute, } = this.props;
|
|
88
|
+
this.schemaRef.current = {
|
|
89
|
+
schema,
|
|
90
|
+
lint,
|
|
91
|
+
useLightVersion: false,
|
|
92
|
+
setUseLightVersion: (newVal) => {
|
|
93
|
+
if (this.schemaRef.current !== undefined) {
|
|
94
|
+
this.schemaRef.current.useLightVersion = newVal;
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
const themeExtension = getThemeExtension(theme, overrideThemeBackgroundColor);
|
|
99
|
+
const changeListener = this.debouncedOnChange
|
|
100
|
+
? [
|
|
101
|
+
EditorView.updateListener.of((upt) => {
|
|
102
|
+
const wasUserEdit = !upt.transactions.some((tr) => tr.annotation(ExternalEdit));
|
|
103
|
+
if (upt.docChanged && wasUserEdit) {
|
|
104
|
+
const doc = upt.state.doc;
|
|
105
|
+
const value = doc.toString();
|
|
106
|
+
this.debouncedOnChange(value, upt);
|
|
107
|
+
}
|
|
108
|
+
}),
|
|
109
|
+
]
|
|
110
|
+
: [];
|
|
111
|
+
this.editorState.current = EditorState.create({
|
|
112
|
+
extensions: [
|
|
113
|
+
keyBindingCompartment.of(keymap.of([...executeKeybinding(onExecute), ...extraKeybindings])),
|
|
114
|
+
historyNavigation(this.props),
|
|
115
|
+
basicNeo4jSetup(),
|
|
116
|
+
themeCompartment.of(themeExtension),
|
|
117
|
+
changeListener,
|
|
118
|
+
cypher(this.schemaRef.current),
|
|
119
|
+
lineWrap ? EditorView.lineWrapping : [],
|
|
120
|
+
lineNumbers({
|
|
121
|
+
formatNumber: (a, state) => {
|
|
122
|
+
if (state.doc.lines === 1 && this.props.prompt !== undefined) {
|
|
123
|
+
return this.props.prompt;
|
|
124
|
+
}
|
|
125
|
+
return a.toString();
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
],
|
|
129
|
+
doc: this.props.value,
|
|
130
|
+
});
|
|
131
|
+
this.editorView.current = new EditorView({
|
|
132
|
+
state: this.editorState.current,
|
|
133
|
+
parent: this.editorContainer.current,
|
|
134
|
+
});
|
|
135
|
+
if (this.props.autofocus) {
|
|
136
|
+
this.focus();
|
|
137
|
+
if (this.props.value) {
|
|
138
|
+
this.updateCursorPosition(this.props.value.length);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (this.props.offset) {
|
|
142
|
+
this.updateCursorPosition(this.props.offset);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
componentDidUpdate(prevProps) {
|
|
146
|
+
if (!this.editorView.current) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Handle externally set value
|
|
150
|
+
const currentCmValue = this.editorView.current.state?.doc.toString() ?? '';
|
|
151
|
+
if (this.props.value !== undefined && currentCmValue !== this.props.value) {
|
|
152
|
+
this.editorView.current.dispatch({
|
|
153
|
+
changes: {
|
|
154
|
+
from: 0,
|
|
155
|
+
to: currentCmValue.length,
|
|
156
|
+
insert: this.props.value ?? '',
|
|
157
|
+
},
|
|
158
|
+
annotations: [ExternalEdit.of(true)],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Handle theme change
|
|
162
|
+
const didChangeTheme = prevProps.theme !== this.props.theme ||
|
|
163
|
+
prevProps.overrideThemeBackgroundColor !==
|
|
164
|
+
this.props.overrideThemeBackgroundColor;
|
|
165
|
+
if (didChangeTheme) {
|
|
166
|
+
this.editorView.current.dispatch({
|
|
167
|
+
effects: themeCompartment.reconfigure(getThemeExtension(this.props.theme, this.props.overrideThemeBackgroundColor)),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (prevProps.extraKeybindings !== this.props.extraKeybindings ||
|
|
171
|
+
prevProps.onExecute !== this.props.onExecute) {
|
|
172
|
+
this.editorView.current.dispatch({
|
|
173
|
+
effects: keyBindingCompartment.reconfigure(keymap.of([
|
|
174
|
+
...executeKeybinding(this.props.onExecute),
|
|
175
|
+
...this.props.extraKeybindings,
|
|
176
|
+
])),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// This component rerenders on every keystroke and comparing the
|
|
180
|
+
// full lists of editor strings on every render could be expensive.
|
|
181
|
+
const didChangeHistoryEstimate = prevProps.history?.length !== this.props.history?.length ||
|
|
182
|
+
prevProps.history?.[0] !== this.props.history?.[0];
|
|
183
|
+
if (didChangeHistoryEstimate) {
|
|
184
|
+
this.editorView.current.dispatch({
|
|
185
|
+
effects: replaceHistory.of(this.props.history ?? []),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/*
|
|
189
|
+
The cypher configuration is a mutable object that is passed to the cypher language extension.
|
|
190
|
+
Much like how the schema based completions work in the official sql language extension.
|
|
191
|
+
https://github.com/codemirror/lang-sql/blob/4b7b2564dff7cdb1a15f8ccd08142f2cc8a0006f/src/sql.ts#L178C17-L178C18
|
|
192
|
+
*/
|
|
193
|
+
this.schemaRef.current.schema = this.props.schema;
|
|
194
|
+
this.schemaRef.current.lint = this.props.lint;
|
|
195
|
+
}
|
|
196
|
+
componentWillUnmount() {
|
|
197
|
+
this.editorView.current?.destroy();
|
|
198
|
+
cleanupWorkers();
|
|
199
|
+
}
|
|
200
|
+
render() {
|
|
201
|
+
const { className, theme } = this.props;
|
|
202
|
+
const themeClass = typeof theme === 'string' ? `cm-theme-${theme}` : 'cm-theme';
|
|
203
|
+
return (_jsx("div", { ref: this.editorContainer, className: `${themeClass}${className ? ` ${className}` : ''}` }));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=CypherEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CypherEditor.js","sourceRoot":"","sources":["../src/CypherEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { expect, test } from '@playwright/experimental-ct-react';
|
|
3
|
+
import { CypherEditor } from '../CypherEditor';
|
|
4
|
+
test.use({ viewport: { width: 500, height: 500 } });
|
|
5
|
+
test('hello world end 2 end test', async ({ mount }) => {
|
|
6
|
+
const component = await mount(_jsx(CypherEditor, { value: "hello world" }));
|
|
7
|
+
await expect(component).toContainText('hello world');
|
|
8
|
+
await component.update(_jsx(CypherEditor, { value: "RETURN 123" }));
|
|
9
|
+
await expect(component).toContainText('RETURN 123');
|
|
10
|
+
});
|
|
11
|
+
test('can complete in the middle of statement', async ({ mount, page }) => {
|
|
12
|
+
const component = await mount(_jsx(CypherEditor, { value: `MATCH ()
|
|
13
|
+
WHER true
|
|
14
|
+
RETURN n;` }));
|
|
15
|
+
// Move into the statement and trigger autocompletion
|
|
16
|
+
const textField = page.getByRole('textbox');
|
|
17
|
+
await textField.focus();
|
|
18
|
+
await textField.press('ArrowDown');
|
|
19
|
+
await textField.press('ArrowRight');
|
|
20
|
+
await textField.press('ArrowRight');
|
|
21
|
+
await textField.press('ArrowRight');
|
|
22
|
+
await textField.press('ArrowRight');
|
|
23
|
+
await textField.press('Control+ ');
|
|
24
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).toBeVisible();
|
|
25
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('WHERE').click();
|
|
26
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
27
|
+
await expect(component).toContainText('WHERE true');
|
|
28
|
+
});
|
|
29
|
+
test('get completions when typing and can accept completions with tab', async ({ mount, page, }) => {
|
|
30
|
+
const component = await mount(_jsx(CypherEditor, {}));
|
|
31
|
+
const textField = page.getByRole('textbox');
|
|
32
|
+
await textField.fill('RETU');
|
|
33
|
+
await expect(page.locator('.cm-tooltip-autocomplete').getByText('RETURN')).toBeVisible();
|
|
34
|
+
// We need to wait for the editor to realise there is a completion open
|
|
35
|
+
// so that it does not just indent with tab key
|
|
36
|
+
await page.waitForTimeout(500);
|
|
37
|
+
await textField.press('Tab');
|
|
38
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
39
|
+
await expect(component).toContainText('RETURN');
|
|
40
|
+
});
|
|
41
|
+
test('can complete labels', async ({ mount, page }) => {
|
|
42
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
43
|
+
labels: ['Pokemon'],
|
|
44
|
+
} }));
|
|
45
|
+
const textField = page.getByRole('textbox');
|
|
46
|
+
await textField.fill('MATCH (n :P');
|
|
47
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('Pokemon').click();
|
|
48
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
49
|
+
await expect(component).toContainText('MATCH (n :Pokemon');
|
|
50
|
+
});
|
|
51
|
+
test('can update dbschema', async ({ mount, page }) => {
|
|
52
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
53
|
+
labels: ['Pokemon'],
|
|
54
|
+
} }));
|
|
55
|
+
const textField = page.getByRole('textbox');
|
|
56
|
+
await textField.fill('MATCH (n :');
|
|
57
|
+
await expect(page.locator('.cm-tooltip-autocomplete').getByText('Pokemon')).toBeVisible();
|
|
58
|
+
await textField.press('Escape');
|
|
59
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
60
|
+
await component.update(_jsx(CypherEditor, { schema: {
|
|
61
|
+
labels: ['Pokemon', 'Digimon'],
|
|
62
|
+
} }));
|
|
63
|
+
await textField.press('Control+ ');
|
|
64
|
+
await expect(page.locator('.cm-tooltip-autocomplete').getByText('Pokemon')).toBeVisible();
|
|
65
|
+
await expect(page.locator('.cm-tooltip-autocomplete').getByText('Digimon')).toBeVisible();
|
|
66
|
+
});
|
|
67
|
+
test('can complete rel types', async ({ page, mount }) => {
|
|
68
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
69
|
+
relationshipTypes: ['KNOWS'],
|
|
70
|
+
} }));
|
|
71
|
+
const textField = page.getByRole('textbox');
|
|
72
|
+
await textField.fill('MATCH (n)-[:');
|
|
73
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('KNOWS').click();
|
|
74
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
75
|
+
await expect(component).toContainText('MATCH (n)-[:KNOWS');
|
|
76
|
+
});
|
|
77
|
+
test('can complete functions', async ({ page, mount }) => {
|
|
78
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
79
|
+
functionSignatures: {
|
|
80
|
+
function123: { label: 'function123', documentation: 'no docs' },
|
|
81
|
+
},
|
|
82
|
+
} }));
|
|
83
|
+
const textField = page.getByRole('textbox');
|
|
84
|
+
await textField.fill('RETURN func');
|
|
85
|
+
await page
|
|
86
|
+
.locator('.cm-tooltip-autocomplete')
|
|
87
|
+
.getByText('function123')
|
|
88
|
+
.click();
|
|
89
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
90
|
+
await expect(component).toContainText('RETURN function123');
|
|
91
|
+
});
|
|
92
|
+
test('can complete procedures', async ({ page, mount }) => {
|
|
93
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
94
|
+
procedureSignatures: {
|
|
95
|
+
'db.ping': { label: 'db.ping', documentation: 'no docs' },
|
|
96
|
+
},
|
|
97
|
+
} }));
|
|
98
|
+
const textField = page.getByRole('textbox');
|
|
99
|
+
await textField.fill('CALL d');
|
|
100
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('db.ping').click();
|
|
101
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
102
|
+
await expect(component).toContainText('CALL db.ping');
|
|
103
|
+
});
|
|
104
|
+
test('can complete parameters', async ({ page, mount }) => {
|
|
105
|
+
const component = await mount(_jsx(CypherEditor, { schema: {
|
|
106
|
+
parameters: { parameter: { type: 'string' } },
|
|
107
|
+
} }));
|
|
108
|
+
const textField = page.getByRole('textbox');
|
|
109
|
+
await textField.fill('RETURN $p');
|
|
110
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('parameter').click();
|
|
111
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
112
|
+
await expect(component).toContainText('RETURN $parameter');
|
|
113
|
+
});
|
|
114
|
+
test('completes allShortestPaths correctly', async ({ page, mount }) => {
|
|
115
|
+
await mount(_jsx(CypherEditor, { schema: {
|
|
116
|
+
parameters: { parameter: { type: 'string' } },
|
|
117
|
+
} }));
|
|
118
|
+
const textField = page.getByRole('textbox');
|
|
119
|
+
// The first query contains errors on purpose so the
|
|
120
|
+
// syntax errors get triggered before the auto-completion
|
|
121
|
+
await textField.fill('MATCH (n) REURN n; MATCH a');
|
|
122
|
+
await page
|
|
123
|
+
.locator('.cm-tooltip-autocomplete')
|
|
124
|
+
.getByText('allShortestPaths')
|
|
125
|
+
.click();
|
|
126
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
127
|
+
expect(await textField.textContent()).toEqual('MATCH (n) REURN n; MATCH allShortestPaths');
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=auto-completion.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-completion.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/auto-completion.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { expect } from '@playwright/experimental-ct-react';
|
|
2
|
+
export class CypherEditorPage {
|
|
3
|
+
page;
|
|
4
|
+
constructor(page) {
|
|
5
|
+
this.page = page;
|
|
6
|
+
}
|
|
7
|
+
getEditor() {
|
|
8
|
+
return this.page.getByRole('textbox');
|
|
9
|
+
}
|
|
10
|
+
async focusEditor() {
|
|
11
|
+
await this.getEditor().focus();
|
|
12
|
+
}
|
|
13
|
+
editorBackgroundIsUnset() {
|
|
14
|
+
return this.page.locator('.cm-editor').evaluate((e) => {
|
|
15
|
+
const browserDefaultBackgroundColor = 'rgba(0, 0, 0, 0)';
|
|
16
|
+
return (window.getComputedStyle(e).getPropertyValue('background-color') ===
|
|
17
|
+
browserDefaultBackgroundColor);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getHexColorOfLocator(locator) {
|
|
21
|
+
return locator.evaluate((e) => {
|
|
22
|
+
// https://stackoverflow.com/questions/49974145/how-to-convert-rgba-to-hex-color-code-using-javascript
|
|
23
|
+
function RGBAToHexA(rgba, forceRemoveAlpha = false) {
|
|
24
|
+
return ('#' +
|
|
25
|
+
rgba
|
|
26
|
+
.replace(/^rgba?\(|\s+|\)$/g, '')
|
|
27
|
+
.split(',')
|
|
28
|
+
.filter((string, index) => !forceRemoveAlpha || index !== 3)
|
|
29
|
+
.map((string) => parseFloat(string))
|
|
30
|
+
.map((number, index) => index === 3 ? Math.round(number * 255) : number)
|
|
31
|
+
.map((number) => number.toString(16))
|
|
32
|
+
.map((string) => (string.length === 1 ? '0' + string : string))
|
|
33
|
+
.join(''));
|
|
34
|
+
}
|
|
35
|
+
const color = window.getComputedStyle(e).getPropertyValue('color');
|
|
36
|
+
return RGBAToHexA(color);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async checkErrorMessage(queryChunk, expectedMsg) {
|
|
40
|
+
return this.checkNotificationMessage('error', queryChunk, expectedMsg);
|
|
41
|
+
}
|
|
42
|
+
async checkWarningMessage(queryChunk, expectedMsg) {
|
|
43
|
+
return this.checkNotificationMessage('warning', queryChunk, expectedMsg);
|
|
44
|
+
}
|
|
45
|
+
async checkNotificationMessage(type, queryChunk, expectedMsg) {
|
|
46
|
+
await expect(this.page.locator('.cm-lintRange-' + type).last()).toBeVisible({ timeout: 2000 });
|
|
47
|
+
await this.page.getByText(queryChunk, { exact: true }).hover();
|
|
48
|
+
await expect(this.page.locator('.cm-tooltip-hover').last()).toBeVisible();
|
|
49
|
+
await expect(this.page.getByText(expectedMsg)).toBeVisible();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=e2e-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e-utils.js","sourceRoot":"","sources":["../../src/e2e_tests/e2e-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { expect, test } from '@playwright/experimental-ct-react';
|
|
3
|
+
import { CypherEditor } from '../CypherEditor';
|
|
4
|
+
import { CypherEditorPage } from './e2e-utils';
|
|
5
|
+
test.use({ viewport: { width: 500, height: 500 } });
|
|
6
|
+
test('can add extra keybinding statically', async ({ mount, page }) => {
|
|
7
|
+
const editorPage = new CypherEditorPage(page);
|
|
8
|
+
let hasRun = false;
|
|
9
|
+
const component = await mount(_jsx(CypherEditor, { extraKeybindings: [
|
|
10
|
+
{
|
|
11
|
+
key: 'a',
|
|
12
|
+
preventDefault: true,
|
|
13
|
+
run: () => {
|
|
14
|
+
hasRun = true;
|
|
15
|
+
return true;
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
] }));
|
|
19
|
+
await editorPage.getEditor().press('a');
|
|
20
|
+
await expect(component).not.toHaveText('a');
|
|
21
|
+
expect(hasRun).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
test('can add extra keybinding dymanically', async ({ mount, page }) => {
|
|
24
|
+
const editorPage = new CypherEditorPage(page);
|
|
25
|
+
let hasRun = false;
|
|
26
|
+
const component = await mount(_jsx(CypherEditor, {}));
|
|
27
|
+
await editorPage.getEditor().press('a');
|
|
28
|
+
await editorPage.getEditor().press('Escape');
|
|
29
|
+
await expect(component).toContainText('a');
|
|
30
|
+
await component.update(_jsx(CypherEditor, { extraKeybindings: [
|
|
31
|
+
{
|
|
32
|
+
key: 'a',
|
|
33
|
+
preventDefault: true,
|
|
34
|
+
run: () => {
|
|
35
|
+
hasRun = true;
|
|
36
|
+
return true;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
] }));
|
|
40
|
+
await editorPage.getEditor().press('a');
|
|
41
|
+
await expect(component).not.toContainText('aa');
|
|
42
|
+
expect(hasRun).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=extra-keybindings.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra-keybindings.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/extra-keybindings.spec.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AAEpD,IAAI,CAAC,qCAAqC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;IACpE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,SAAS,GAAG,MAAM,KAAK,CAC3B,KAAC,YAAY,IACX,gBAAgB,EAAE;YAChB;gBACE,GAAG,EAAE,GAAG;gBACR,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,GAAG,EAAE;oBACR,MAAM,GAAG,IAAI,CAAC;oBACd,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;SACF,GACD,CACH,CAAC;IAEF,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAExC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sCAAsC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;IACrE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,KAAC,YAAY,KAAG,CAAC,CAAC;IAChD,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAE3C,MAAM,SAAS,CAAC,MAAM,CACpB,KAAC,YAAY,IACX,gBAAgB,EAAE;YAChB;gBACE,GAAG,EAAE,GAAG;gBACR,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,GAAG,EAAE;oBACR,MAAM,GAAG,IAAI,CAAC;oBACd,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;SACF,GACD,CACH,CAAC;IAEF,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC"}
|