complete ts type, add test

This commit is contained in:
HSunboy 2019-05-14 16:57:09 +08:00
parent c20549970f
commit 41aed6b4ce
10 changed files with 314 additions and 1117 deletions

View File

@ -91,3 +91,4 @@ hiveimpala等语法解析文件来自[Hue](https://github.com/cloudera/hue)
- 1.1.8 添加转义字符支持 - 1.1.8 添加转义字符支持
- 1.1.9 添加函数的中括号语法支持( split(nameList)[0] ) - 1.1.9 添加函数的中括号语法支持( split(nameList)[0] )
- 1.2.0 添加 ts添加测试

185
jest.config.js Normal file
View File

@ -0,0 +1,185 @@
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
module.exports = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// Respect "browser" field in package.json when resolving modules
// browser: false,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/private/var/folders/xr/54w2mws93hj3p3_ysc347flc0000gn/T/jest_dx",
// Automatically clear mock calls and instances between every test
// clearMocks: false,
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: null,
// The directory where Jest should output its coverage files
// coverageDirectory: null,
// An array of regexp pattern strings used to skip coverage collection
coveragePathIgnorePatterns: [
"/node_modules/"
],
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: null,
// A path to a custom dependency extractor
// dependencyExtractor: null,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: null,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: null,
// A set of global variables that need to be available in all test environments
// globals: {},
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "json",
// "jsx",
// "ts",
// "tsx",
// "node"
// ],
// A map from regular expressions to module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: null,
// Run tests from one or more projects
// projects: null,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state between every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: null,
// Automatically restore mock state between every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: null,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
testEnvironment: "node",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
testPathIgnorePatterns: [
"/node_modules/"
],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: null,
// This option allows use of a custom test runner
// testRunner: "jasmine2",
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
// testURL: "http://localhost",
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
// timers: "real",
// A map from regular expressions to paths to transformers
// transform: null,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: [
"/node_modules/"
],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: null,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};

View File

@ -3,40 +3,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
// import * as sqlSyntaxParser from '../core/sqlSyntaxParser'; // import * as sqlSyntaxParser from '../core/sqlSyntaxParser';
const sqlSyntaxParser = require("../core/sqlSyntaxParser"); const sqlSyntaxParser = require("../core/sqlSyntaxParser");
const sqlAutoCompleteParser = require("../core/sqlAutoCompleteParser"); const sqlAutoCompleteParser = require("../core/sqlAutoCompleteParser");
var sqlType;
(function (sqlType) {
sqlType["Hive"] = "hive";
sqlType["None"] = "sql";
sqlType["Impala"] = "impala";
})(sqlType || (sqlType = {}));
function sqlToParserArgs(sql) {
let preSql = '', sufSql = '';
if (Object.prototype.toString.call(sql) == '[object Array]') {
preSql = sql[0];
sufSql = sql[1];
}
return [preSql, sufSql];
}
/** /**
* 自动补全提示 * 校验语法
* @param {(string | Array<string>)} sql
* @param {string} [type="hive"]
*/ */
function parseSyntax(sql, type) { function parseSyntax(sql, type = sqlType.Hive) {
if (typeof type == "undefined") { const parserArgs = sqlToParserArgs(sql);
type = "hive"; return sqlSyntaxParser.parser.parseSyntax(parserArgs[0], parserArgs[1], type, false);
}
let sql1 = sql;
let sql2 = '';
if (sql instanceof Array) {
sql1 = sql[0];
sql2 = sql[1];
}
// @ts-nocheck
return sqlSyntaxParser.parser.parseSyntax(sql1, sql2, type, false);
} }
exports.parseSyntax = parseSyntax; exports.parseSyntax = parseSyntax;
/** /**
* 自动补全提示 * 自动补全提示
* @param {(string | Array<string>)} sql
* @param {string} [type="hive"]
*/ */
function parserSql(sql, type) { function parserSql(sql, type = sqlType.Hive) {
if (typeof type == "undefined") { const parserArgs = sqlToParserArgs(sql);
type = "hive"; return sqlAutoCompleteParser.parser.parseSql(parserArgs[0], parserArgs[1], type, false);
}
let sql1 = sql;
let sql2 = '';
if (sql instanceof Array) {
sql1 = sql[0];
sql2 = sql[1];
}
return sqlAutoCompleteParser.parser.parseSql(sql1, sql2, type, false);
} }
exports.parserSql = parserSql; exports.parserSql = parserSql;

View File

@ -1,18 +1,26 @@
{ {
"name": "dt-sql-parser", "name": "dt-sql-parser",
"version": "1.1.10", "version": "1.2.0",
"description": "sql,hive,parser ", "description": "sql,hive,parser ",
"keywords":["hive","hql","sql","parser"], "keywords": [
"main": "index.js", "hive",
"hql",
"sql",
"parser"
],
"main": "lib/index.js",
"scripts": { "scripts": {
"build:parse": "pegjs -o core/astParser.js peg/nquery.pegjs ", "build:parse": "pegjs -o core/astParser.js peg/nquery.pegjs ",
"build:filter": "pegjs -o core/comment.js peg/comment.pegjs ", "build:filter": "pegjs -o core/comment.js peg/comment.pegjs ",
"build:syntax": "sh ./jison/hue-sql-syntax.sh ", "build:syntax": "sh ./jison/hue-sql-syntax.sh ",
"build": "rm -rf lib && tsc" "build": "jest && rm -rf lib && tsc",
"test": "jest"
}, },
"author": "xiaokang", "author": "xiaokang",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/jest": "^24.0.13",
"jest": "^24.8.0",
"node-query": "^0.3.3", "node-query": "^0.3.3",
"pegjs": "^0.10.0" "pegjs": "^0.10.0"
}, },

View File

@ -1,4 +1,32 @@
interface Location {
export const parser:{ first_column: number,
parseSql:Function first_line: number,
last_column: number,
last_line: number
} }
declare enum sqlType {
Hive = 'hive',
None = 'sql',
Impala = 'impala'
}
interface Locations {
// 语句类型
type: string;
// 语法是否缺失
missing?: Boolean;
// 语句位置
location: Location;
}
interface SuggestKeyword {
value: string;
weight: number;
}
interface CompleteParser {
parseSql: (preSql: string, sufSql: string, type: sqlType, d: Boolean) => CompleteResult
}
export interface CompleteResult {
locations: Locations[];
suggestKeywords: SuggestKeyword[];
}
export const parser:CompleteParser;

View File

@ -1,3 +1,29 @@
export const parser:{ import { Locations, SuggestKeyword } from "./sqlAutoCompleteParser";
parseSyntax:Function declare enum sqlType {
Hive = 'hive',
None = 'sql',
Impala = 'impala'
} }
interface SyntaxParser {
parseSyntax: (preSql: string, sufSql: string, type: sqlType, d: Boolean) => SyntaxResult | false
}
interface ExpectedWord {
text: string;
distance: number;
}
interface ErrorLoc {
first_column: number;
first_line: number;
last_column: number;
last_line: number;
}
export interface SyntaxResult {
text: string;
expected: ExpectedWord[];
incompleteStatement: Boolean;
loc: ErrorLoc,
token: string
}
export const parser: SyntaxParser;

View File

@ -1,41 +1,35 @@
// import * as sqlSyntaxParser from '../core/sqlSyntaxParser'; // import * as sqlSyntaxParser from '../core/sqlSyntaxParser';
import * as sqlSyntaxParser from '../core/sqlSyntaxParser'; import * as sqlSyntaxParser from '../core/sqlSyntaxParser';
import * as sqlAutoCompleteParser from '../core/sqlAutoCompleteParser'; import * as sqlAutoCompleteParser from '../core/sqlAutoCompleteParser';
type sql = string | string [];
enum sqlType {
Hive = 'hive',
None = 'sql',
Impala = 'impala'
}
function sqlToParserArgs (sql: sql) {
let preSql = '', sufSql = '';
if(Object.prototype.toString.call(sql) == '[object Array]'){
preSql=sql[0];
sufSql=sql[1];
}
return [preSql, sufSql];
}
/** /**
* *
* @param {(string | Array<string>)} sql
* @param {string} [type="hive"]
*/ */
function parseSyntax(sql, type) { function parseSyntax(sql: sql, type:sqlType = sqlType.Hive): sqlSyntaxParser.SyntaxResult | false {
if (typeof type == "undefined") { const parserArgs = sqlToParserArgs(sql);
type = "hive" return sqlSyntaxParser.parser.parseSyntax(parserArgs[0], parserArgs[1], type, false)
}
let sql1=sql;
let sql2='';
if(sql instanceof Array){
sql1=sql[0];
sql2=sql[1];
}
// @ts-nocheck
return sqlSyntaxParser.parser.parseSyntax(sql1, sql2, type, false)
} }
/** /**
* *
* @param {(string | Array<string>)} sql
* @param {string} [type="hive"]
*/ */
function parserSql(sql, type) { function parserSql(sql: sql, type:sqlType = sqlType.Hive): sqlAutoCompleteParser.CompleteResult {
if (typeof type == "undefined") { const parserArgs = sqlToParserArgs(sql);
type = "hive" return sqlAutoCompleteParser.parser.parseSql(parserArgs[0], parserArgs[1], type, false)
}
let sql1=sql;
let sql2='';
if(sql instanceof Array){
sql1=sql[0];
sql2=sql[1];
}
return sqlAutoCompleteParser.parser.parseSql(sql1, sql2, type, false)
} }
export { export {

View File

@ -13,10 +13,10 @@ start
union_stmt union_stmt
=stmt: =single_stmt:
( (
words:(!kw_start word:. {return word})* words:text*
stmt:(comment:comment {return ''}/quote:quote {return quote}/";" {isSplit=true;return ";"}) stmt:(comment:comment {return comment}/quote:quote {return quote}/";" {isSplit=true;return ";"})
{ {
const text=words.join("")+stmt; const text=words.join("")+stmt;
let index=Math.max(lines.length-1,0); let index=Math.max(lines.length-1,0);
@ -29,9 +29,9 @@ union_stmt
} }
)* other:.* )* other:.*
{ {
const text=stmt.join("")+other.join("") const text=single_stmt.join("")+other.join("")
let index=Math.max(lines.length-1,0); let index=Math.max(lines.length-1,0);
lines[index]=lines[index]+other.join(""); lines[index]=(lines[index]||'')+other.join("");
return text; return text;
} }
@ -75,7 +75,7 @@ quote
text = !kw_start word:. {return word}
kw_start=KW_SINGLE_LINE_START/KW_MULTI_LINE_START/"\""/"'"/";" kw_start=KW_SINGLE_LINE_START/KW_MULTI_LINE_START/"\""/"'"/";"

File diff suppressed because it is too large Load Diff

View File

@ -12,5 +12,10 @@
"exclude": [ "exclude": [
"./src/peg/*", "./src/peg/*",
"./src/jison/*" "./src/jison/*"
],
"typeAcquisition": {
"include": [
"jest"
] ]
} }
}