From f226f95da39a0d5d5f0ca48b198813e57137c2c1 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 10:24:37 +0200 Subject: [PATCH 1/7] Improve document detection Detect not only .yml but also .yaml document extensions. --- client/package-lock.json | 13 +++- client/package.json | 3 +- client/src/common/utils.ts | 98 ++++++++++++++++++++---------- client/src/requests/gxworkflows.ts | 25 ++++++-- package-lock.json | 4 +- 5 files changed, 101 insertions(+), 42 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index ad46de4..ac0b888 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,8 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "vscode-languageclient": "^8.1.0" + "vscode-languageclient": "^8.1.0", + "vscode-uri": "^3.0.8" }, "engines": { "vscode": "^1.63.0" @@ -99,6 +100,11 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -172,6 +178,11 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/client/package.json b/client/package.json index fef8b52..b8b8e13 100644 --- a/client/package.json +++ b/client/package.json @@ -16,7 +16,8 @@ "vscode": "^1.63.0" }, "dependencies": { - "vscode-languageclient": "^8.1.0" + "vscode-languageclient": "^8.1.0", + "vscode-uri": "^3.0.8" }, "scripts": { "webpack": "webpack", diff --git a/client/src/common/utils.ts b/client/src/common/utils.ts index 1d69a51..c143596 100644 --- a/client/src/common/utils.ts +++ b/client/src/common/utils.ts @@ -1,4 +1,5 @@ -import { OutputChannel, Uri, workspace } from "vscode"; +import { workspace } from "vscode"; +import { URI } from "vscode-uri"; /** * Determines if the current workspace contains @@ -22,8 +23,8 @@ export function getWorkspaceScheme(): "file" | "vscode-vfs" { * @param targetScheme The new scheme. * @returns A new copy of the URI with the new scheme. */ -export function replaceUriScheme(uri: Uri, targetScheme: string): Uri { - return Uri.parse(uri.toString().replace(uri.scheme, targetScheme)); +export function replaceUriScheme(uri: URI, targetScheme: string): URI { + return URI.parse(uri.toString().replace(uri.scheme, targetScheme)); } /** @@ -32,44 +33,77 @@ export function replaceUriScheme(uri: Uri, targetScheme: string): Uri { * @param ref The git ref to add to the URI query * @returns The URI with a ref query value set */ -export function addRefToUri(uri: Uri, ref: string): Uri { - return Uri.parse(uri.toString() + `?ref=${ref}`); +export function addRefToUri(uri: URI, ref: string): URI { + return URI.parse(uri.toString() + `?ref=${ref}`); } -/** Just for debugging */ -export function debugPrintCommandArgs(command: string, args: unknown[], outputChannel: OutputChannel): void { - outputChannel.appendLine(`Command ${command} args:`); - for (let index = 0; index < args.length; index++) { - const element = args[index]; - outputChannel.appendLine(` [${index}] ${JSON.stringify(element)}`); - } - outputChannel.appendLine(`---\n`); +// Workflow tests document can end with -test.yml, -tests.yml, -test.yaml, -tests.yaml +const workflowTestsDocumentPattern = /(.*)-(test|tests)\.(yml|yaml)$/; + +// Workflow format1 documents can end with .ga +// Workflow format2 documents can end with .gxwf.yml or .gxwf.yaml +const format1WorkflowDocumentPattern = /\.ga$/; +const format2WorkflowDocumentPattern = /\.gxwf\.(yml|yaml)$/; + +export function isWorkflowTestsDocument(uri: URI): boolean { + return workflowTestsDocumentPattern.test(uri.path); +} + +export function isNativeWorkflowDocument(uri: URI): boolean { + return format1WorkflowDocumentPattern.test(uri.path); } -export function isWorkflowTestsDocument(uri: Uri): boolean { - return uri.path.endsWith("-test.yml") || uri.path.endsWith("-tests.yml"); +export function isFormat2WorkflowDocument(uri: URI): boolean { + return format2WorkflowDocumentPattern.test(uri.path); +} + +export async function getAssociatedWorkflowUriFromTestsUri(workflowTestsDocumentUri: URI): Promise { + if (!isWorkflowTestsDocument(workflowTestsDocumentUri)) { + return undefined; + } + + //Try to find a format1 workflow document first + let workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".ga"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + //Try to find a format2 workflow document + workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".gxwf.yaml"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + + workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".gxwf.yml"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + return undefined; } -export function isNativeWorkflowDocument(uri: Uri): boolean { - return uri.path.endsWith(".ga"); +/** + * Replaces the matched pattern in the URI path with the replacement. + * @param uri The URI to be modified. + * @param pattern The pattern to match in the URI path. + * @param replacement The replacement string. + * @returns A new copy of the URI with the pattern replaced. + */ +export function replaceUriPattern(uri: URI, pattern: RegExp, replacement: string): URI { + const uriString = uri.toString(); + const newUriString = uriString.replace(pattern, `$1${replacement}`); + const result = URI.parse(newUriString); + return result; } -export async function getAssociatedWorkflowUriFromTestsUri(workflowTestsDocumentUri: Uri): Promise { - const format2WorkflowUri = Uri.parse( - workflowTestsDocumentUri.toString().replace("-test.yml", ".gxwf.yml").replace("-tests.yml", ".gxwf.yml") - ); +/** + * Determines if a file exists at the given URI in the workspace. + * @param uri The URI to check for existence. + * @returns true if the (virtual) file exists, false otherwise. + */ +export async function fileUriExistsInWorkspace(uri: URI): Promise { try { - await workspace.fs.stat(format2WorkflowUri); - return format2WorkflowUri; + await workspace.fs.stat(uri); + return true; } catch { - const nativeWorkflowUri = Uri.parse( - workflowTestsDocumentUri.toString().replace("-test.yml", ".ga").replace("-tests.yml", ".ga") - ); - try { - await workspace.fs.stat(nativeWorkflowUri); - return nativeWorkflowUri; - } catch { - return undefined; - } + return false; } } diff --git a/client/src/requests/gxworkflows.ts b/client/src/requests/gxworkflows.ts index baad2f4..42ec2a7 100644 --- a/client/src/requests/gxworkflows.ts +++ b/client/src/requests/gxworkflows.ts @@ -12,6 +12,8 @@ import { TargetWorkflowDocumentParams, } from "../languageTypes"; +const TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP = new Map(); + export function setupRequests( context: ExtensionContext, nativeWorkflowClient: BaseLanguageClient, @@ -19,23 +21,34 @@ export function setupRequests( ): void { function createRequestHandler(requestIdentifier: string) { return async (params: TargetWorkflowDocumentParams) => { - let targetUri: Uri | undefined = Uri.parse(params.uri); + const targetUri: Uri | undefined = Uri.parse(params.uri); + let resultUri: Uri | undefined = undefined; if (isWorkflowTestsDocument(targetUri)) { // If the target is a test file, we need to find the associated workflow file - targetUri = await getAssociatedWorkflowUriFromTestsUri(targetUri); + //Try cache first + const cacheKey = targetUri.toString(); + if (TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.has(cacheKey)) { + resultUri = TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.get(cacheKey)!; + } + if (!resultUri) { + resultUri = await getAssociatedWorkflowUriFromTestsUri(targetUri); + if (resultUri) { + TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.set(cacheKey, resultUri); + } + } } - if (!targetUri) { + if (!resultUri) { console.debug("No associated workflow file found for:", params.uri); return undefined; } // Open the file to include it in the document cache - await workspace.openTextDocument(targetUri); + await workspace.openTextDocument(resultUri); let languageClient = gxFormat2Client; - if (isNativeWorkflowDocument(targetUri)) { + if (isNativeWorkflowDocument(resultUri)) { languageClient = nativeWorkflowClient; } - const requestParams: TargetWorkflowDocumentParams = { uri: targetUri.toString() }; + const requestParams: TargetWorkflowDocumentParams = { uri: resultUri.toString() }; const result = await languageClient.sendRequest(requestIdentifier, requestParams); return result; }; diff --git a/package-lock.json b/package-lock.json index fe78658..bc3ca55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "galaxy-workflows", - "version": "0.3.1", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "galaxy-workflows", - "version": "0.3.1", + "version": "0.4.0", "hasInstallScript": true, "license": "MIT", "devDependencies": { From 42d6114ba812619a49e4385a3e6f7993e18d1fab Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 10:25:00 +0200 Subject: [PATCH 2/7] Add unit tests for isWorkflowTestsDocument, isNativeWorkflowDocument, and isFormat2WorkflowDocument --- client/tests/unit/utils.test.ts | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 client/tests/unit/utils.test.ts diff --git a/client/tests/unit/utils.test.ts b/client/tests/unit/utils.test.ts new file mode 100644 index 0000000..f3e3428 --- /dev/null +++ b/client/tests/unit/utils.test.ts @@ -0,0 +1,62 @@ +import { it } from "@jest/globals"; // This is a workaround for type clashes between jest and mocha +import { URI } from "vscode-uri"; +import { isFormat2WorkflowDocument, isNativeWorkflowDocument, isWorkflowTestsDocument } from "../../src/common/utils"; + +jest.mock( + "vscode", + () => ({ + workspace: { + // Mock properties and methods of `workspace` as needed for your tests + }, + // Add other vscode namespaces and members you need to mock + }), + { virtual: true } +); + +describe("Common Utils", () => { + describe("isWorkflowTestsDocument", () => { + it.each([ + ["-test.yml", true], + ["-tests.yml", true], + ["-test.yaml", true], + ["-tests.yaml", true], + ["test.txt", false], + ["tests.txt", false], + ["test.yml", false], + ["tests.yml", false], + ["whatever.test.yml", false], + ["whatever.gxwf.test.yml", false], + ["whatevertest.yml", false], + ["whatever.gxwftest.yml", false], + ])("given '%s' should return %s", (input: string, expected: boolean) => { + expect(isWorkflowTestsDocument(URI.parse(input))).toBe(expected); + }); + }); + + describe("isNativeWorkflowDocument", () => { + it.each([ + ["test.ga", true], + ["whatever.ga", true], + ["asd.txt", false], + ["test.yaml", false], + ])("given '%s' should return %s", (input: string, expected: boolean) => { + expect(isNativeWorkflowDocument(URI.parse(input))).toBe(expected); + }); + }); + + describe("isFormat2WorkflowDocument", () => { + it.each([ + ["test.gxwf.yaml", true], + ["whatever.gxwf.yaml", true], + ["test.gxwf.yml", true], + ["whatever.gxwf.yml", true], + ["asd.txt", false], + ["-test.yaml", false], + ["whatever-test.yaml", false], + ["whatever.gxwf-test.yaml", false], + ["whatever.gxwf.test.yaml", false], + ])("given '%s' should return %s", (input: string, expected: boolean) => { + expect(isFormat2WorkflowDocument(URI.parse(input))).toBe(expected); + }); + }); +}); From 842af7afaf6e19b64e54da01d4d2df10ec1e8101 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:11:37 +0200 Subject: [PATCH 3/7] Add test coverage for getAssociatedWorkflowUriFromTestsUri --- client/tests/unit/utils.test.ts | 57 +++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/client/tests/unit/utils.test.ts b/client/tests/unit/utils.test.ts index f3e3428..9728616 100644 --- a/client/tests/unit/utils.test.ts +++ b/client/tests/unit/utils.test.ts @@ -1,14 +1,33 @@ import { it } from "@jest/globals"; // This is a workaround for type clashes between jest and mocha import { URI } from "vscode-uri"; -import { isFormat2WorkflowDocument, isNativeWorkflowDocument, isWorkflowTestsDocument } from "../../src/common/utils"; +import { + getAssociatedWorkflowUriFromTestsUri, + isFormat2WorkflowDocument, + isNativeWorkflowDocument, + isWorkflowTestsDocument, +} from "../../src/common/utils"; + +// Partially mimics vscode FileStat interface +interface FileStat { + size: number; +} + +const FILES_IN_WORKSPACE = ["workflow1.ga", "workflow2.gxwf.yaml", "workflow3.gxwf.yml"]; jest.mock( "vscode", () => ({ workspace: { - // Mock properties and methods of `workspace` as needed for your tests + fs: { + stat: (uri: URI) => { + const file = FILES_IN_WORKSPACE.find((f) => URI.parse(f).path === uri.path); + if (file) { + return Promise.resolve({ size: file.length }); + } + throw new Error(`File not found: ${uri.path}`); + }, + }, }, - // Add other vscode namespaces and members you need to mock }), { virtual: true } ); @@ -59,4 +78,36 @@ describe("Common Utils", () => { expect(isFormat2WorkflowDocument(URI.parse(input))).toBe(expected); }); }); + + describe("getAssociatedWorkflowUriFromTestsUri", () => { + it("should return undefined if the input URI is not a workflow tests document", async () => { + const uri = URI.parse("test.txt"); + const result = await getAssociatedWorkflowUriFromTestsUri(uri); + expect(result).toBeUndefined(); + }); + + it("should return the associated (.ga) workflow document URI if it exists in workspace", async () => { + const uri = URI.parse("workflow1-test.yaml"); + const result = await getAssociatedWorkflowUriFromTestsUri(uri); + expect(result?.path.endsWith("workflow1.ga")).toBe(true); + }); + + it("should return the associated (yaml) workflow document URI if it exists in workspace", async () => { + const uri = URI.parse("workflow2-test.yaml"); + const result = await getAssociatedWorkflowUriFromTestsUri(uri); + expect(result?.path.endsWith("workflow2.gxwf.yaml")).toBe(true); + }); + + it("should return the associated (yml) workflow document URI if it exists in workspace", async () => { + const uri = URI.parse("workflow3-tests.yaml"); + const result = await getAssociatedWorkflowUriFromTestsUri(uri); + expect(result?.path.endsWith("workflow3.gxwf.yml")).toBe(true); + }); + + it("should return undefined if the associated workflow document does not exist in workspace", async () => { + const uri = URI.parse("nonexistent-test.yaml"); + const result = await getAssociatedWorkflowUriFromTestsUri(uri); + expect(result).toBeUndefined(); + }); + }); }); From 7521fae99ae4b7070c7427d942cb220a0dcd18cc Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:21:11 +0200 Subject: [PATCH 4/7] Add support for additional workflow file extensions This improves the document detection for Galaxy workflow and tests files. --- package.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index eb9c3cc..0155651 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "Galaxy Workflow (YAML)" ], "extensions": [ - ".gxwf.yml" + ".gxwf.yml", + ".gxwf.yaml" ], "configuration": "./workflow-languages/configurations/yml.language-configuration.json" }, @@ -67,7 +68,10 @@ "Galaxy Workflow Tests (YAML)" ], "extensions": [ - "-tests.yml" + "-test.yml", + "-tests.yml", + "-test.yaml", + "-tests.yaml" ], "configuration": "./workflow-languages/configurations/yml.language-configuration.json" } From 4d6f322e14d52b7adf8e061a93d3399a8016b598 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:25:52 +0200 Subject: [PATCH 5/7] Remove placeholder test file --- client/tests/unit/client.test.ts | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 client/tests/unit/client.test.ts diff --git a/client/tests/unit/client.test.ts b/client/tests/unit/client.test.ts deleted file mode 100644 index 7d80b5d..0000000 --- a/client/tests/unit/client.test.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe("Client", () => { - it("should test", () => { - expect(true).toBe(true); - }); -}); From 52f3f807bb8d4543c6f95560f3adee6718b6585a Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:55:59 +0200 Subject: [PATCH 6/7] Update vscode launch configuration and e2e test file paths --- .vscode/launch.json | 4 ++-- client/tests/e2e/suite/helpers.ts | 6 +++--- package.json | 6 +++--- server/package.json | 1 + 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 848517e..c4af8a1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -82,9 +82,9 @@ "args": [ "--disable-extensions", "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/client/out/e2e/suite/index" + "--extensionTestsPath=${workspaceFolder}/client/out/tests/e2e/suite/index" ], - "outFiles": ["${workspaceFolder}client/out/e2e/**/*.js"], + "outFiles": ["${workspaceFolder}client/out/tests/e2e/**/*.js"], "preLaunchTask": { "type": "npm", "script": "test-compile" diff --git a/client/tests/e2e/suite/helpers.ts b/client/tests/e2e/suite/helpers.ts index 39d742a..29edd10 100644 --- a/client/tests/e2e/suite/helpers.ts +++ b/client/tests/e2e/suite/helpers.ts @@ -1,6 +1,6 @@ -import * as vscode from "vscode"; -import * as path from "path"; import * as assert from "assert"; +import * as path from "path"; +import * as vscode from "vscode"; /** * Contains the document and its corresponding editor @@ -60,7 +60,7 @@ export async function waitForDiagnostics(docUri: vscode.Uri, timeoutInMillisecon } export const getDocPath = (filePath: string): string => { - return path.resolve(__dirname, path.join("..", "..", "..", "..", "test-data", filePath)); + return path.resolve(__dirname, path.join("..", "..", "..", "..", "..", "test-data", filePath)); }; export const getDocUri = (filePath: string): vscode.Uri => { diff --git a/package.json b/package.json index 0155651..17b3e5e 100644 --- a/package.json +++ b/package.json @@ -219,7 +219,7 @@ "postinstall": "cd client && npm install && cd ../server && npm install && cd ..", "lint": "eslint ./client/src ./server --ext .ts,.tsx", "format": "prettier --write .", - "clean": "rimraf client/dist && rimraf server/dist", + "clean": "rimraf client/dist && rimraf client/out && cd server && npm run clean && cd ..", "compile-servers": "cd server && npm run compile", "compile": "npm run clean && webpack --config ./client/webpack.config.js && npm run compile-servers", "vscode:prepublish": "npm run compile", @@ -230,8 +230,8 @@ "test-client": "cd client && npm test", "test-server": "cd server && npm test", "test-compile": "tsc --project ./client --outDir client/out", - "pretest:e2e": "npm run compile && npm run test-compile", - "test:e2e": "node ./client/out/e2e/runTests.js", + "pretest:e2e": "npm run clean && npm run compile && npm run test-compile", + "test:e2e": "node ./client/out/tests/e2e/runTests.js", "test-browser": "vscode-test-web --extensionDevelopmentPath=. ./test-data" }, "devDependencies": { diff --git a/server/package.json b/server/package.json index a75b4d1..7461cd8 100644 --- a/server/package.json +++ b/server/package.json @@ -6,6 +6,7 @@ "author": "davelopez", "license": "MIT", "scripts": { + "clean": "rimraf ./gx-workflow-ls-native/dist && rimraf ./gx-workflow-ls-format2/dist", "compile-native-server": "webpack --config ./gx-workflow-ls-native/webpack.config.js", "compile-format2-server": "webpack --config ./gx-workflow-ls-format2/webpack.config.js", "compile": "npm run compile-native-server && npm run compile-format2-server", From 866a8a649df9fbfc5d6ef7c5e74cb6f342011b30 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:32:47 +0200 Subject: [PATCH 7/7] Refactor e2e tests configuration + strict types in client --- client/package-lock.json | 65 ++++++++++++++++++++++ client/package.json | 3 + client/src/commands/index.ts | 5 ++ client/tests/e2e/runTests.ts | 2 +- client/tests/e2e/suite/extension.ga.e2e.ts | 15 +++-- client/tests/e2e/suite/helpers.ts | 10 ++-- client/tests/e2e/tsconfig.json | 11 ++++ client/tsconfig.json | 5 +- package.json | 2 +- 9 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 client/tests/e2e/tsconfig.json diff --git a/client/package-lock.json b/client/package-lock.json index ac0b888..7489b81 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,10 +12,38 @@ "vscode-languageclient": "^8.1.0", "vscode-uri": "^3.0.8" }, + "devDependencies": { + "@types/glob": "^8.1.0" + }, "engines": { "vscode": "^1.63.0" } }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -65,6 +93,12 @@ "node": ">=10" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/vscode-jsonrpc": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz", @@ -112,6 +146,31 @@ } }, "dependencies": { + "@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "requires": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -149,6 +208,12 @@ "lru-cache": "^6.0.0" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "vscode-jsonrpc": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz", diff --git a/client/package.json b/client/package.json index b8b8e13..9b90320 100644 --- a/client/package.json +++ b/client/package.json @@ -23,5 +23,8 @@ "webpack": "webpack", "watch": "webpack --watch --progress", "test": "jest" + }, + "devDependencies": { + "@types/glob": "^8.1.0" } } diff --git a/client/src/commands/index.ts b/client/src/commands/index.ts index e903df1..3de261b 100644 --- a/client/src/commands/index.ts +++ b/client/src/commands/index.ts @@ -57,6 +57,11 @@ export class ComparableWorkflow { uri: Uri; ref?: string; + constructor(uri: Uri, ref?: string) { + this.uri = uri; + this.ref = ref; + } + // TODO: This is no longer working until a new API is available // ref: https://github.com/microsoft/vscode/issues/177319 // ref: https://github.com/microsoft/vscode/issues/84297 diff --git a/client/tests/e2e/runTests.ts b/client/tests/e2e/runTests.ts index c871f34..3d87e91 100644 --- a/client/tests/e2e/runTests.ts +++ b/client/tests/e2e/runTests.ts @@ -6,7 +6,7 @@ async function main(): Promise { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, "../../../"); + const extensionDevelopmentPath = path.resolve(__dirname, "../../../../"); // The path to test runner // Passed to --extensionTestsPath diff --git a/client/tests/e2e/suite/extension.ga.e2e.ts b/client/tests/e2e/suite/extension.ga.e2e.ts index 8cab3cd..1f387db 100644 --- a/client/tests/e2e/suite/extension.ga.e2e.ts +++ b/client/tests/e2e/suite/extension.ga.e2e.ts @@ -1,18 +1,18 @@ // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from "vscode"; -import * as path from "path"; import * as assert from "assert"; import { beforeEach } from "mocha"; +import * as path from "path"; +import * as vscode from "vscode"; import { activateAndOpenInEditor, - getDocUri, + assertDiagnostics, closeAllEditors, + getDocUri, openDocument, + resetSettings, sleep, - assertDiagnostics, updateSettings, - resetSettings, waitForDiagnostics, } from "./helpers"; @@ -22,7 +22,9 @@ suite("Native (JSON) Workflows", () => { test("Clean workflow command removes non-essential properties", async () => { const dirtyDocUri = getDocUri(path.join("json", "clean", "wf_01_dirty.ga")); const cleanDocUri = getDocUri(path.join("json", "clean", "wf_01_clean.ga")); - const { document } = await activateAndOpenInEditor(dirtyDocUri); + const editor = await activateAndOpenInEditor(dirtyDocUri); + const document = editor?.document; + assert.ok(document); await sleep(500); // Wait for extension to fully activate... yes Windows CI I'm looking at you... const dirtyDoc = document.getText(); await vscode.commands.executeCommand("galaxy-workflows.cleanWorkflow"); @@ -30,6 +32,7 @@ suite("Native (JSON) Workflows", () => { const actualCleanJson = document.getText(); assert.notEqual(dirtyDoc, actualCleanJson); const expectedCleanDocument = await openDocument(cleanDocUri); + assert.ok(expectedCleanDocument); const expectedCleanJson = expectedCleanDocument.getText(); assert.strictEqual(actualCleanJson, expectedCleanJson); }); diff --git a/client/tests/e2e/suite/helpers.ts b/client/tests/e2e/suite/helpers.ts index 29edd10..939ac28 100644 --- a/client/tests/e2e/suite/helpers.ts +++ b/client/tests/e2e/suite/helpers.ts @@ -12,11 +12,11 @@ export interface DocumentEditor { export async function activate(): Promise { const ext = vscode.extensions.getExtension("davelopez.galaxy-workflows"); - const api = ext.isActive ? ext.exports : await ext.activate(); + const api = ext?.isActive ? ext.exports : await ext?.activate(); return api; } -export async function openDocumentInEditor(docUri: vscode.Uri): Promise { +export async function openDocumentInEditor(docUri: vscode.Uri): Promise { try { const document = await vscode.workspace.openTextDocument(docUri); const editor = await vscode.window.showTextDocument(document); @@ -29,16 +29,18 @@ export async function openDocumentInEditor(docUri: vscode.Uri): Promise { +export async function openDocument(docUri: vscode.Uri): Promise { try { const document = await vscode.workspace.openTextDocument(docUri); return document; } catch (e) { console.error(e); } + + return undefined; } -export async function activateAndOpenInEditor(docUri: vscode.Uri): Promise { +export async function activateAndOpenInEditor(docUri: vscode.Uri): Promise { await activate(); const documentEditor = await openDocumentInEditor(docUri); return documentEditor; diff --git a/client/tests/e2e/tsconfig.json b/client/tests/e2e/tsconfig.json new file mode 100644 index 0000000..e5954c9 --- /dev/null +++ b/client/tests/e2e/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2019", + "lib": ["ES2019", "WebWorker"], + "module": "commonjs", + "sourceMap": true, + "strict": true, + "baseUrl": ".", + "skipLibCheck": true + } +} diff --git a/client/tsconfig.json b/client/tsconfig.json index c7417ce..4c4d44d 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -1,10 +1,11 @@ { "compilerOptions": { - "module": "commonjs", "target": "es2019", "lib": ["ES2019", "WebWorker"], - "rootDirs": ["src", "tests"], + "module": "commonjs", "sourceMap": true, + "strict": true, + "baseUrl": ".", "skipLibCheck": true }, "include": ["tests"], diff --git a/package.json b/package.json index 17b3e5e..b76536f 100644 --- a/package.json +++ b/package.json @@ -229,7 +229,7 @@ "test": "npm run test-client && npm run test-server", "test-client": "cd client && npm test", "test-server": "cd server && npm test", - "test-compile": "tsc --project ./client --outDir client/out", + "test-compile": "tsc --project ./client/tests/e2e --outDir client/out/tests/e2e", "pretest:e2e": "npm run clean && npm run compile && npm run test-compile", "test:e2e": "node ./client/out/tests/e2e/runTests.js", "test-browser": "vscode-test-web --extensionDevelopmentPath=. ./test-data"