From 7520b13bee73570c57899a48254251224bb861d8 Mon Sep 17 00:00:00 2001 From: Nikita Shkaruba Date: Fri, 1 Dec 2023 11:58:30 +0100 Subject: [PATCH] refactor: migrate explain and insert tests to typescript (#98) * refactor: migrate explain, insert tests to typescript * refactor: add eslint fixes to new tests --- .../generic/jison/explain/explain.test.json | 69 ---- .../generic/jison/explain/explain.test.ts | 132 ++++++++ .../generic/jison/insert/insert.test.json | 303 ------------------ .../generic/jison/insert/insert.test.ts | 235 ++++++++++++++ 4 files changed, 367 insertions(+), 372 deletions(-) delete mode 100644 src/parsing/parsers/generic/jison/explain/explain.test.json create mode 100644 src/parsing/parsers/generic/jison/explain/explain.test.ts delete mode 100644 src/parsing/parsers/generic/jison/insert/insert.test.json create mode 100644 src/parsing/parsers/generic/jison/insert/insert.test.ts diff --git a/src/parsing/parsers/generic/jison/explain/explain.test.json b/src/parsing/parsers/generic/jison/explain/explain.test.json deleted file mode 100644 index aa9fe94e..00000000 --- a/src/parsing/parsers/generic/jison/explain/explain.test.json +++ /dev/null @@ -1,69 +0,0 @@ -[ - { - "namePrefix": "should not report errors on EXPLAIN SELECT statement", - "beforeCursor": "EXPLAIN SELECT * FROM test_table; ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should not report errors on EXPLAIN DELETE statement", - "beforeCursor": "EXPLAIN DELETE FROM test_table; ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should not report errors on EXPLAIN CREATE statement", - "beforeCursor": "EXPLAIN CREATE TABLE Persons (id int); ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should report error on double EXPLAIN statement", - "beforeCursor": "EXPLAIN EXPLAIN SELECT * FROM test_table; ", - "afterCursor": "", - "expectedErrors": [ - { - "text": "EXPLAIN", - "token": "EXPLAIN", - "loc": { - "first_line": 1, - "last_line": 1, - "first_column": 8, - "last_column": 15 - } - } - ] - }, - { - "namePrefix": "should suggest EXPLAIN", - "beforeCursor": "", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["EXPLAIN"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest query", - "beforeCursor": "EXPLAIN ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["ALTER", "CREATE", "DELETE", "DROP", "INSERT", "SELECT", "SET", "UPDATE"], - "expectedResult": { - "lowerCase": false - } - } -] diff --git a/src/parsing/parsers/generic/jison/explain/explain.test.ts b/src/parsing/parsers/generic/jison/explain/explain.test.ts new file mode 100644 index 00000000..6f3b3520 --- /dev/null +++ b/src/parsing/parsers/generic/jison/explain/explain.test.ts @@ -0,0 +1,132 @@ +import {expect, test} from '@jest/globals'; + +import { + KeywordSuggestion, + StatementPart, + parseGenericSql, + parseGenericSqlWithoutCursor, +} from '../../../../index'; + +test('should suggest EXPLAIN', () => { + const parseResult = parseGenericSql('', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion = {value: 'EXPLAIN', weight: -1}; + expect(parseResult.suggestKeywords).toContainEqual(suggestion); +}); + +test('should suggest query beginnings', () => { + const parseResult = parseGenericSql('EXPLAIN ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion[] = [ + {value: 'CREATE', weight: -1}, + {value: 'ALTER', weight: -1}, + {value: 'DELETE', weight: -1}, + {value: 'SELECT', weight: -1}, + ]; + expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestion)); +}); + +test('should report an error', () => { + const parseResult = parseGenericSql('EXPLAIN EXPLAIN ', ''); + + expect(parseResult.errors).not.toBeUndefined(); + + // TODO: check errors more thoroughly + // Currently, we are unable to check that the first element exists, and that it's token is explain properly + // expect(errors[0].token).toEqual("EXPLAIN"); + we should check locations +}); + +test('should not report errors on full statement and fill locations', () => { + const parseResult = parseGenericSqlWithoutCursor('EXPLAIN SELECT * FROM test_database;'); + + expect(parseResult.errors).toBeUndefined(); + + const statementParts: StatementPart[] = [ + { + location: { + first_column: 1, + first_line: 1, + last_column: 36, + last_line: 1, + }, + type: 'statement', + }, + { + identifier: 'SELECT', + location: { + first_column: 9, + first_line: 1, + last_column: 15, + last_line: 1, + }, + type: 'statementType', + }, + { + location: { + first_column: 16, + first_line: 1, + last_column: 17, + last_line: 1, + }, + missing: false, + type: 'selectList', + }, + { + location: { + first_column: 16, + first_line: 1, + last_column: 17, + last_line: 1, + }, + tables: [ + { + identifierChain: [ + { + name: 'test_database', + }, + ], + }, + ], + type: 'asterisk', + }, + { + identifierChain: [ + { + name: 'test_database', + }, + ], + location: { + first_column: 23, + first_line: 1, + last_column: 36, + last_line: 1, + }, + type: 'table', + }, + { + location: { + first_column: 36, + first_line: 1, + last_column: 36, + last_line: 1, + }, + missing: true, + type: 'whereClause', + }, + { + location: { + first_column: 36, + first_line: 1, + last_column: 36, + last_line: 1, + }, + missing: true, + type: 'limitClause', + }, + ]; + expect(parseResult.locations).toEqual(statementParts); +}); diff --git a/src/parsing/parsers/generic/jison/insert/insert.test.json b/src/parsing/parsers/generic/jison/insert/insert.test.json deleted file mode 100644 index 654c5761..00000000 --- a/src/parsing/parsers/generic/jison/insert/insert.test.json +++ /dev/null @@ -1,303 +0,0 @@ -[ - { - "namePrefix": "should not report errors", - "beforeCursor": "INSERT INTO bla.boo VALUES (1, 2, 'a', 3); ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should not report errors", - "beforeCursor": "INSERT INTO bla.boo (column) VALUES (1); ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should not report errors with couple column names", - "beforeCursor": "INSERT INTO bla.boo (column1, column2) VALUES (1, 2); ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["SELECT"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should not report errors with filled column", - "beforeCursor": "INSERT INTO bla.boo (column) ", - "afterCursor": "", - "noErrors": true, - "containsKeywords": ["VALUES"], - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest keywords", - "beforeCursor": "", - "afterCursor": "", - "containsKeywords": ["INSERT"], - "noErrors": true, - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest keywords", - "beforeCursor": "INSERT ", - "afterCursor": "", - "containsKeywords": ["INTO"], - "noErrors": true, - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest tables", - "beforeCursor": "INSERT INTO ", - "afterCursor": "", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestTables": {}, - "suggestDatabases": { - "appendDot": true - }, - "suggestKeywords": ["TABLE"] - } - }, - { - "namePrefix": "should suggest tables", - "beforeCursor": "INSERT INTO baa.", - "afterCursor": "", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestTables": { - "identifierChain": [ - { - "name": "baa" - } - ] - } - } - }, - { - "namePrefix": "should suggest tables", - "beforeCursor": "INSERT INTO TABLE baa.", - "afterCursor": "", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestTables": { - "identifierChain": [ - { - "name": "baa" - } - ] - } - } - }, - { - "namePrefix": "should suggest keywords", - "beforeCursor": "INSERT INTO baa ", - "afterCursor": "", - "containsKeywords": ["VALUES"], - "noErrors": true, - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest keywords", - "beforeCursor": "INSERT INTO TABLE baa ", - "afterCursor": "", - "containsKeywords": ["VALUES"], - "noErrors": true, - "expectedResult": { - "lowerCase": false - } - }, - { - "namePrefix": "should suggest columns", - "beforeCursor": "INSERT INTO TABLE baa (", - "afterCursor": ")", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestColumns": { - "tables": [ - { - "identifierChain": [ - { - "name": "baa" - } - ] - } - ] - } - } - }, - { - "namePrefix": "should suggest columns", - "beforeCursor": "INSERT INTO TABLE baa (column1, ", - "afterCursor": ")", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestColumns": { - "tables": [ - { - "identifierChain": [ - { - "name": "baa" - } - ] - } - ] - } - } - }, - { - "namePrefix": "should suggest columns on full SQL query", - "beforeCursor": "INSERT INTO TABLE baa (", - "afterCursor": ") VALUES (one, two)", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestColumns": { - "tables": [ - { - "identifierChain": [ - { - "name": "baa" - } - ] - } - ] - } - } - }, - { - "namePrefix": "should suggest columns on full SQL query", - "beforeCursor": "INSERT INTO TABLE baa (column1, ", - "afterCursor": ") VALUES (one, two)", - "noErrors": true, - "expectedResult": { - "lowerCase": false, - "suggestColumns": { - "tables": [ - { - "identifierChain": [ - { - "name": "baa" - } - ] - } - ] - } - } - }, - { - "namePrefix": "should suggest tables without filled table columns", - "beforeCursor": "INSERT INTO ", - "afterCursor": " ()", - "expectedErrors": [ - { - "text": ")", - "token": ")", - "line": 0, - "loc": { - "first_line": 1, - "last_line": 1, - "first_column": 17, - "last_column": 18 - } - } - ], - "expectedResult": { - "lowerCase": false, - "suggestTables": {}, - "suggestKeywords": ["TABLE"], - "suggestDatabases": { - "appendDot": true - } - } - }, - { - "namePrefix": "should suggest tables without filled table columns and values", - "beforeCursor": "INSERT INTO ", - "afterCursor": " () VALUES ()", - "expectedErrors": [ - { - "text": ")", - "token": ")", - "line": 0, - "loc": { - "first_line": 1, - "last_line": 1, - "first_column": 17, - "last_column": 18 - } - }, - { - "text": ")", - "token": ")", - "line": 0, - "loc": { - "first_line": 1, - "last_line": 1, - "first_column": 27, - "last_column": 28 - } - } - ], - "expectedResult": { - "lowerCase": false, - "suggestTables": {}, - "suggestKeywords": ["TABLE"], - "suggestDatabases": { - "appendDot": true - } - } - }, - { - "namePrefix": "should suggest columns with filled table and empty values", - "beforeCursor": "INSERT INTO some_table (", - "afterCursor": ") VALUES ()", - "expectedErrors": [ - { - "text": ")", - "token": ")", - "line": 0, - "loc": { - "first_line": 1, - "last_line": 1, - "first_column": 37, - "last_column": 38 - } - } - ], - "expectedResult": { - "lowerCase": false, - "suggestColumns": { - "tables": [ - { - "identifierChain": [ - { - "name": "some_table" - } - ] - } - ] - } - } - } -] diff --git a/src/parsing/parsers/generic/jison/insert/insert.test.ts b/src/parsing/parsers/generic/jison/insert/insert.test.ts new file mode 100644 index 00000000..cfe86e47 --- /dev/null +++ b/src/parsing/parsers/generic/jison/insert/insert.test.ts @@ -0,0 +1,235 @@ +import {expect, test} from '@jest/globals'; + +import { + ColumnSuggestion, + DatabasesSuggestion, + KeywordSuggestion, + StatementPart, + TablesSuggestion, + parseGenericSql, + parseGenericSqlWithoutCursor, +} from '../../../../index'; + +// TODO: test separately OptionalParenthesizedColumnListOrError +// TODO: test separately InsertValuesListOrError + +test('should suggest INSERT', () => { + const parseResult = parseGenericSql('', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion = {value: 'INSERT', weight: -1}; + expect(parseResult.suggestKeywords).toContainEqual(suggestion); +}); + +test('should suggest INTO', () => { + const parseResult = parseGenericSql('INSERT ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion[] = [{value: 'INTO', weight: -1}]; + expect(parseResult.suggestKeywords).toEqual(suggestion); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const tablesSuggestion: TablesSuggestion = {}; + expect(parseResult.suggestTables).toEqual(tablesSuggestion); + + const databasesSuggestion: DatabasesSuggestion = { + appendDot: true, + }; + expect(parseResult.suggestDatabases).toEqual(databasesSuggestion); + + const suggestion: KeywordSuggestion[] = [{value: 'TABLE', weight: -1}]; + expect(parseResult.suggestKeywords).toEqual(suggestion); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO TABLE ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const tablesSuggestion: TablesSuggestion = {}; + expect(parseResult.suggestTables).toEqual(tablesSuggestion); + + const databasesSuggestion: DatabasesSuggestion = { + appendDot: true, + }; + expect(parseResult.suggestDatabases).toEqual(databasesSuggestion); + + expect(parseResult.suggestKeywords).toBeUndefined(); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO TABLE test_table ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion = {value: 'VALUES', weight: -1}; + expect(parseResult.suggestKeywords).toContainEqual(suggestion); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO test_table (test_column) ', ''); + + expect(parseResult.errors).toBeUndefined(); + + const suggestion: KeywordSuggestion = {value: 'VALUES', weight: -1}; + expect(parseResult.suggestKeywords).toContainEqual(suggestion); +}); + +test('should suggest columns', () => { + const parseResult = parseGenericSql('INSERT INTO test_table (', ')'); + + const columnSuggestion: ColumnSuggestion = { + tables: [ + { + identifierChain: [ + { + name: 'test_table', + }, + ], + }, + ], + }; + expect(parseResult.suggestColumns).toEqual(columnSuggestion); +}); + +test('should suggest columns', () => { + const parseResult = parseGenericSql( + 'INSERT INTO test_table (', + ') VALUES (test_value_1, test_value_2)', + ); + + const columnSuggestion: ColumnSuggestion = { + tables: [ + { + identifierChain: [ + { + name: 'test_table', + }, + ], + }, + ], + }; + expect(parseResult.suggestColumns).toEqual(columnSuggestion); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO ', ' ()'); + + const tablesSuggestion: TablesSuggestion = {}; + expect(parseResult.suggestTables).toEqual(tablesSuggestion); + + const databasesSuggestion: DatabasesSuggestion = { + appendDot: true, + }; + expect(parseResult.suggestDatabases).toEqual(databasesSuggestion); + + const suggestion: KeywordSuggestion[] = [{value: 'TABLE', weight: -1}]; + expect(parseResult.suggestKeywords).toEqual(suggestion); +}); + +test('should suggest tables', () => { + const parseResult = parseGenericSql('INSERT INTO ', ' () VALUES ()'); + + const tablesSuggestion: TablesSuggestion = {}; + expect(parseResult.suggestTables).toEqual(tablesSuggestion); + + const databasesSuggestion: DatabasesSuggestion = { + appendDot: true, + }; + expect(parseResult.suggestDatabases).toEqual(databasesSuggestion); + + const suggestion: KeywordSuggestion[] = [{value: 'TABLE', weight: -1}]; + expect(parseResult.suggestKeywords).toEqual(suggestion); +}); + +test('should suggest columns', () => { + const parseResult = parseGenericSql('INSERT INTO test_table (', ') VALUES ()'); + + const columnSuggestion: ColumnSuggestion = { + tables: [ + { + identifierChain: [ + { + name: 'test_table', + }, + ], + }, + ], + }; + expect(parseResult.suggestColumns).toEqual(columnSuggestion); +}); + +test('should not report errors and fill locations', () => { + const parseResult = parseGenericSqlWithoutCursor( + 'INSERT INTO test_table (test_column_1, test_column_2) VALUES (123, 324);', + ); + + expect(parseResult.errors).toBeUndefined(); + + const statementParts: StatementPart[] = [ + { + location: { + first_column: 1, + first_line: 1, + last_column: 72, + last_line: 1, + }, + type: 'statement', + }, + { + identifierChain: [ + { + name: 'test_table', + }, + ], + location: { + first_column: 13, + first_line: 1, + last_column: 23, + last_line: 1, + }, + type: 'table', + }, + ]; + expect(parseResult.locations).toEqual(statementParts); +}); + +test('should not report errors and fill locations', () => { + const parseResult = parseGenericSqlWithoutCursor('INSERT INTO test_table VALUES (123, 324);'); + + expect(parseResult.errors).toBeUndefined(); + + const statementParts: StatementPart[] = [ + { + location: { + first_column: 1, + first_line: 1, + last_column: 41, + last_line: 1, + }, + type: 'statement', + }, + { + identifierChain: [ + { + name: 'test_table', + }, + ], + location: { + first_column: 13, + first_line: 1, + last_column: 23, + last_line: 1, + }, + type: 'table', + }, + ]; + expect(parseResult.locations).toEqual(statementParts); +});