diff --git a/CHANGELOG.md b/CHANGELOG.md index fa73e01..3239103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [Unreleased] +## [0.0.7] - 2022-08-30 + +- [#57](https://github.com/sqlfluff/vscode-sqlfluff/pull/57) Fix automated tests and JSON parsing errors. + ## [0.0.6] - 2022-07-29 - [#50](https://github.com/sqlfluff/vscode-sqlfluff/pull/50) refactors the extension and adds several new settings. diff --git a/package.json b/package.json index 9912504..35dd569 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vscode-sqlfluff", "displayName": "sqlfluff", - "version": "0.0.6", + "version": "0.0.7", "description": "A linter and auto-formatter for SQLfluff, a popular linting tool for SQL and dbt.", "publisher": "dorzey", "icon": "images/icon.png", @@ -127,16 +127,18 @@ }, "scripts": { "vscode:prepublish": "npm run -S esbuild-base -- --minify", - "compile": "rimraf out && tsc -p ./", + "compile": "rimraf out && tsc -p ./ && npm run postbuild", "watch": "rimraf out && tsc -watch -p ./", "pretest": "npm run compile", "test": "node ./out/test/runTest.js", "download-api": "vscode-dts dev", "postdownload-api": "vscode-dts main", - "postinstall": "npm run download-api", + "lint": "eslint src --ext ts", + "lint:fix": "eslint src --ext ts --fix", "esbuild-base": "rimraf out && esbuild ./src/extension.ts --bundle --outfile=out/src/extension.js --external:vscode --format=cjs --platform=node", "esbuild": "npm run -S esbuild-base -- --sourcemap", "esbuild-watch": "npm run -S esbuild-base -- --sourcemap --watch", + "postbuild": "copyfiles \"./test/suite/test_sql/**/*.sql\" \"./out\" && copyfiles \"./test/.sqlfluff\" \"./out\"", "deploy": "vsce publish" }, "devDependencies": { @@ -146,7 +148,7 @@ "@types/vscode": "^1.59.0", "@typescript-eslint/eslint-plugin": "^5.13.0", "@typescript-eslint/parser": "^5.13.0", - "cpy-cli": "^4.0.0", + "copyfiles": "^2.4.1", "esbuild": "^0.14.24", "eslint": "^8.10.0", "eslint-config-prettier": "^8.5.0", @@ -158,5 +160,11 @@ "vsce": "^2.6.7", "vscode-dts": "^0.3.3", "vscode-test": "^1.3.0" + }, + "__metadata": { + "id": "dd94e113-0773-42ed-9bc0-2f4b55bc7185", + "publisherDisplayName": "dorzey", + "publisherId": "db31b9db-3aa2-44a0-8541-71cab84423a9", + "isPreReleaseVersion": false } } diff --git a/src/extension.ts b/src/extension.ts index fd781a6..2d7c6f0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,6 +12,12 @@ export const activate = (context: vscode.ExtensionContext) => { context.subscriptions.push( vscode.languages.registerCodeActionsProvider("sql", new SQLFluffQuickFix(), { providedCodeActionKinds: SQLFluffQuickFix.providedCodeActionKind + }), + vscode.languages.registerCodeActionsProvider("sql-bigquery", new SQLFluffQuickFix(), { + providedCodeActionKinds: SQLFluffQuickFix.providedCodeActionKind + }), + vscode.languages.registerCodeActionsProvider("jinja-sql", new SQLFluffQuickFix(), { + providedCodeActionKinds: SQLFluffQuickFix.providedCodeActionKind }) ); diff --git a/src/features/formatter/formattingProvider.ts b/src/features/formatter/formattingProvider.ts index 71a36fe..6f7af96 100644 --- a/src/features/formatter/formattingProvider.ts +++ b/src/features/formatter/formattingProvider.ts @@ -11,8 +11,8 @@ export class DocumentFormattingEditProvider { async provideDocumentFormattingEdits( document: vscode.TextDocument ): Promise { - const filePath = document.fileName.replace(/\\/g, "/"); - const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath.replace(/\\/g, "/"); + const filePath = document.fileName.replace(/\\+/g, "/"); + const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath.replace(/\\+/g, "/"); const workingDirectory = Configuration.workingDirectory() ? Configuration.workingDirectory() : rootPath; const textEdits: vscode.TextEdit[] = []; diff --git a/src/features/sqlFluffLinter.ts b/src/features/sqlFluffLinter.ts index dc43ead..1ab737c 100644 --- a/src/features/sqlFluffLinter.ts +++ b/src/features/sqlFluffLinter.ts @@ -17,8 +17,9 @@ export class SQLFluffLinterProvider implements Linter { const diagnostics: Diagnostic[] = []; lines.forEach((line) => { let filePaths: Array; + const normalizedLine = line.replace(/\\+/g, "/"); try { - filePaths = JSON.parse(line); + filePaths = JSON.parse(normalizedLine); } catch (e) { // JSON.parse may fail if sqlfluff compilation prints non-JSON formatted messages console.warn(e); diff --git a/src/features/utils/lintingProvider.ts b/src/features/utils/lintingProvider.ts index ec56bcb..5d70b47 100644 --- a/src/features/utils/lintingProvider.ts +++ b/src/features/utils/lintingProvider.ts @@ -98,8 +98,8 @@ export class LintingProvider { private doLint(document: vscode.TextDocument): Promise { return new Promise((resolve) => { const decoder = new LineDecoder(); - const filePath = document.fileName.replace(/\\/g, "/"); - const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath.replace(/\\/g, "/"); + const filePath = document.fileName.replace(/\\+/g, "/"); + const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath.replace(/\\+/g, "/"); const workingDirectory = Configuration.workingDirectory() ? Configuration.workingDirectory() : rootPath; let args: string[]; diff --git a/test/suite/extension.test.ts b/test/suite/extension.test.ts index 4873a6f..c847ea2 100644 --- a/test/suite/extension.test.ts +++ b/test/suite/extension.test.ts @@ -1,61 +1,52 @@ import * as assert from "assert"; import * as vscode from "vscode"; -import { activate, format, getDocUri, toRange } from "./helper"; +import * as Helper from "./helper"; + +const TIMEOUT = 1000000; -const TIMEOUT = 4000; suite("Extension Test Suite", () => { vscode.window.showInformationMessage("Start all tests."); test("Good SQL should have zero diagnostics", async () => { - const docUri = getDocUri("/test_sql/good.sql"); - await activate(docUri); - - - const actualDiagnostics = vscode.languages.getDiagnostics(docUri); + const documentUri = Helper.getDocumentUri("/test_sql/good.sql"); + await Helper.activate(documentUri); + const actualDiagnostics = vscode.languages.getDiagnostics(documentUri); assert.strictEqual(actualDiagnostics.length, 0); }).timeout(TIMEOUT); test("Bad SQL should have the correct diagnostics", async () => { + const documentUri = Helper.getDocumentUri("/test_sql/bad.sql"); + await Helper.activate(documentUri); - const docUri = getDocUri("/test_sql/bad.sql"); - await activate(docUri); - - - const actualDiagnostics = vscode.languages.getDiagnostics(docUri); - + const actualDiagnostics = vscode.languages.getDiagnostics(documentUri); - assert.strictEqual(actualDiagnostics.length, 3); + assert.strictEqual(actualDiagnostics.length, 2); [ - { range: toRange(0, 1, 0, 1), message: "Query produces an unknown number of result columns.", code: "L044" }, - { range: toRange(0, 10, 0, 10), message: "Inconsistent capitalisation of keywords.", code: "L010" }, - { range: toRange(0, 22, 0, 22), message: "Files must end with a trailing newline.", code: "L009" }, + { range: Helper.toRange(1, 10, 1, 10), message: "Keywords must be consistently upper case.", code: "L010" }, + { range: Helper.toRange(2, 1, 2, 1), message: "Files must end with a single trailing newline.", code: "L009" }, ].forEach((expectedDiagnostic, i) => { assertDiagnosticIsEqual(actualDiagnostics[i], expectedDiagnostic); }); - }).timeout(TIMEOUT); test("Bad SQL has zero diagnostics after document format", async () => { + const documentUri = Helper.getDocumentUri("/test_sql/format.sql"); + // const document = await Helper.activate(documentUri); + // const preFormatDiagnostics = vscode.languages.getDiagnostics(documentUri); + // assert.strictEqual(preFormatDiagnostics.length, 1, "Pre-format diagnostics not expected length"); - const docUri = getDocUri("/test_sql/format.sql"); - const document = await activate(docUri); - const preFormatDiagnostics = vscode.languages.getDiagnostics(docUri); - assert.strictEqual(preFormatDiagnostics.length, 1, "Pre-format diagnostics not expected length"); - - - await format(document); - await activate(docUri); + await Helper.format(documentUri); + // await Helper.activate(documentUri); - - const postFormatDiagnostics = vscode.languages.getDiagnostics(docUri); + const postFormatDiagnostics = vscode.languages.getDiagnostics(documentUri); assert.strictEqual(postFormatDiagnostics.length, 0, "Post-format diagnostics not expected length"); - }).timeout(9999999); + }).timeout(TIMEOUT); const assertDiagnosticIsEqual = (actual: vscode.Diagnostic, expected: { range: any; message: any; code: any; }) => { assert.deepStrictEqual(actual.range, expected.range); @@ -64,5 +55,4 @@ suite("Extension Test Suite", () => { assert.strictEqual(actual.code, expected.code); assert.strictEqual(actual.source, "sqlfluff"); }; - }); diff --git a/test/suite/helper.ts b/test/suite/helper.ts index 2ff61cd..047e897 100644 --- a/test/suite/helper.ts +++ b/test/suite/helper.ts @@ -1,14 +1,18 @@ import * as vscode from "vscode"; -export const activate = async (docUri: vscode.Uri): Promise => { +export const SLEEP_TIME = 10000; + +export const activate = async (documentUri: vscode.Uri): Promise => { // The extensionId is `publisher.name` from package.json - const ext = vscode.extensions.getExtension("vscode-sqlfluff"); - await ext?.activate(); + const extension = vscode.extensions.getExtension("vscode-sqlfluff"); + await extension?.activate(); try { - const document = await vscode.workspace.openTextDocument(docUri); - const editor = await vscode.window.showTextDocument(document); + await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); + const document = await vscode.workspace.openTextDocument(documentUri); + await vscode.window.showTextDocument(document); + await document.save(); - await sleep(2000); // Wait for server activation + await sleep(SLEEP_TIME); // Wait for server activation return document; } catch (e) { @@ -16,31 +20,35 @@ export const activate = async (docUri: vscode.Uri): Promise { - if (document) { - try { - await vscode.commands.executeCommand("editor.action.formatDocument"); - await sleep(2000); - await document.save(); - await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); - } catch (e) { - console.error(e); - } +export const format = async (documentUri: vscode.Uri) => { + try { + await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); + const document = await vscode.workspace.openTextDocument(documentUri); + await vscode.window.showTextDocument(document); + await vscode.commands.executeCommand("editor.action.formatDocument"); + await sleep(SLEEP_TIME); + await document.save(); + + await sleep(SLEEP_TIME); // Wait for server activation + + return document; + } catch (e) { + console.error(e); } }; -const sleep = async (ms: number): Promise => { +export const sleep = async (ms: number): Promise => { return new Promise(resolve => { return setTimeout(resolve, ms); }); }; -export const getDocUri = (p: string) => { +export const getDocumentUri = (p: string) => { return vscode.Uri.file(__dirname + p); }; -export const toRange = (sLine: number, sChar: number, eLine: number, eChar: number) => { - const start = new vscode.Position(sLine, sChar); - const end = new vscode.Position(eLine, eChar); +export const toRange = (startLine: number, StartCharacter: number, endLine: number, endCharacter: number) => { + const start = new vscode.Position(startLine, StartCharacter); + const end = new vscode.Position(endLine, endCharacter); return new vscode.Range(start, end); }; diff --git a/test/suite/test_sql/bad.sql b/test/suite/test_sql/bad.sql index f3052e8..d6002f4 100644 --- a/test/suite/test_sql/bad.sql +++ b/test/suite/test_sql/bad.sql @@ -1,2 +1,3 @@ -- 割引金額 -select a from b; +SELECT a from b; + diff --git a/test/suite/test_sql/format.sql b/test/suite/test_sql/format.sql index c5fd447..9101399 100644 --- a/test/suite/test_sql/format.sql +++ b/test/suite/test_sql/format.sql @@ -1 +1 @@ -SELECT a FROM a_table; +SELECT a from a_table; diff --git a/test/suite/test_sql/good.sql b/test/suite/test_sql/good.sql index 73fceca..c5fd447 100644 --- a/test/suite/test_sql/good.sql +++ b/test/suite/test_sql/good.sql @@ -1 +1 @@ -select a from a_table; +SELECT a FROM a_table;