@neo4j-cypher/react-codemirror 2.0.0-next.3 → 2.0.0-next.30
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 +257 -0
- package/README.md +3 -2
- package/dist/{types → src}/CypherEditor.d.ts +81 -3
- package/dist/src/CypherEditor.js +336 -0
- package/dist/src/CypherEditor.js.map +1 -0
- package/dist/src/CypherEditor.test.js +154 -0
- package/dist/src/CypherEditor.test.js.map +1 -0
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/e2e_tests/autoCompletion.spec.js +332 -0
- package/dist/src/e2e_tests/autoCompletion.spec.js.map +1 -0
- package/dist/src/e2e_tests/configuration.spec.js +83 -0
- package/dist/src/e2e_tests/configuration.spec.js.map +1 -0
- package/dist/src/e2e_tests/debounce.spec.js +66 -0
- package/dist/src/e2e_tests/debounce.spec.js.map +1 -0
- package/dist/{types/e2e_tests/e2e-utils.d.ts → src/e2e_tests/e2eUtils.d.ts} +2 -0
- package/dist/src/e2e_tests/e2eUtils.js +79 -0
- package/dist/src/e2e_tests/e2eUtils.js.map +1 -0
- package/dist/src/e2e_tests/extraKeybindings.spec.js +43 -0
- package/dist/src/e2e_tests/extraKeybindings.spec.js.map +1 -0
- package/dist/src/e2e_tests/historyNavigation.spec.js +227 -0
- package/dist/src/e2e_tests/historyNavigation.spec.js.map +1 -0
- package/dist/src/e2e_tests/performanceTest.spec.d.ts +6 -0
- package/dist/src/e2e_tests/performanceTest.spec.js +97 -0
- package/dist/src/e2e_tests/performanceTest.spec.js.map +1 -0
- package/dist/src/e2e_tests/sanityChecks.spec.js +53 -0
- package/dist/src/e2e_tests/sanityChecks.spec.js.map +1 -0
- package/dist/src/e2e_tests/signatureHelp.spec.js +228 -0
- package/dist/src/e2e_tests/signatureHelp.spec.js.map +1 -0
- package/dist/src/e2e_tests/snippets.spec.js +62 -0
- package/dist/src/e2e_tests/snippets.spec.js.map +1 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.d.ts +1 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.js +90 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.js.map +1 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.d.ts +1 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.js +126 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.js.map +1 -0
- package/dist/src/historyNavigation.js +163 -0
- package/dist/src/historyNavigation.js.map +1 -0
- package/dist/{types → src}/icons.d.ts +1 -1
- package/dist/src/icons.js +62 -0
- package/dist/src/icons.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lang-cypher/autocomplete.d.ts +6 -0
- package/dist/src/lang-cypher/autocomplete.js +113 -0
- package/dist/src/lang-cypher/autocomplete.js.map +1 -0
- package/dist/{types → src}/lang-cypher/constants.d.ts +11 -0
- package/dist/src/lang-cypher/constants.js +69 -0
- package/dist/src/lang-cypher/constants.js.map +1 -0
- package/dist/src/lang-cypher/contants.test.d.ts +1 -0
- package/dist/src/lang-cypher/contants.test.js +103 -0
- package/dist/src/lang-cypher/contants.test.js.map +1 -0
- package/dist/src/lang-cypher/createCypherTheme.js +183 -0
- package/dist/src/lang-cypher/createCypherTheme.js.map +1 -0
- package/dist/src/lang-cypher/langCypher.d.ts +13 -0
- package/dist/src/lang-cypher/langCypher.js +23 -0
- package/dist/src/lang-cypher/langCypher.js.map +1 -0
- package/dist/src/lang-cypher/lintWorker.mjs +2022 -0
- package/dist/src/lang-cypher/parser-adapter.d.ts +19 -0
- package/dist/src/lang-cypher/parser-adapter.js +113 -0
- package/dist/src/lang-cypher/parser-adapter.js.map +1 -0
- package/dist/src/lang-cypher/signatureHelp.d.ts +4 -0
- package/dist/src/lang-cypher/signatureHelp.js +109 -0
- package/dist/src/lang-cypher/signatureHelp.js.map +1 -0
- package/dist/{types/lang-cypher/syntax-validation.d.ts → src/lang-cypher/syntaxValidation.d.ts} +2 -1
- package/dist/src/lang-cypher/syntaxValidation.js +57 -0
- package/dist/src/lang-cypher/syntaxValidation.js.map +1 -0
- package/dist/src/lang-cypher/themeIcons.js +22 -0
- package/dist/src/lang-cypher/themeIcons.js.map +1 -0
- package/dist/src/lang-cypher/utils.d.ts +2 -0
- package/dist/src/lang-cypher/utils.js +10 -0
- package/dist/src/lang-cypher/utils.js.map +1 -0
- package/dist/src/ndlTokensCopy.d.ts +570 -0
- package/dist/src/ndlTokensCopy.js +571 -0
- package/dist/src/ndlTokensCopy.js.map +1 -0
- package/dist/src/ndlTokensCopy.test.d.ts +1 -0
- package/dist/src/ndlTokensCopy.test.js +12 -0
- package/dist/src/ndlTokensCopy.test.js.map +1 -0
- package/dist/src/neo4jSetup.d.ts +6 -0
- package/dist/src/neo4jSetup.js +120 -0
- package/dist/src/neo4jSetup.js.map +1 -0
- package/dist/src/richClipboardCopier.d.ts +4 -0
- package/dist/src/richClipboardCopier.js +78 -0
- package/dist/src/richClipboardCopier.js.map +1 -0
- package/dist/src/richClipboardCopier.test.d.ts +1 -0
- package/dist/src/richClipboardCopier.test.js +53 -0
- package/dist/src/richClipboardCopier.test.js.map +1 -0
- package/dist/{types → src}/themes.d.ts +1 -1
- package/dist/src/themes.js +93 -0
- package/dist/src/themes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +43 -41
- package/src/CypherEditor.test.tsx +204 -0
- package/src/CypherEditor.tsx +316 -42
- package/src/constants.ts +1 -0
- package/src/e2e_tests/autoCompletion.spec.tsx +571 -0
- package/src/e2e_tests/configuration.spec.tsx +111 -0
- package/src/e2e_tests/debounce.spec.tsx +106 -0
- package/src/e2e_tests/{e2e-utils.ts → e2eUtils.ts} +41 -3
- package/src/e2e_tests/{extra-keybindings.spec.tsx → extraKeybindings.spec.tsx} +1 -3
- package/src/e2e_tests/{history-navigation.spec.tsx → historyNavigation.spec.tsx} +137 -18
- package/src/e2e_tests/performanceTest.spec.tsx +163 -0
- package/src/e2e_tests/{sanity-checks.spec.tsx → sanityChecks.spec.tsx} +7 -22
- package/src/e2e_tests/signatureHelp.spec.tsx +444 -0
- package/src/e2e_tests/snippets.spec.tsx +92 -0
- package/src/e2e_tests/{syntax-highlighting.spec.tsx → syntaxHighlighting.spec.tsx} +26 -24
- package/src/e2e_tests/syntaxValidation.spec.tsx +259 -0
- package/src/{history-navigation.ts → historyNavigation.ts} +1 -1
- package/src/icons.ts +3 -0
- package/src/index.ts +2 -2
- package/src/lang-cypher/autocomplete.ts +99 -18
- package/src/lang-cypher/constants.ts +27 -0
- package/src/lang-cypher/contants.test.ts +6 -2
- package/src/lang-cypher/{create-cypher-theme.ts → createCypherTheme.ts} +45 -2
- package/src/lang-cypher/langCypher.ts +42 -0
- package/src/lang-cypher/lintWorker.mjs +2022 -0
- package/src/lang-cypher/parser-adapter.ts +145 -0
- package/src/lang-cypher/signatureHelp.ts +151 -0
- package/src/lang-cypher/syntaxValidation.ts +72 -0
- package/src/lang-cypher/utils.ts +9 -0
- package/src/{ndl-tokens-copy.test.ts → ndlTokensCopy.test.ts} +2 -1
- package/src/ndlTokensCopy.ts +570 -0
- package/src/{neo4j-setup.tsx → neo4jSetup.tsx} +78 -17
- package/src/richClipboardCopier.test.ts +65 -0
- package/src/richClipboardCopier.ts +99 -0
- package/src/themes.ts +45 -70
- package/src/viteEnv.d.ts +1 -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/index.d.ts +0 -4
- package/dist/types/lang-cypher/ParserAdapter.d.ts +0 -14
- package/dist/types/lang-cypher/autocomplete.d.ts +0 -3
- package/dist/types/lang-cypher/lang-cypher.d.ts +0 -7
- package/dist/types/ndl-tokens-copy.d.ts +0 -379
- package/dist/types/neo4j-setup.d.ts +0 -2
- package/dist/types/tsconfig.tsbuildinfo +0 -1
- package/src/e2e_tests/auto-completion.spec.tsx +0 -232
- package/src/e2e_tests/mock-data.ts +0 -4310
- package/src/e2e_tests/performance-test.spec.tsx +0 -71
- package/src/e2e_tests/syntax-validation.spec.tsx +0 -156
- package/src/lang-cypher/ParserAdapter.ts +0 -92
- package/src/lang-cypher/lang-cypher.ts +0 -32
- package/src/lang-cypher/syntax-validation.ts +0 -24
- package/src/ndl-tokens-copy.ts +0 -379
- /package/dist/{types/e2e_tests/auto-completion.spec.d.ts → src/CypherEditor.test.d.ts} +0 -0
- /package/dist/{types/e2e_tests/extra-keybindings.spec.d.ts → src/e2e_tests/autoCompletion.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/history-navigation.spec.d.ts → src/e2e_tests/configuration.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/performance-test.spec.d.ts → src/e2e_tests/debounce.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/sanity-checks.spec.d.ts → src/e2e_tests/extraKeybindings.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-highlighting.spec.d.ts → src/e2e_tests/historyNavigation.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-validation.spec.d.ts → src/e2e_tests/sanityChecks.spec.d.ts} +0 -0
- /package/dist/{types/lang-cypher/contants.test.d.ts → src/e2e_tests/signatureHelp.spec.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.test.d.ts → src/e2e_tests/snippets.spec.d.ts} +0 -0
- /package/dist/{types/history-navigation.d.ts → src/historyNavigation.d.ts} +0 -0
- /package/dist/{types/lang-cypher/create-cypher-theme.d.ts → src/lang-cypher/createCypherTheme.d.ts} +0 -0
- /package/dist/{types/lang-cypher/theme-icons.d.ts → src/lang-cypher/themeIcons.d.ts} +0 -0
- /package/src/lang-cypher/{theme-icons.ts → themeIcons.ts} +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { EditorView } from '@codemirror/view';
|
|
4
|
+
import { createRef } from 'react';
|
|
5
|
+
import { createRoot } from 'react-dom/client';
|
|
6
|
+
import { act } from 'react-dom/test-utils';
|
|
7
|
+
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
|
|
8
|
+
import { DEBOUNCE_TIME } from './constants';
|
|
9
|
+
import { CypherEditor } from './CypherEditor';
|
|
10
|
+
|
|
11
|
+
const container = document.createElement('div');
|
|
12
|
+
let root: ReturnType<typeof createRoot>;
|
|
13
|
+
|
|
14
|
+
const ref = createRef<CypherEditor>();
|
|
15
|
+
let value = '';
|
|
16
|
+
const onChange = vi.fn((v: string) => {
|
|
17
|
+
value = v;
|
|
18
|
+
rerender();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
global.IS_REACT_ACT_ENVIRONMENT = true;
|
|
22
|
+
const DEBOUNCE_TIME_WITH_MARGIN = DEBOUNCE_TIME + 100;
|
|
23
|
+
|
|
24
|
+
/** Avoids crash in test environment */
|
|
25
|
+
function mockEditorView(editorView: EditorView) {
|
|
26
|
+
editorView.coordsAtPos = vi.fn().mockReturnValue({
|
|
27
|
+
left: 0,
|
|
28
|
+
top: 0,
|
|
29
|
+
right: 0,
|
|
30
|
+
bottom: 0,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function debounce() {
|
|
35
|
+
await new Promise((resolve) =>
|
|
36
|
+
setTimeout(resolve, DEBOUNCE_TIME_WITH_MARGIN),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getEditorValue() {
|
|
41
|
+
return ref.current.editorView.current.state.doc.toString();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function rerender() {
|
|
45
|
+
act(() => {
|
|
46
|
+
root.render(<CypherEditor value={value} onChange={onChange} ref={ref} />);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
root = createRoot(container);
|
|
52
|
+
act(() => {
|
|
53
|
+
root.render(<CypherEditor value={value} onChange={onChange} ref={ref} />);
|
|
54
|
+
});
|
|
55
|
+
mockEditorView(ref.current.editorView.current);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
act(() => {
|
|
60
|
+
root.unmount();
|
|
61
|
+
});
|
|
62
|
+
value = '';
|
|
63
|
+
vi.clearAllMocks();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('editorValue updates props.value after debounce', async () => {
|
|
67
|
+
ref.current.setValueAndFocus('new value');
|
|
68
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
69
|
+
expect(getEditorValue()).toBe('new value');
|
|
70
|
+
expect(value).toBe('');
|
|
71
|
+
await debounce();
|
|
72
|
+
|
|
73
|
+
expect(onChange).toHaveBeenCalledOnce();
|
|
74
|
+
expect(getEditorValue()).toBe('new value');
|
|
75
|
+
expect(value).toBe('new value');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('editorValue updates should not be applied twice', async () => {
|
|
79
|
+
const dispatch = vi.spyOn(ref.current.editorView.current, 'dispatch');
|
|
80
|
+
|
|
81
|
+
ref.current.setValueAndFocus('new value');
|
|
82
|
+
await debounce();
|
|
83
|
+
|
|
84
|
+
expect(onChange).toHaveBeenCalledOnce();
|
|
85
|
+
expect(dispatch).toHaveBeenCalledOnce(); // it gets called once for the initial setValueAndFocus
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('props.value updates editorValue', () => {
|
|
89
|
+
value = 'external value';
|
|
90
|
+
rerender();
|
|
91
|
+
|
|
92
|
+
expect(getEditorValue()).toBe('external value');
|
|
93
|
+
expect(value).toBe('external value');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('props.value set to undefined preserves editorValue', () => {
|
|
97
|
+
// 1. value is set initially
|
|
98
|
+
value = 'initial';
|
|
99
|
+
rerender();
|
|
100
|
+
|
|
101
|
+
// 2. value is set to undefined
|
|
102
|
+
value = undefined;
|
|
103
|
+
rerender();
|
|
104
|
+
|
|
105
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
106
|
+
expect(value).toBeUndefined();
|
|
107
|
+
expect(getEditorValue()).toBe('initial');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// value updates from outside onExecute are overwritten by pending updates
|
|
111
|
+
test.fails('new props.value should cancel onChange', async () => {
|
|
112
|
+
// 1. value is updated internally
|
|
113
|
+
ref.current.setValueAndFocus('update');
|
|
114
|
+
|
|
115
|
+
// 2. editor is rerendered with a new value while a value update is still pending
|
|
116
|
+
value = 'new external value';
|
|
117
|
+
rerender();
|
|
118
|
+
|
|
119
|
+
await debounce();
|
|
120
|
+
|
|
121
|
+
// expect(onChange).not.toHaveBeenCalled();
|
|
122
|
+
expect(getEditorValue()).toBe('new external value');
|
|
123
|
+
expect(value).toBe('new external value');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// value updates from outside onExecute are overwritten by pending updates
|
|
127
|
+
test.fails(
|
|
128
|
+
'new props.value set to same value should cancel onChange',
|
|
129
|
+
async () => {
|
|
130
|
+
// 1. value is set initially
|
|
131
|
+
value = 'same value';
|
|
132
|
+
rerender();
|
|
133
|
+
|
|
134
|
+
// 2. value is updated internally
|
|
135
|
+
ref.current.setValueAndFocus('update');
|
|
136
|
+
|
|
137
|
+
// 3. editor is rerendered with a new value while a value update is still pending
|
|
138
|
+
value = 'same value';
|
|
139
|
+
rerender();
|
|
140
|
+
|
|
141
|
+
await debounce();
|
|
142
|
+
|
|
143
|
+
// expect(onChange).not.toHaveBeenCalled();
|
|
144
|
+
expect(getEditorValue()).toBe('same value');
|
|
145
|
+
expect(value).toBe('same value');
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
test('rerender should not cancel onChange', async () => {
|
|
150
|
+
// 1. value is updated internally
|
|
151
|
+
ref.current.setValueAndFocus('changed');
|
|
152
|
+
|
|
153
|
+
// 2. editor is rerendered while a value update is still pending
|
|
154
|
+
rerender();
|
|
155
|
+
|
|
156
|
+
await debounce();
|
|
157
|
+
|
|
158
|
+
expect(onChange).toHaveBeenCalledOnce();
|
|
159
|
+
expect(getEditorValue()).toBe('changed');
|
|
160
|
+
expect(value).toBe('changed');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('rerender with a previous update should not cancel onChange', async () => {
|
|
164
|
+
// 1. value is updated internally
|
|
165
|
+
ref.current.setValueAndFocus('changed');
|
|
166
|
+
await debounce();
|
|
167
|
+
|
|
168
|
+
// 2. value is updated internally again
|
|
169
|
+
ref.current.setValueAndFocus('new change');
|
|
170
|
+
|
|
171
|
+
// 3. editor is rerendered while a value update is still pending
|
|
172
|
+
rerender();
|
|
173
|
+
|
|
174
|
+
await debounce();
|
|
175
|
+
|
|
176
|
+
expect(onChange).toHaveBeenCalledTimes(2);
|
|
177
|
+
expect(getEditorValue()).toBe('new change');
|
|
178
|
+
expect(value).toBe('new change');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('rerender with prior external update should not cancel onChange', async () => {
|
|
182
|
+
// 1. value is set initially
|
|
183
|
+
ref.current.setValueAndFocus('initial');
|
|
184
|
+
await debounce();
|
|
185
|
+
|
|
186
|
+
// 2. value is updated externally
|
|
187
|
+
value = 'external update';
|
|
188
|
+
rerender();
|
|
189
|
+
|
|
190
|
+
// 3. value is updated internally
|
|
191
|
+
ref.current.setValueAndFocus('internal update');
|
|
192
|
+
|
|
193
|
+
// 4. editor is rerendered while a value update is still pending
|
|
194
|
+
rerender();
|
|
195
|
+
|
|
196
|
+
await debounce();
|
|
197
|
+
|
|
198
|
+
expect(getEditorValue()).toBe('internal update');
|
|
199
|
+
expect(value).toBe('internal update');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('setValueAndFocus should handle CRLF newline characters', () => {
|
|
203
|
+
expect(() => ref.current.setValueAndFocus('new value\r\nnew line')).not.toThrow();
|
|
204
|
+
});
|