@neo4j-cypher/react-codemirror 2.0.0-next.1 → 2.0.0-next.11
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 +86 -0
- package/README.md +4 -1
- package/dist/{types/CypherEditor.d.ts → CypherEditor.d.ts} +69 -8
- package/dist/CypherEditor.js +300 -0
- package/dist/CypherEditor.js.map +1 -0
- package/dist/CypherEditor.test.js +151 -0
- package/dist/CypherEditor.test.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/e2e_tests/autoCompletion.spec.js +267 -0
- package/dist/e2e_tests/autoCompletion.spec.js.map +1 -0
- package/dist/e2e_tests/configuration.spec.js +83 -0
- package/dist/e2e_tests/configuration.spec.js.map +1 -0
- package/dist/e2e_tests/debounce.spec.js +65 -0
- package/dist/e2e_tests/debounce.spec.js.map +1 -0
- package/dist/e2e_tests/e2eUtils.js +60 -0
- package/dist/e2e_tests/e2eUtils.js.map +1 -0
- package/dist/e2e_tests/extraKeybindings.spec.js +43 -0
- package/dist/e2e_tests/extraKeybindings.spec.js.map +1 -0
- package/dist/e2e_tests/historyNavigation.spec.js +227 -0
- package/dist/e2e_tests/historyNavigation.spec.js.map +1 -0
- package/dist/e2e_tests/performanceTest.spec.d.ts +6 -0
- package/dist/e2e_tests/performanceTest.spec.js +96 -0
- package/dist/e2e_tests/performanceTest.spec.js.map +1 -0
- package/dist/e2e_tests/sanityChecks.spec.js +53 -0
- package/dist/e2e_tests/sanityChecks.spec.js.map +1 -0
- package/dist/e2e_tests/signatureHelp.spec.js +179 -0
- package/dist/e2e_tests/signatureHelp.spec.js.map +1 -0
- package/dist/e2e_tests/snippets.spec.js +62 -0
- package/dist/e2e_tests/snippets.spec.js.map +1 -0
- package/dist/e2e_tests/syntaxHighlighting.spec.d.ts +1 -0
- package/dist/e2e_tests/syntaxHighlighting.spec.js +90 -0
- package/dist/e2e_tests/syntaxHighlighting.spec.js.map +1 -0
- package/dist/e2e_tests/syntaxValidation.spec.d.ts +1 -0
- package/dist/e2e_tests/syntaxValidation.spec.js +79 -0
- package/dist/e2e_tests/syntaxValidation.spec.js.map +1 -0
- package/dist/historyNavigation.d.ts +7 -0
- package/dist/historyNavigation.js +163 -0
- package/dist/historyNavigation.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/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lang-cypher/autocomplete.d.ts +6 -0
- package/dist/lang-cypher/autocomplete.js +124 -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.d.ts +1 -0
- package/dist/lang-cypher/contants.test.js +103 -0
- package/dist/lang-cypher/contants.test.js.map +1 -0
- package/dist/lang-cypher/createCypherTheme.js +179 -0
- package/dist/lang-cypher/createCypherTheme.js.map +1 -0
- package/dist/lang-cypher/langCypher.d.ts +14 -0
- package/dist/lang-cypher/langCypher.js +30 -0
- package/dist/lang-cypher/langCypher.js.map +1 -0
- package/dist/lang-cypher/lintWorker.d.ts +8 -0
- package/dist/lang-cypher/lintWorker.js +4 -0
- package/dist/lang-cypher/lintWorker.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/signatureHelp.d.ts +4 -0
- package/dist/lang-cypher/signatureHelp.js +94 -0
- package/dist/lang-cypher/signatureHelp.js.map +1 -0
- package/dist/lang-cypher/syntaxValidation.d.ts +5 -0
- package/dist/lang-cypher/syntaxValidation.js +69 -0
- package/dist/lang-cypher/syntaxValidation.js.map +1 -0
- package/dist/lang-cypher/themeIcons.js +22 -0
- package/dist/lang-cypher/themeIcons.js.map +1 -0
- package/dist/lang-cypher/utils.d.ts +2 -0
- package/dist/lang-cypher/utils.js +10 -0
- package/dist/lang-cypher/utils.js.map +1 -0
- package/dist/ndlTokensCopy.js +380 -0
- package/dist/ndlTokensCopy.js.map +1 -0
- package/dist/ndlTokensCopy.test.d.ts +1 -0
- package/dist/ndlTokensCopy.test.js +12 -0
- package/dist/ndlTokensCopy.test.js.map +1 -0
- package/dist/neo4jSetup.js +120 -0
- package/dist/neo4jSetup.js.map +1 -0
- package/dist/{types/themes.d.ts → themes.d.ts} +1 -1
- package/dist/themes.js +114 -0
- package/dist/themes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +30 -31
- package/src/CypherEditor.test.tsx +200 -0
- package/src/CypherEditor.tsx +292 -41
- package/src/constants.ts +1 -0
- package/src/e2e_tests/autoCompletion.spec.tsx +472 -0
- package/src/e2e_tests/configuration.spec.tsx +111 -0
- package/src/e2e_tests/debounce.spec.tsx +101 -0
- package/src/e2e_tests/{e2e-utils.ts → e2eUtils.ts} +11 -1
- package/src/e2e_tests/{extra-keybindings.spec.tsx → extraKeybindings.spec.tsx} +1 -3
- package/src/e2e_tests/historyNavigation.spec.tsx +315 -0
- package/src/e2e_tests/performanceTest.spec.tsx +158 -0
- package/src/e2e_tests/{sanity-checks.spec.tsx → sanityChecks.spec.tsx} +7 -22
- package/src/e2e_tests/signatureHelp.spec.tsx +380 -0
- package/src/e2e_tests/snippets.spec.tsx +92 -0
- package/src/e2e_tests/{syntax-highlighting.spec.tsx → syntaxHighlighting.spec.tsx} +1 -3
- package/src/e2e_tests/{syntax-validation.spec.tsx → syntaxValidation.spec.tsx} +6 -7
- package/src/{repl-mode.ts → historyNavigation.ts} +7 -30
- package/src/icons.ts +3 -0
- package/src/index.ts +5 -2
- package/src/lang-cypher/autocomplete.ts +107 -15
- package/src/lang-cypher/constants.ts +23 -0
- package/src/lang-cypher/contants.test.ts +6 -2
- package/src/lang-cypher/{create-cypher-theme.ts → createCypherTheme.ts} +41 -2
- package/src/lang-cypher/langCypher.ts +53 -0
- package/src/lang-cypher/lintWorker.ts +14 -0
- package/src/lang-cypher/parser-adapter.ts +145 -0
- package/src/lang-cypher/signatureHelp.ts +133 -0
- package/src/lang-cypher/syntaxValidation.ts +96 -0
- package/src/lang-cypher/utils.ts +9 -0
- package/src/{ndl-tokens-copy.test.ts → ndlTokensCopy.test.ts} +2 -1
- package/src/{neo4j-setup.tsx → neo4jSetup.tsx} +51 -1
- package/src/themes.ts +4 -2
- package/src/viteEnv.d.ts +1 -0
- package/dist/cjs/index.cjs +0 -1443
- package/dist/cjs/index.cjs.map +0 -7
- package/dist/esm/index.mjs +0 -1466
- 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/lang-cypher/syntax-validation.d.ts +0 -3
- package/dist/types/repl-mode.d.ts +0 -8
- package/dist/types/tsconfig.tsbuildinfo +0 -1
- package/src/e2e_tests/auto-completion.spec.tsx +0 -232
- package/src/e2e_tests/history-navigation.spec.tsx +0 -144
- package/src/e2e_tests/mock-data.ts +0 -4310
- package/src/e2e_tests/performance-test.spec.tsx +0 -71
- 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/dist/{types/e2e_tests/auto-completion.spec.d.ts → CypherEditor.test.d.ts} +0 -0
- /package/dist/{types/e2e_tests/extra-keybindings.spec.d.ts → e2e_tests/autoCompletion.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/history-navigation.spec.d.ts → e2e_tests/configuration.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/performance-test.spec.d.ts → e2e_tests/debounce.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/e2e-utils.d.ts → e2e_tests/e2eUtils.d.ts} +0 -0
- /package/dist/{types/e2e_tests/sanity-checks.spec.d.ts → e2e_tests/extraKeybindings.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-highlighting.spec.d.ts → e2e_tests/historyNavigation.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-validation.spec.d.ts → e2e_tests/sanityChecks.spec.d.ts} +0 -0
- /package/dist/{types/lang-cypher/contants.test.d.ts → e2e_tests/signatureHelp.spec.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.test.d.ts → e2e_tests/snippets.spec.d.ts} +0 -0
- /package/dist/{types/lang-cypher/create-cypher-theme.d.ts → lang-cypher/createCypherTheme.d.ts} +0 -0
- /package/dist/{types/lang-cypher/theme-icons.d.ts → lang-cypher/themeIcons.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.d.ts → ndlTokensCopy.d.ts} +0 -0
- /package/dist/{types/neo4j-setup.d.ts → neo4jSetup.d.ts} +0 -0
- /package/src/lang-cypher/{theme-icons.ts → themeIcons.ts} +0 -0
- /package/src/{ndl-tokens-copy.ts → ndlTokensCopy.ts} +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { testData } from '@neo4j-cypher/language-support';
|
|
3
|
+
import { expect, test } from '@playwright/experimental-ct-react';
|
|
4
|
+
import { CypherEditor } from '../CypherEditor';
|
|
5
|
+
test.use({ viewport: { width: 1000, height: 500 } });
|
|
6
|
+
function testTooltip(tooltip, expectations) {
|
|
7
|
+
const includes = expectations.includes ?? [];
|
|
8
|
+
const excludes = expectations.excludes ?? [];
|
|
9
|
+
const included = Promise.all(includes.map((text) => {
|
|
10
|
+
return expect(tooltip).toContainText(text, {
|
|
11
|
+
timeout: 2000,
|
|
12
|
+
});
|
|
13
|
+
}));
|
|
14
|
+
const excluded = Promise.all(excludes.map((text) => {
|
|
15
|
+
return expect(tooltip).not.toContainText(text, {
|
|
16
|
+
timeout: 2000,
|
|
17
|
+
});
|
|
18
|
+
}));
|
|
19
|
+
return Promise.all([included, excluded]);
|
|
20
|
+
}
|
|
21
|
+
test('Signature help works for functions', async ({ page, mount }) => {
|
|
22
|
+
const query = 'RETURN abs(';
|
|
23
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
24
|
+
await expect(page.locator('.cm-signature-help-panel')).toBeVisible({
|
|
25
|
+
timeout: 2000,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
test('Signature help works for procedures', async ({ page, mount }) => {
|
|
29
|
+
const query = 'CALL apoc.import.csv(';
|
|
30
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
31
|
+
await expect(page.locator('.cm-signature-help-panel')).toBeVisible({
|
|
32
|
+
timeout: 2000,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
test('Signature help shows the description for the first argument', async ({ page, mount, }) => {
|
|
36
|
+
const query = 'CALL apoc.import.csv(';
|
|
37
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
38
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
39
|
+
await testTooltip(tooltip, {
|
|
40
|
+
includes: [
|
|
41
|
+
'nodes :: LIST<MAP>',
|
|
42
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
test('Signature help shows the description for the first argument when the cursor is at that position', async ({ page, mount, }) => {
|
|
47
|
+
const query = 'CALL apoc.import.csv()';
|
|
48
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, offset: 21 }));
|
|
49
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
50
|
+
await testTooltip(tooltip, {
|
|
51
|
+
includes: [
|
|
52
|
+
'nodes :: LIST<MAP>',
|
|
53
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
test('Signature help shows the description for the second argument', async ({ page, mount, }) => {
|
|
58
|
+
const query = 'CALL apoc.import.csv(nodes,';
|
|
59
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
60
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
61
|
+
await testTooltip(tooltip, {
|
|
62
|
+
includes: [
|
|
63
|
+
'rels :: LIST<MAP>',
|
|
64
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
test('Signature help shows the description for the second argument when the cursor is at that position', async ({ page, mount, }) => {
|
|
69
|
+
const query = 'CALL apoc.import.csv(nodes,)';
|
|
70
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, offset: 27 }));
|
|
71
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
72
|
+
await testTooltip(tooltip, {
|
|
73
|
+
includes: [
|
|
74
|
+
'rels :: LIST<MAP>',
|
|
75
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
test('Signature help shows the description for the second argument when the cursor is at that position, even after whitespaces', async ({ page, mount, }) => {
|
|
80
|
+
const query = 'CALL apoc.import.csv(nodes, )';
|
|
81
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, offset: 28 }));
|
|
82
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
83
|
+
await testTooltip(tooltip, {
|
|
84
|
+
includes: [
|
|
85
|
+
'rels :: LIST<MAP>',
|
|
86
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
87
|
+
],
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
test('Signature help shows description for arguments with a space following a separator', async ({ page, mount, }) => {
|
|
91
|
+
const query = 'CALL apoc.import.csv(nodes, ';
|
|
92
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
93
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
94
|
+
await testTooltip(tooltip, {
|
|
95
|
+
includes: [
|
|
96
|
+
'rels :: LIST<MAP>',
|
|
97
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
test('Signature help shows the description for the third argument', async ({ page, mount, }) => {
|
|
102
|
+
const query = 'CALL apoc.import.csv(nodes, rels,';
|
|
103
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
104
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
105
|
+
await testTooltip(tooltip, {
|
|
106
|
+
includes: [
|
|
107
|
+
'config :: MAP',
|
|
108
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
109
|
+
],
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
test('Signature help works on multiline queries', async ({ page, mount }) => {
|
|
113
|
+
const query = `CALL apoc.import.csv(
|
|
114
|
+
nodes,
|
|
115
|
+
rels,
|
|
116
|
+
`;
|
|
117
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
118
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
119
|
+
await testTooltip(tooltip, {
|
|
120
|
+
includes: [
|
|
121
|
+
'config :: MAP',
|
|
122
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file',
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
test('Signature help only shows the description past the last argument', async ({ page, mount, }) => {
|
|
127
|
+
const query = 'CALL apoc.import.csv(nodes, rels, config,';
|
|
128
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
129
|
+
1;
|
|
130
|
+
const tooltip = page.locator('.cm-signature-help-panel');
|
|
131
|
+
await testTooltip(tooltip, {
|
|
132
|
+
includes: [
|
|
133
|
+
'apoc.import.csv(nodes :: LIST<MAP>, rels :: LIST<MAP>, config :: MAP)',
|
|
134
|
+
'Imports `NODE` and `RELATIONSHIP` values with the given labels and types from the provided CSV file.',
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
test('Signature help does not show any help when method finished', async ({ page, mount, }) => {
|
|
139
|
+
const query = 'CALL apoc.import.csv(nodes, rels, config)';
|
|
140
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
141
|
+
await expect(page.locator('.cm-signature-help-panel')).not.toBeVisible({
|
|
142
|
+
timeout: 2000,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
test('Signature help does not blow up on empty query', async ({ page, mount, }) => {
|
|
146
|
+
const query = '';
|
|
147
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
148
|
+
await expect(page.locator('.cm-signature-help-panel')).not.toBeVisible({
|
|
149
|
+
timeout: 2000,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
test('Signature help is shown below the text by default', async ({ page, mount, }) => {
|
|
153
|
+
// We need to introduce new lines to make sure there's
|
|
154
|
+
// enough space to show the tooltip above
|
|
155
|
+
const query = '\n\n\n\n\n\n\nRETURN abs(';
|
|
156
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, autofocus: true }));
|
|
157
|
+
await expect(page.locator('.cm-signature-help-panel.cm-tooltip-below')).toBeVisible({
|
|
158
|
+
timeout: 2000,
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
test('Setting showSignatureTooltipBelow to true shows the signature help above the text', async ({ page, mount, }) => {
|
|
162
|
+
// We need to introduce new lines to make sure there's
|
|
163
|
+
// enough space to show the tooltip above
|
|
164
|
+
const query = '\n\n\n\n\n\n\nRETURN abs(';
|
|
165
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, showSignatureTooltipBelow: true, autofocus: true }));
|
|
166
|
+
await expect(page.locator('.cm-signature-help-panel.cm-tooltip-below')).toBeVisible({
|
|
167
|
+
timeout: 2000,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
test('Setting showSignatureTooltipBelow to false shows the signature help above the text', async ({ page, mount, }) => {
|
|
171
|
+
// We need to introduce new lines to make sure there's
|
|
172
|
+
// enough space to show the tooltip above
|
|
173
|
+
const query = '\n\n\n\n\n\n\nRETURN abs(';
|
|
174
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema, showSignatureTooltipBelow: false, autofocus: true }));
|
|
175
|
+
await expect(page.locator('.cm-signature-help-panel.cm-tooltip-above')).toBeVisible({
|
|
176
|
+
timeout: 2000,
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=signatureHelp.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatureHelp.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/signatureHelp.spec.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AAOrD,SAAS,WAAW,CAAC,OAAgB,EAAE,YAAiC;IACtE,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAC;IAE7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAC1B,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE;YACzC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAC1B,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE;YAC7C,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,IAAI,CAAC,oCAAoC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACnE,MAAM,KAAK,GAAG,aAAa,CAAC;IAE5B,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,WAAW,CAAC;QACjE,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qCAAqC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACpE,MAAM,KAAK,GAAG,uBAAuB,CAAC;IAEtC,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,WAAW,CAAC;QACjE,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,EAAE,EACzE,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,uBAAuB,CAAC;IAEtC,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,oBAAoB;YACpB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iGAAiG,EAAE,KAAK,EAAE,EAC7G,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,wBAAwB,CAAC;IAEvC,MAAM,KAAK,CACT,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAI,CACxE,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,oBAAoB;YACpB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8DAA8D,EAAE,KAAK,EAAE,EAC1E,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,6BAA6B,CAAC;IAE5C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,mBAAmB;YACnB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kGAAkG,EAAE,KAAK,EAAE,EAC9G,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,8BAA8B,CAAC;IAE7C,MAAM,KAAK,CACT,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAI,CACxE,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,mBAAmB;YACnB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0HAA0H,EAAE,KAAK,EAAE,EACtI,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,gCAAgC,CAAC;IAE/C,MAAM,KAAK,CACT,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAI,CACxE,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,mBAAmB;YACnB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mFAAmF,EAAE,KAAK,EAAE,EAC/F,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,8BAA8B,CAAC;IAE7C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,mBAAmB;YACnB,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,EAAE,EACzE,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,mCAAmC,CAAC;IAElD,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,eAAe;YACf,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IAC1E,MAAM,KAAK,GAAG;;;KAGX,CAAC;IAEJ,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,eAAe;YACf,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,KAAK,EAAE,EAC9E,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,2CAA2C,CAAC;IAE1D,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEzD,MAAM,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE;YACR,uEAAuE;YACvE,sGAAsG;SACvG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,KAAK,EAAE,EACxE,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,2CAA2C,CAAC;IAE1D,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACrE,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,KAAK,EAAE,EAC5D,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,EAAE,CAAC;IAEjB,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACrE,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,EAAE,EAC/D,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,sDAAsD;IACtD,yCAAyC;IACzC,MAAM,KAAK,GAAG,2BAA2B,CAAC;IAE1C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CACV,IAAI,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAC1D,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mFAAmF,EAAE,KAAK,EAAE,EAC/F,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,sDAAsD;IACtD,yCAAyC;IACzC,MAAM,KAAK,GAAG,2BAA2B,CAAC;IAE1C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,yBAAyB,EAAE,IAAI,EAC/B,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CACV,IAAI,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAC1D,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oFAAoF,EAAE,KAAK,EAAE,EAChG,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,sDAAsD;IACtD,yCAAyC;IACzC,MAAM,KAAK,GAAG,2BAA2B,CAAC;IAE1C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,QAAQ,CAAC,UAAU,EAC3B,yBAAyB,EAAE,KAAK,EAChC,SAAS,EAAE,IAAI,GACf,CACH,CAAC;IAEF,MAAM,MAAM,CACV,IAAI,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAC1D,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
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('can complete pattern snippet', async ({ page, mount }) => {
|
|
5
|
+
await mount(_jsx(CypherEditor, {}));
|
|
6
|
+
const textField = page.getByRole('textbox');
|
|
7
|
+
await textField.fill('MATCH ()-[]->()');
|
|
8
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('-[]->()').click();
|
|
9
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
10
|
+
await textField.press('Tab');
|
|
11
|
+
await textField.press('Tab');
|
|
12
|
+
await expect(textField).toHaveText('MATCH ()-[]->()-[ ]->( )');
|
|
13
|
+
});
|
|
14
|
+
test('can navigate snippet', async ({ page, mount }) => {
|
|
15
|
+
await mount(_jsx(CypherEditor, {}));
|
|
16
|
+
const textField = page.getByRole('textbox');
|
|
17
|
+
await textField.fill('CREATE INDEX abc FOR ()');
|
|
18
|
+
await page
|
|
19
|
+
.locator('.cm-tooltip-autocomplete')
|
|
20
|
+
.getByText('-[]-()', { exact: true })
|
|
21
|
+
.click();
|
|
22
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
23
|
+
await expect(page.locator('.cm-snippetField')).toHaveCount(2);
|
|
24
|
+
await textField.press('Tab');
|
|
25
|
+
await textField.press('Shift+Tab');
|
|
26
|
+
await expect(textField).toHaveText('CREATE INDEX abc FOR ()-[ ]-( )');
|
|
27
|
+
await textField.press('a');
|
|
28
|
+
await expect(textField).toHaveText('CREATE INDEX abc FOR ()-[a]-( )');
|
|
29
|
+
await textField.press('Escape');
|
|
30
|
+
await textField.press('Escape');
|
|
31
|
+
await expect(page.locator('.cm-snippetField')).toHaveCount(0);
|
|
32
|
+
await textField.press('Tab');
|
|
33
|
+
await expect(textField).toHaveText('CREATE INDEX abc FOR ()-[a ]-( )');
|
|
34
|
+
});
|
|
35
|
+
test('can accept completion inside pattern snippet', async ({ page, mount, }) => {
|
|
36
|
+
await mount(_jsx(CypherEditor, { schema: { labels: ['City'] } }));
|
|
37
|
+
const textField = page.getByRole('textbox');
|
|
38
|
+
await textField.fill('MATCH ()-[]->()');
|
|
39
|
+
await page.locator('.cm-tooltip-autocomplete').getByText('-[]->()').click();
|
|
40
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
41
|
+
// move to node
|
|
42
|
+
await textField.press('Tab');
|
|
43
|
+
// get & accept completion
|
|
44
|
+
await textField.press(':');
|
|
45
|
+
await expect(page.locator('.cm-tooltip-autocomplete').getByText('City')).toBeVisible();
|
|
46
|
+
await textField.press('Tab');
|
|
47
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
48
|
+
// tab out of the snippet
|
|
49
|
+
await textField.press('Tab');
|
|
50
|
+
await expect(textField).toHaveText('MATCH ()-[]->()-[ ]->(:City)');
|
|
51
|
+
});
|
|
52
|
+
test('does not automatically open completion panel for expressions after snippet trigger char', async ({ page, mount, }) => {
|
|
53
|
+
await mount(_jsx(CypherEditor, {}));
|
|
54
|
+
const textField = page.getByRole('textbox');
|
|
55
|
+
await textField.fill('RETURN (1)');
|
|
56
|
+
// expect the panel to not show up
|
|
57
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).not.toBeVisible();
|
|
58
|
+
// unless manually triggered
|
|
59
|
+
await textField.press('Control+ ');
|
|
60
|
+
await expect(page.locator('.cm-tooltip-autocomplete')).toBeVisible();
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=snippets.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippets.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/snippets.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
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 { darkThemeConstants, lightThemeConstants } from '../themes';
|
|
5
|
+
import { CypherEditorPage } from './e2eUtils';
|
|
6
|
+
test('light theme highlighting', async ({ page, mount }) => {
|
|
7
|
+
const editorPage = new CypherEditorPage(page);
|
|
8
|
+
const query = `
|
|
9
|
+
MATCH (variable :Label)-[:REL_TYPE]->()
|
|
10
|
+
WHERE variable.property = "String"
|
|
11
|
+
OR namespaced.function() = false
|
|
12
|
+
// comment
|
|
13
|
+
OR $parameter > 1234
|
|
14
|
+
RETURN variable;`;
|
|
15
|
+
await mount(_jsx(CypherEditor, { value: query, theme: "light" }));
|
|
16
|
+
const keywordcolors = await Promise.all(['MATCH', 'WHERE', 'RETURN'].map((kw) => editorPage.getHexColorOfLocator(page.getByText(kw))));
|
|
17
|
+
keywordcolors.every((kw) => expect(kw).toEqual(lightThemeConstants.highlightStyles.keyword));
|
|
18
|
+
const labelReltype = await Promise.all(['Label', 'REL_TYPE'].map((kw) => editorPage.getHexColorOfLocator(page.getByText(kw))));
|
|
19
|
+
labelReltype.every((kw) => expect(kw).toEqual(lightThemeConstants.highlightStyles.label));
|
|
20
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('parameter'))).toEqual(lightThemeConstants.highlightStyles.paramValue);
|
|
21
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('property'))).toEqual(lightThemeConstants.highlightStyles.property);
|
|
22
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('false'))).toEqual(lightThemeConstants.highlightStyles.booleanLiteral);
|
|
23
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('String'))).toEqual(lightThemeConstants.highlightStyles.stringLiteral);
|
|
24
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('comment'))).toEqual(lightThemeConstants.highlightStyles.comment);
|
|
25
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('1234', { exact: true }))).toEqual(lightThemeConstants.highlightStyles.numberLiteral);
|
|
26
|
+
expect(await editorPage.editorBackgroundIsUnset()).toEqual(false);
|
|
27
|
+
});
|
|
28
|
+
test('dark theme highlighting', async ({ page, mount }) => {
|
|
29
|
+
const editorPage = new CypherEditorPage(page);
|
|
30
|
+
const query = `
|
|
31
|
+
MATCH (variable :Label)-[:REL_TYPE]->()
|
|
32
|
+
WHERE variable.property = "String"
|
|
33
|
+
OR namespaced.function() = false
|
|
34
|
+
// comment
|
|
35
|
+
OR $parameter > 1234
|
|
36
|
+
RETURN variable;`;
|
|
37
|
+
await mount(_jsx(CypherEditor, { value: query, theme: "dark" }));
|
|
38
|
+
const keywordcolors = await Promise.all(['MATCH', 'WHERE', 'RETURN'].map((kw) => editorPage.getHexColorOfLocator(page.getByText(kw))));
|
|
39
|
+
keywordcolors.every((kw) => expect(kw).toEqual(darkThemeConstants.highlightStyles.keyword));
|
|
40
|
+
const labelReltype = await Promise.all(['Label', 'REL_TYPE'].map((kw) => editorPage.getHexColorOfLocator(page.getByText(kw))));
|
|
41
|
+
labelReltype.every((kw) => expect(kw).toEqual(darkThemeConstants.highlightStyles.label));
|
|
42
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('parameter'))).toEqual(darkThemeConstants.highlightStyles.paramValue);
|
|
43
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('property'))).toEqual(darkThemeConstants.highlightStyles.property);
|
|
44
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('false'))).toEqual(darkThemeConstants.highlightStyles.booleanLiteral);
|
|
45
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('String'))).toEqual(darkThemeConstants.highlightStyles.stringLiteral);
|
|
46
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('comment'))).toEqual(darkThemeConstants.highlightStyles.comment);
|
|
47
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('1234', { exact: true }))).toEqual(darkThemeConstants.highlightStyles.numberLiteral);
|
|
48
|
+
expect(await editorPage.editorBackgroundIsUnset()).toEqual(false);
|
|
49
|
+
});
|
|
50
|
+
test('can live switch theme ', async ({ page, mount }) => {
|
|
51
|
+
const editorPage = new CypherEditorPage(page);
|
|
52
|
+
const component = await mount(_jsx(CypherEditor, { theme: "light", value: "RETURN" }));
|
|
53
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('RETURN', { exact: true }))).toEqual(lightThemeConstants.highlightStyles.keyword);
|
|
54
|
+
await component.update(_jsx(CypherEditor, { theme: "dark", value: "RETURN" }));
|
|
55
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('RETURN', { exact: true }))).toEqual(darkThemeConstants.highlightStyles.keyword);
|
|
56
|
+
});
|
|
57
|
+
test('respects prop to allow overriding bkg color', async ({ page, mount }) => {
|
|
58
|
+
const editorPage = new CypherEditorPage(page);
|
|
59
|
+
await mount(_jsx(CypherEditor, { theme: "light", value: "text", overrideThemeBackgroundColor: true }));
|
|
60
|
+
expect(await editorPage.editorBackgroundIsUnset()).toEqual(true);
|
|
61
|
+
});
|
|
62
|
+
test('highlights multiline string literal correctly', async ({ page, mount, }) => {
|
|
63
|
+
const editorPage = new CypherEditorPage(page);
|
|
64
|
+
const query = `
|
|
65
|
+
RETURN "
|
|
66
|
+
multilinestring";`;
|
|
67
|
+
await mount(_jsx(CypherEditor, { theme: "light", value: query }));
|
|
68
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('multilinestring'))).toEqual(lightThemeConstants.highlightStyles.stringLiteral);
|
|
69
|
+
});
|
|
70
|
+
test('highlights multiline label correctly', async ({ page, mount }) => {
|
|
71
|
+
const editorPage = new CypherEditorPage(page);
|
|
72
|
+
const query = `
|
|
73
|
+
MATCH (v:\`
|
|
74
|
+
|
|
75
|
+
Label\`)
|
|
76
|
+
`;
|
|
77
|
+
await mount(_jsx(CypherEditor, { theme: "light", value: query }));
|
|
78
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('Label'))).toEqual(lightThemeConstants.highlightStyles.label);
|
|
79
|
+
});
|
|
80
|
+
test('highlights multiline comment correctly', async ({ page, mount }) => {
|
|
81
|
+
const editorPage = new CypherEditorPage(page);
|
|
82
|
+
const query = `
|
|
83
|
+
/*
|
|
84
|
+
|
|
85
|
+
comment
|
|
86
|
+
*/";`;
|
|
87
|
+
await mount(_jsx(CypherEditor, { theme: "light", value: query }));
|
|
88
|
+
expect(await editorPage.getHexColorOfLocator(page.getByText('comment'))).toEqual(lightThemeConstants.highlightStyles.comment);
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=syntaxHighlighting.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntaxHighlighting.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/syntaxHighlighting.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
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 './e2eUtils';
|
|
5
|
+
test.use({ viewport: { width: 1000, height: 500 } });
|
|
6
|
+
test('Prop lint set to false disables syntax validation', async ({ page, mount, }) => {
|
|
7
|
+
const query = 'METCH (n) RETURN n';
|
|
8
|
+
await mount(_jsx(CypherEditor, { value: query, lint: false }));
|
|
9
|
+
await expect(page.locator('.cm-lintRange-error').last()).not.toBeVisible({
|
|
10
|
+
timeout: 2000,
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
test('Can turn linting back on', async ({ page, mount }) => {
|
|
14
|
+
const editorPage = new CypherEditorPage(page);
|
|
15
|
+
const query = 'METCH (n) RETURN n';
|
|
16
|
+
const component = await mount(_jsx(CypherEditor, { value: query, lint: false }));
|
|
17
|
+
await expect(page.locator('.cm-lintRange-error').last()).not.toBeVisible({
|
|
18
|
+
timeout: 2000,
|
|
19
|
+
});
|
|
20
|
+
await component.update(_jsx(CypherEditor, { value: query, lint: true }));
|
|
21
|
+
await editorPage.getEditor().fill('METCH (n) RETURN n');
|
|
22
|
+
await editorPage.checkErrorMessage('METCH', 'Unrecognized keyword. Did you mean MATCH?');
|
|
23
|
+
});
|
|
24
|
+
test('Syntactic errors are surfaced', async ({ page, mount }) => {
|
|
25
|
+
const editorPage = new CypherEditorPage(page);
|
|
26
|
+
const query = 'METCH (n) RETURN n';
|
|
27
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
28
|
+
await editorPage.checkErrorMessage('METCH', 'Unrecognized keyword. Did you mean MATCH?');
|
|
29
|
+
});
|
|
30
|
+
test('Errors for undefined labels are surfaced', async ({ page, mount }) => {
|
|
31
|
+
const editorPage = new CypherEditorPage(page);
|
|
32
|
+
const query = 'MATCH (n: Person) RETURN n';
|
|
33
|
+
await mount(_jsx(CypherEditor, { value: query, schema: { labels: ['Movie'], relationshipTypes: [] } }));
|
|
34
|
+
await editorPage.checkWarningMessage('Person', "Label Person is not present in the database. Make sure you didn't misspell it or that it is available when you run this statement in your application");
|
|
35
|
+
});
|
|
36
|
+
test('Errors for multiline undefined labels are highlighted correctly', async ({ page, mount, }) => {
|
|
37
|
+
const editorPage = new CypherEditorPage(page);
|
|
38
|
+
const query = `MATCH (n:\`Foo
|
|
39
|
+
Bar\`) RETURN n`;
|
|
40
|
+
const expectedMsg = `Label \`Foo
|
|
41
|
+
Bar\` is not present in the database. Make sure you didn't misspell it or that it is available when you run this statement in your application`;
|
|
42
|
+
await mount(_jsx(CypherEditor, { value: query, schema: { labels: ['Movie'], relationshipTypes: [] } }));
|
|
43
|
+
await editorPage.checkWarningMessage('`Foo', expectedMsg);
|
|
44
|
+
await editorPage.checkWarningMessage('Bar`', expectedMsg);
|
|
45
|
+
});
|
|
46
|
+
test('Semantic errors are surfaced when there are no syntactic errors', async ({ page, mount, }) => {
|
|
47
|
+
const editorPage = new CypherEditorPage(page);
|
|
48
|
+
const query = 'MATCH (n) RETURN m';
|
|
49
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
50
|
+
await editorPage.checkErrorMessage('m', 'Variable `m` not defined');
|
|
51
|
+
});
|
|
52
|
+
test('Semantic errors are correctly accumulated', async ({ page, mount }) => {
|
|
53
|
+
const editorPage = new CypherEditorPage(page);
|
|
54
|
+
const query = 'CALL { MATCH (n) } IN TRANSACTIONS OF -1 ROWS';
|
|
55
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
56
|
+
await editorPage.checkErrorMessage('MATCH (n)', 'Query cannot conclude with MATCH (must be a RETURN clause, a FINISH clause, an update clause, a unit subquery call, or a procedure call with no YIELD).');
|
|
57
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer");
|
|
58
|
+
});
|
|
59
|
+
test('Multiline errors are correctly placed', async ({ page, mount }) => {
|
|
60
|
+
const editorPage = new CypherEditorPage(page);
|
|
61
|
+
const query = `CALL {
|
|
62
|
+
MATCH (n)
|
|
63
|
+
} IN TRANSACTIONS
|
|
64
|
+
OF -1 ROWS`;
|
|
65
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
66
|
+
await editorPage.checkErrorMessage('MATCH (n)', 'Query cannot conclude with MATCH (must be a RETURN clause, a FINISH clause, an update clause, a unit subquery call, or a procedure call with no YIELD)');
|
|
67
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer");
|
|
68
|
+
});
|
|
69
|
+
test('Validation errors are correctly overlapped', async ({ page, mount }) => {
|
|
70
|
+
const editorPage = new CypherEditorPage(page);
|
|
71
|
+
const query = `CALL { MATCH (n)
|
|
72
|
+
RETURN n
|
|
73
|
+
} IN TRANSACTIONS
|
|
74
|
+
OF -1 ROWS`;
|
|
75
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
76
|
+
await editorPage.checkErrorMessage('-1', 'Query cannot conclude with CALL (must be a RETURN clause, a FINISH clause, an update clause, a unit subquery call, or a procedure call with no YIELD).');
|
|
77
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer");
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=syntaxValidation.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntaxValidation.spec.js","sourceRoot":"","sources":["../../src/e2e_tests/syntaxValidation.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Extension } from '@codemirror/state';
|
|
2
|
+
export declare const replaceHistory: import("@codemirror/state").StateEffectType<string[]>;
|
|
3
|
+
type ReplProps = {
|
|
4
|
+
history?: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare const replMode: ({ history }: ReplProps) => Extension[];
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { StateEffect } from '@codemirror/state';
|
|
2
|
+
import { keymap } from '@codemirror/view';
|
|
3
|
+
import { StateField } from '@codemirror/state';
|
|
4
|
+
const DRAFT_ENTRY_INDEX = -1;
|
|
5
|
+
const historyInitialState = {
|
|
6
|
+
history: [],
|
|
7
|
+
index: DRAFT_ENTRY_INDEX,
|
|
8
|
+
documentUpdate: null,
|
|
9
|
+
draft: '',
|
|
10
|
+
};
|
|
11
|
+
const historyState = StateField.define({
|
|
12
|
+
create() {
|
|
13
|
+
return historyInitialState;
|
|
14
|
+
},
|
|
15
|
+
toJSON(value) {
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
},
|
|
18
|
+
update(value, transaction) {
|
|
19
|
+
for (const effect of transaction.effects) {
|
|
20
|
+
if (effect.is(moveInHistory)) {
|
|
21
|
+
if (value.history.length === 0) {
|
|
22
|
+
return {
|
|
23
|
+
...value,
|
|
24
|
+
documentUpdate: null,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const currentHistoryIndex = value.index;
|
|
28
|
+
if (effect.value === 'BACK') {
|
|
29
|
+
const newHistoryIndex = currentHistoryIndex + 1;
|
|
30
|
+
if (newHistoryIndex === value.history.length) {
|
|
31
|
+
return {
|
|
32
|
+
...value,
|
|
33
|
+
documentUpdate: null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let draft = value.draft;
|
|
37
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
38
|
+
draft = transaction.state.doc.toString();
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...value,
|
|
42
|
+
draft,
|
|
43
|
+
index: newHistoryIndex,
|
|
44
|
+
documentUpdate: value.history[newHistoryIndex],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else if (effect.value === 'FORWARDS') {
|
|
48
|
+
const newHistoryIndex = currentHistoryIndex - 1;
|
|
49
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
50
|
+
return { ...value, documentUpdate: null };
|
|
51
|
+
}
|
|
52
|
+
if (newHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
53
|
+
return {
|
|
54
|
+
...value,
|
|
55
|
+
index: newHistoryIndex,
|
|
56
|
+
documentUpdate: value.draft,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return {
|
|
61
|
+
...value,
|
|
62
|
+
index: newHistoryIndex,
|
|
63
|
+
documentUpdate: value.history[newHistoryIndex],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (effect.is(replaceHistory)) {
|
|
69
|
+
return {
|
|
70
|
+
...value,
|
|
71
|
+
index: DRAFT_ENTRY_INDEX,
|
|
72
|
+
history: effect.value,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const moveInHistory = StateEffect.define();
|
|
80
|
+
export const replaceHistory = StateEffect.define();
|
|
81
|
+
function navigateHistory(view, direction) {
|
|
82
|
+
view.dispatch(view.state.update({
|
|
83
|
+
effects: moveInHistory.of(direction),
|
|
84
|
+
selection: { anchor: direction === 'BACK' ? 0 : view.state.doc.length },
|
|
85
|
+
}));
|
|
86
|
+
const updatedHistory = view.state.field(historyState, false);
|
|
87
|
+
if (updatedHistory.documentUpdate !== null) {
|
|
88
|
+
view.dispatch(view.state.update({
|
|
89
|
+
changes: {
|
|
90
|
+
from: 0,
|
|
91
|
+
to: view.state.doc.length,
|
|
92
|
+
insert: updatedHistory.documentUpdate,
|
|
93
|
+
},
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const replMode = ({ history }) => {
|
|
98
|
+
return [
|
|
99
|
+
historyState.init(() => ({
|
|
100
|
+
...historyInitialState,
|
|
101
|
+
history,
|
|
102
|
+
})),
|
|
103
|
+
keymap.of([
|
|
104
|
+
{
|
|
105
|
+
key: 'ArrowUp',
|
|
106
|
+
preventDefault: true,
|
|
107
|
+
run: (view) => {
|
|
108
|
+
// If text is selected or cursor is not at top of document, do nothing
|
|
109
|
+
const { empty, head } = view.state.selection.main;
|
|
110
|
+
if (!empty || head !== 0) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
navigateHistory(view, 'BACK');
|
|
114
|
+
return true;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
mac: 'Cmd-ArrowUp',
|
|
119
|
+
win: 'Ctrl-ArrowUp',
|
|
120
|
+
linux: 'Ctrl-ArrowUp',
|
|
121
|
+
preventDefault: true,
|
|
122
|
+
run: (view) => {
|
|
123
|
+
// If text is selected or cursor is not at top of document, do nothing
|
|
124
|
+
const { empty, head } = view.state.selection.main;
|
|
125
|
+
if (!empty || head !== 0) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
navigateHistory(view, 'BACK');
|
|
129
|
+
return true;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: 'ArrowDown',
|
|
134
|
+
preventDefault: true,
|
|
135
|
+
run: (view) => {
|
|
136
|
+
const { empty, head } = view.state.selection.main;
|
|
137
|
+
// If text is selected or cursor is not at end of document, do nothing
|
|
138
|
+
if (!empty || head !== view.state.doc.length) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
navigateHistory(view, 'FORWARDS');
|
|
142
|
+
return true;
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
mac: 'Cmd-ArrowDown',
|
|
147
|
+
win: 'Ctrl-ArrowDown',
|
|
148
|
+
linux: 'Ctrl-ArrowDown',
|
|
149
|
+
preventDefault: true,
|
|
150
|
+
run: (view) => {
|
|
151
|
+
const { empty, head } = view.state.selection.main;
|
|
152
|
+
// If text is selected or cursor is not at end of document, do nothing
|
|
153
|
+
if (!empty || head !== view.state.doc.length) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
navigateHistory(view, 'FORWARDS');
|
|
157
|
+
return true;
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
]),
|
|
161
|
+
];
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=historyNavigation.js.map
|