import { createParsingResult, } from '../cypherLanguageService.js';
import { testData } from './testData.js';
import { highlightSyntax } from '../syntaxHighlighting/syntaxHighlighting.js';
import { autocomplete } from '../autocompletion/autocompletion.js';
import { getDiagnosticsForQuery, getSymbolTablesForQuery, } from './syntaxValidation/helpers.js';
function expectParsedCommands(query, toEqual) {
    const result = createParsingResult(query, { consoleCommandsEnabled: true });
    expect(result.statementsParsing.flatMap((statement) => statement.syntaxErrors)).toEqual([]);
    expect(result.statementsParsing
        .flatMap((statement) => [statement.command])
        .map((cmd) => {
        const copy = { ...cmd };
        // These data structures are recursive, so .toEqual doesn't work.
        // We test the positions work properly in with the error position tests
        delete copy.start;
        delete copy.stop;
        return copy;
    })).toEqual(toEqual);
}
function expectErrorMessage(query, msg) {
    const result = createParsingResult(query, { consoleCommandsEnabled: true });
    expect(result.statementsParsing
        .flatMap((statement) => statement.syntaxErrors)
        .map((e) => e.message)).toContain(msg);
}
describe('sanity checks', () => {
    test('parses simple commands without args ', () => {
        expectParsedCommands(':clear', [{ type: 'clear' }]);
        expectParsedCommands(':history', [{ type: 'history' }]);
        expectParsedCommands(':connect', [{ type: 'connect' }]);
        expectParsedCommands(':disconnect', [{ type: 'disconnect' }]);
        expectParsedCommands(':sysinfo', [{ type: 'sysinfo' }]);
        expectParsedCommands(':style', [{ type: 'style' }]);
        expectParsedCommands(':help', [{ type: 'help' }]);
    });
    test('properly highlights simple commands', () => {
        expect(highlightSyntax(':clear')).toEqual([
            {
                length: 1,
                position: {
                    line: 0,
                    startCharacter: 0,
                    startOffset: 0,
                },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: {
                    line: 0,
                    startCharacter: 1,
                    startOffset: 1,
                },
                token: 'clear',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':history')).toEqual([
            {
                length: 1,
                position: {
                    line: 0,
                    startCharacter: 0,
                    startOffset: 0,
                },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 7,
                position: {
                    line: 0,
                    startCharacter: 1,
                    startOffset: 1,
                },
                token: 'history',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':connect')).toEqual([
            {
                length: 1,
                position: {
                    line: 0,
                    startCharacter: 0,
                    startOffset: 0,
                },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 7,
                position: {
                    line: 0,
                    startCharacter: 1,
                    startOffset: 1,
                },
                token: 'connect',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':disconnect')).toEqual([
            {
                length: 1,
                position: {
                    line: 0,
                    startCharacter: 0,
                    startOffset: 0,
                },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 10,
                position: {
                    line: 0,
                    startCharacter: 1,
                    startOffset: 1,
                },
                token: 'disconnect',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':sysinfo')).toEqual([
            {
                length: 1,
                position: {
                    line: 0,
                    startCharacter: 0,
                    startOffset: 0,
                },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 7,
                position: {
                    line: 0,
                    startCharacter: 1,
                    startOffset: 1,
                },
                token: 'sysinfo',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':style')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'style',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':style reset')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'style',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 7, startOffset: 7 },
                token: 'reset',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':play')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'play',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':help')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'help',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':auto')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'auto',
                tokenType: 'consoleCommand',
            },
        ]);
    });
    test('completes basic console cmds on :', () => {
        expect(autocomplete(':', {})).toEqual([
            { kind: 23, label: 'server' },
            { kind: 23, label: 'use' },
            { kind: 23, label: 'auto' },
            { kind: 23, label: 'help' },
            { kind: 23, label: 'access-mode' },
            { kind: 23, label: 'play' },
            { kind: 23, label: 'style' },
            { kind: 23, label: 'style reset' },
            { kind: 23, label: 'sysinfo' },
            { kind: 23, label: 'welcome' },
            { kind: 23, label: 'disconnect' },
            { kind: 23, label: 'connect' },
            { kind: 23, label: 'param' },
            { kind: 23, label: 'history' },
            { kind: 23, label: 'clear' },
        ]);
    });
    test('accepts trailing ; ', () => {
        expectParsedCommands(':history;', [
            { type: 'history' },
            { type: 'cypher', statement: '' },
        ]);
    });
    test('parses multiple cmds', () => {
        expectParsedCommands(':history;:history;:clear', [
            { type: 'history' },
            { type: 'history' },
            { type: 'clear' },
        ]);
    });
    test('accepts upper case', () => {
        expectParsedCommands(':HISTORY;', [
            { type: 'history' },
            { type: 'cypher', statement: '' },
        ]);
    });
    test('accepts mixed case', () => {
        expectParsedCommands(':cLeaR;', [
            { type: 'clear' },
            { type: 'cypher', statement: '' },
        ]);
    });
    test('handles misspelled or non-existing command', () => {
        expectErrorMessage(':foo', 'Expected any of auto, help, access-mode, play, style, sysinfo, welcome, disconnect, connect, param, history, clear, server or use');
        expectErrorMessage(':clea', 'Unexpected token. Did you mean clear?');
    });
});
describe(':use', () => {
    test('parses without arg', () => {
        expectParsedCommands(':use', [{ type: 'use' }]);
    });
    test('parses with arg', () => {
        expectParsedCommands(':use foo', [{ type: 'use', database: 'foo' }]);
    });
    test('completes database & alias names', () => {
        expect(autocomplete(':use ', {
            databaseNames: ['foo'],
            aliasNames: ['bar'],
        })).toEqual([
            { kind: 12, label: 'foo' },
            { kind: 12, label: 'bar' },
        ]);
    });
    test('gives errors on incorrect usage of :use', () => {
        expectErrorMessage(':use 123', "Expected ';' or a database name");
        expectErrorMessage(':use foo bar', "Expected ';' or a database name");
    });
    test('highlights properly', () => {
        expect(highlightSyntax(':use')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 3,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'use',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':use foo')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 3,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'use',
                tokenType: 'consoleCommand',
            },
            {
                length: 3,
                position: { line: 0, startCharacter: 5, startOffset: 5 },
                token: 'foo',
                tokenType: 'symbolicName',
            },
        ]);
    });
});
describe(':play', () => {
    const dbSchema = {
        databaseNames: ['foo'],
        aliasNames: ['bar'],
        labels: ['fan'],
        relationshipTypes: ['follows'],
        userNames: ['fred'],
        roleNames: ['fixer'],
        parameters: { fixing: 'foobar' },
        propertyKeys: ['firstName'],
    };
    test('parses with arg', () => {
        expectParsedCommands(':play intro', [{ type: 'play', guide: 'intro' }]);
    });
    test('gives no completion on `:play `', () => {
        expect(autocomplete(':play ', dbSchema)).toEqual([]);
    });
    test('gives no completion on `:play f`', () => {
        expect(autocomplete(':play f', dbSchema)).toEqual([]);
    });
    test('gives errors on incorrect usage of :play', () => {
        expectErrorMessage(':play ', 'Expected an identifier');
        expectErrorMessage(':play 123', 'Expected an identifier');
        expectErrorMessage(':play foo bar', "Expected ';'");
    });
    test('highlights properly', () => {
        expect(highlightSyntax(':play')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'play',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':play intro')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'play',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 6, startOffset: 6 },
                token: 'intro',
                tokenType: 'symbolicName',
            },
        ]);
    });
});
describe('parameters', () => {
    test('basic param usage', () => {
        expectParsedCommands(':param', [{ type: 'list-parameters' }]);
        expectParsedCommands(':params ', [{ type: 'list-parameters' }]);
        expectParsedCommands(':params list', [{ type: 'list-parameters' }]);
        expectParsedCommands(':params clear', [{ type: 'clear-parameters' }]);
    });
    test('allows setting parameters', () => {
        expectParsedCommands(':param foo => bar', [
            {
                type: 'set-parameters',
                parameters: [{ name: 'foo', expression: 'bar' }],
            },
        ]);
        expectParsedCommands(':param {a: 2, b: rand()}', [
            {
                type: 'set-parameters',
                parameters: [
                    { name: 'a', expression: '2' },
                    { name: 'b', expression: 'rand()' },
                ],
            },
        ]);
    });
    test('allows setting parameters with escaped name', () => {
        expectParsedCommands(':param `foo foo` => bar', [
            {
                type: 'set-parameters',
                parameters: [{ name: '`foo foo`', expression: 'bar' }],
            },
        ]);
        expectParsedCommands(':param {`a a a`: 2, `b-b-b`: rand()}', [
            {
                type: 'set-parameters',
                parameters: [
                    { name: '`a a a`', expression: '2' },
                    { name: '`b-b-b`', expression: 'rand()' },
                ],
            },
        ]);
    });
    test('autocompletes expressions', () => {
        const arrowCompletions = autocomplete(':param foo => ', {
            functions: {
                'CYPHER 5': {
                    'duration.inSeconds': {
                        ...testData.emptyFunction,
                        name: 'duration.inSeconds',
                    },
                },
            },
        });
        const mapCompletions = autocomplete(':param {a:  ', {
            functions: {
                'CYPHER 5': {
                    'duration.inSeconds': {
                        ...testData.emptyFunction,
                        name: 'duration.inSeconds',
                    },
                },
            },
        });
        const expected = [
            { detail: '(namespace)', kind: 3, label: 'duration' },
            {
                detail: '(function)',
                kind: 3,
                label: 'duration.inSeconds',
                signature: '',
                documentation: '',
            },
            { kind: 14, label: 'TRUE' },
            { kind: 14, label: 'FALSE' },
        ];
        expected.forEach((completion) => {
            expect(arrowCompletions).toContainEqual(completion);
            expect(mapCompletions).toContainEqual(completion);
        });
    });
    test('incorrect usage of :params', () => {
        expectErrorMessage(':param x=21', "Expected '>'");
        expectErrorMessage(':param x=>', 'Expected an expression');
        expectErrorMessage(':param {a: 3', "Expected any of '}', ',', AND, OR, XOR or an expression");
        expectErrorMessage(':param RETURN', "Expected '='");
        expectErrorMessage(':param RETURN b', "Expected '='");
        expectErrorMessage(':param b => ', 'Expected an expression');
        expectErrorMessage(':param {', "Expected '}' or an identifier");
        expectErrorMessage(':param {x}', "Expected ':'");
        expectErrorMessage(':param {x: ', 'Expected an expression');
        expectErrorMessage(':param {: 4} ', "Expected '}' or an identifier");
    });
    test('unfinished string inside a parameter', () => {
        expectErrorMessage(':param x=>"foo', 'Failed to parse string literal. The query must contain an even number of non-escaped quotes.');
    });
    test('unfinished comment inside a parameter', () => {
        expectErrorMessage(`:param x => /* unfinished comment "foo"`, 'Failed to parse comment. A comment starting on `/*` must have a closing `*/`.');
    });
    test('highlights :params properly', () => {
        expect(highlightSyntax(':param')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'param',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':params')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'params',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':params list')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'params',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 8, startOffset: 8 },
                token: 'list',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':param clear')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'param',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 7, startOffset: 7 },
                token: 'clear',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':param x => 324')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'param',
                tokenType: 'consoleCommand',
            },
            {
                length: 1,
                position: { line: 0, startCharacter: 7, startOffset: 7 },
                token: 'x',
                tokenType: 'variable',
            },
            {
                length: 1,
                position: { line: 0, startCharacter: 9, startOffset: 9 },
                token: '=',
                tokenType: 'operator',
            },
            {
                length: 1,
                position: { line: 0, startCharacter: 10, startOffset: 10 },
                token: '>',
                tokenType: 'operator',
            },
            {
                length: 3,
                position: { line: 0, startCharacter: 12, startOffset: 12 },
                token: '324',
                tokenType: 'numberLiteral',
            },
        ]);
        expect(highlightSyntax(':params {d: true}')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'params',
                tokenType: 'consoleCommand',
            },
            {
                bracketInfo: { bracketLevel: 0, bracketType: 'curly' },
                length: 1,
                position: { line: 0, startCharacter: 8, startOffset: 8 },
                token: '{',
                tokenType: 'bracket',
            },
            {
                length: 1,
                position: { line: 0, startCharacter: 9, startOffset: 9 },
                token: 'd',
                tokenType: 'property',
            },
            {
                length: 1,
                position: { line: 0, startCharacter: 10, startOffset: 10 },
                token: ':',
                tokenType: 'operator',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 12, startOffset: 12 },
                token: 'true',
                tokenType: 'booleanLiteral',
            },
            {
                bracketInfo: { bracketLevel: 0, bracketType: 'curly' },
                length: 1,
                position: { line: 0, startCharacter: 16, startOffset: 16 },
                token: '}',
                tokenType: 'bracket',
            },
        ]);
    });
});
describe('server', () => {
    test('basic server usage', () => {
        expectParsedCommands(':server connect', [
            { type: 'server', operation: 'connect' },
        ]);
        expectParsedCommands(':server disconnect', [
            { type: 'server', operation: 'disconnect' },
        ]);
    });
    test('autocompletes operation', () => {
        const mapCompletions = autocomplete(':server conn', {
            functions: {
                'CYPHER 5': {
                    'duration.inSeconds': {
                        ...testData.emptyFunction,
                        name: 'duration.inSeconds',
                    },
                },
            },
        });
        const expected = [
            { kind: 23, label: 'connect' },
            { kind: 23, label: 'disconnect' },
        ];
        expected.forEach((completion) => {
            expect(mapCompletions).toContainEqual(completion);
        });
    });
    test('incorrect usage of :server', () => {
        expectErrorMessage(':server', 'Expected connect or disconnect');
        expectErrorMessage(':server xyz', 'Expected connect or disconnect');
    });
    test('highlights :server properly', () => {
        expect(highlightSyntax(':server')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'server',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':server connect')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'server',
                tokenType: 'consoleCommand',
            },
            {
                length: 7,
                position: { line: 0, startCharacter: 8, startOffset: 8 },
                token: 'connect',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':server disconnect')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 6,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'server',
                tokenType: 'consoleCommand',
            },
            {
                length: 10,
                position: { line: 0, startCharacter: 8, startOffset: 8 },
                token: 'disconnect',
                tokenType: 'consoleCommand',
            },
        ]);
    });
});
describe('auto', () => {
    test('parses without arg', () => {
        expectParsedCommands(':auto', [{ type: 'auto', statement: '' }]);
    });
    test('parses with valid statement', () => {
        expectParsedCommands(':auto RETURN 1', [
            { type: 'auto', statement: 'RETURN 1' },
        ]);
    });
    test('gives errors on invalid statement', () => {
        const linting = getDiagnosticsForQuery({
            query: ':auto asdf',
            consoleCommandsEnabled: true,
        });
        expect(linting).toEqual([
            {
                offsets: {
                    end: 10,
                    start: 6,
                },
                message: "Invalid input 'asdf': expected 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH'",
                range: {
                    end: {
                        character: 10,
                        line: 0,
                    },
                    start: {
                        character: 6,
                        line: 0,
                    },
                },
                severity: 1,
            },
        ]);
    });
    test('gives errors on trailing garbage after valid statement', () => {
        const linting = getDiagnosticsForQuery({
            query: ':auto RETURN 1 asdf',
            consoleCommandsEnabled: true,
        });
        expect(linting).toEqual([
            {
                offsets: {
                    end: 19,
                    start: 15,
                },
                message: "Invalid input 'asdf': expected an expression, ',', 'AS', 'ORDER BY', 'CALL', 'CREATE', 'LOAD CSV', 'DELETE', 'DETACH', 'FINISH', 'FOREACH', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REMOVE', 'RETURN', 'SET', 'SKIP', 'UNION', 'UNWIND', 'USE', 'WITH' or <EOF>",
                range: {
                    end: {
                        character: 19,
                        line: 0,
                    },
                    start: {
                        character: 15,
                        line: 0,
                    },
                },
                severity: 1,
            },
        ]);
    });
    test('provides symbol tables with correct positions', () => {
        const symbolTables = getSymbolTablesForQuery({
            query: ':auto MATCH (n) RETURN n',
            consoleCommandsEnabled: true,
        });
        expect(symbolTables).toEqual([
            [
                {
                    variable: 'n',
                    definitionPosition: 13,
                    types: ['Node'],
                    references: [13, 23],
                    labels: {
                        condition: 'and',
                        children: [],
                    },
                },
            ],
        ]);
    });
    test('provides semantic errors', () => {
        const linting = getDiagnosticsForQuery({
            query: ':auto RETURN n',
            consoleCommandsEnabled: true,
        });
        expect(linting).toEqual([
            {
                offsets: {
                    end: 14,
                    start: 13,
                },
                message: 'Variable `n` not defined',
                range: {
                    end: {
                        character: 14,
                        line: 0,
                    },
                    start: {
                        character: 13,
                        line: 0,
                    },
                },
                severity: 1,
            },
        ]);
    });
    test('handles multiple statements', () => {
        const linting = getDiagnosticsForQuery({
            query: ':auto RETURN n; MATCH (n) RETURN n',
            consoleCommandsEnabled: true,
        });
        expect(linting).toEqual([
            {
                offsets: {
                    end: 14,
                    start: 13,
                },
                message: 'Variable `n` not defined',
                range: {
                    end: {
                        character: 14,
                        line: 0,
                    },
                    start: {
                        character: 13,
                        line: 0,
                    },
                },
                severity: 1,
            },
        ]);
    });
});
describe('command parser also handles cypher', () => {
    test('parses cypher', () => {
        expectParsedCommands('MATCH (n) RETURN n', [
            { statement: 'MATCH (n) RETURN n', type: 'cypher' },
        ]);
    });
    test('preserves original whitespace', () => {
        expectParsedCommands('MATCH\n(n)\nRETURN n', [
            { statement: 'MATCH\n(n)\nRETURN n', type: 'cypher' },
        ]);
    });
    test('can split cypher into statements', () => {
        expectParsedCommands('CALL db.info(); RETURN 123; SHOW DATABASES', [
            { statement: 'CALL db.info()', type: 'cypher' },
            { statement: 'RETURN 123', type: 'cypher' },
            { statement: 'SHOW DATABASES', type: 'cypher' },
        ]);
    });
    test('can weave cypher with cmds', () => {
        expectParsedCommands(':use neo4j; :param x => 23;RETURN $x;:use system; SHOW DATABASES; ', [
            { database: 'neo4j', type: 'use' },
            {
                parameters: [{ name: 'x', expression: '23' }],
                type: 'set-parameters',
            },
            { statement: 'RETURN $x', type: 'cypher' },
            { database: 'system', type: 'use' },
            { statement: 'SHOW DATABASES', type: 'cypher' },
            { statement: '', type: 'cypher' },
        ]);
    });
});
describe('style', () => {
    test('parses style reset', () => {
        expectParsedCommands(':style reset', [
            { type: 'style', operation: 'reset' },
        ]);
    });
});
describe('access-mode', () => {
    test('basic access-mode usage', () => {
        expectParsedCommands(':access-mode', [
            { type: 'access-mode', operation: undefined },
        ]);
        expectParsedCommands(':access-mode read', [
            { type: 'access-mode', operation: 'read' },
        ]);
        expectParsedCommands(':access-mode write', [
            { type: 'access-mode', operation: 'write' },
        ]);
    });
    test('highlights :access-mode properly', () => {
        expect(highlightSyntax(':access-mode')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 11,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'access-mode',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':access-mode read')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 11,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'access-mode',
                tokenType: 'consoleCommand',
            },
            {
                length: 4,
                position: { line: 0, startCharacter: 13, startOffset: 13 },
                token: 'read',
                tokenType: 'consoleCommand',
            },
        ]);
        expect(highlightSyntax(':access-mode write')).toEqual([
            {
                length: 1,
                position: { line: 0, startCharacter: 0, startOffset: 0 },
                token: ':',
                tokenType: 'consoleCommand',
            },
            {
                length: 11,
                position: { line: 0, startCharacter: 1, startOffset: 1 },
                token: 'access-mode',
                tokenType: 'consoleCommand',
            },
            {
                length: 5,
                position: { line: 0, startCharacter: 13, startOffset: 13 },
                token: 'write',
                tokenType: 'consoleCommand',
            },
        ]);
    });
    test('autocompletes read operation', () => {
        const mapCompletions = autocomplete(':access-mode r', {
            functions: {
                'CYPHER 5': {
                    'duration.inSeconds': {
                        ...testData.emptyFunction,
                        name: 'duration.inSeconds',
                    },
                },
            },
        });
        const expected = [{ kind: 23, label: 'read' }];
        expected.forEach((completion) => {
            expect(mapCompletions).toContainEqual(completion);
        });
    });
    test('autocompletes write operation', () => {
        const mapCompletions = autocomplete(':access-mode w', {
            functions: {
                'CYPHER 5': {
                    'duration.inSeconds': {
                        ...testData.emptyFunction,
                        name: 'duration.inSeconds',
                    },
                },
            },
        });
        const expected = [{ kind: 23, label: 'write' }];
        expected.forEach((completion) => {
            expect(mapCompletions).toContainEqual(completion);
        });
    });
    test('incorrect usage of :access-mode', () => {
        expectErrorMessage(':access-mode xyz', "Expected any of ';', read or write");
    });
});
//# sourceMappingURL=consoleCommands.test.js.map