From 465cbf9903288002cf072b26a534cb8947a0d6fc Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 20 Oct 2024 17:55:37 +0200 Subject: [PATCH] test: Execute all tests on VSIX Installation base --- .github/workflows/build.yml | 16 +++++++ .gitignore | 1 + .vscode-test.mjs | 68 ++++++++++++++------------ package-lock.json | 96 ++++++++++++++++++++++++++++++++----- package.json | 9 +++- scripts/extractVsix.mts | 34 +++++++++++++ src/esbuild.ts | 17 ++++++- 7 files changed, 195 insertions(+), 46 deletions(-) create mode 100644 scripts/extractVsix.mts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa28fe3..f26887f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,22 @@ jobs: run: npm test if: runner.os != 'Linux' + - name: Pack for VSIX Tests + run: npm run package:test + env: + TEST_TEMP: ${{ runner.temp }} + + - name: Run VSIX Tests (Linux) + run: xvfb-run -a npm run test:vsix + env: + TEST_TEMP: ${{ runner.temp }} + if: runner.os == 'Linux' + - name: Run VSIX Tests (Win/MacOS) + run: npm run test:vsix + env: + TEST_TEMP: ${{ runner.temp }} + if: runner.os != 'Linux' + - name: Run Linter if: always() run: npm run lint diff --git a/.gitignore b/.gitignore index 70839a0..efb6be7 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ dist out *.vsix vscode*.d.ts +tmp \ No newline at end of file diff --git a/.vscode-test.mjs b/.vscode-test.mjs index 214e97c..54de15c 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -3,6 +3,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; + const dirname = fileURLToPath(new URL('.', import.meta.url)); const integrationTestDir = path.join(dirname, 'out/test/integration'); const workspaceBaseDir = path.join(dirname, 'test-workspaces'); @@ -10,41 +11,46 @@ const workspaceBaseDir = path.join(dirname, 'test-workspaces'); const vsCodeVersion = process.env.VSCODE_TEST_VERSION ?? 'stable'; const vsCodePlatform = process.env.VSCODE_TEST_PLATFORM ?? 'desktop'; -let createCommonOptions = (label) => { - if (process.env.GITHUB_ACTIONS) { - return { - platform: vsCodePlatform, - version: vsCodeVersion, - env: { - MOCHA_COLORS: 'true', - MOCHA_VSCODE_TEST: 'true' - }, - mocha: { - ui: 'bdd', +let extensionDevelopmentPath = ''; - reporter: path.join(dirname, '.vscode-ci-test-reporter.js'), - reporterOption: { - jsonReporterOption: { - output: path.join(dirname, 'test-results', `${label}.json`), - }, - }, - timeout: 60_000, - }, - }; - } else { - return { - platform: vsCodePlatform, - version: vsCodeVersion, - env: { - MOCHA_VSCODE_TEST: 'true' - }, - mocha: { - ui: 'bdd', - timeout: 60_000, +const testMode = process.env.TEST_MODE ?? 'normal'; + +if (testMode === 'vsix') { + const tempDir = process.env.TEST_TEMP ?? path.join(dirname, 'tmp') + extensionDevelopmentPath = path.resolve(path.join(tempDir, 'vsix', 'extension')); +} + +function createCommonOptions(label) { + /**@type {import('@vscode/test-cli').TestConfiguration} */ + const options = { + platform: vsCodePlatform, + version: vsCodeVersion, + env: { + MOCHA_VSCODE_TEST: 'true', + }, + mocha: { + ui: 'bdd', + timeout: 60_000, + }, + }; + + if (process.env.GITHUB_ACTIONS) { + options.mocha.reporter = path.join(dirname, '.vscode-ci-test-reporter.js'); + options.mocha.reporterOption = { + jsonReporterOption: { + output: path.join(dirname, 'test-results', `${testMode}-${label}.json`), }, }; + options.env.MOCHA_COLORS = 'true'; + } + + if (extensionDevelopmentPath) { + options.extensionDevelopmentPath = extensionDevelopmentPath; } -}; + + + return options; +} const config = [ { diff --git a/package-lock.json b/package-lock.json index 43f1334..c994cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@types/chai": "^4.3.17", "@types/eslint__js": "^8.42.3", "@types/estree": "^1.0.5", + "@types/extract-zip": "^2.0.1", "@types/glob": "^8.1.0", "@types/mocha": "^10.0.8", "@types/node": "22.x", @@ -36,6 +37,7 @@ "acorn-loose": "^8.4.0", "ansi-colors": "^4.1.3", "chai": "^4.4.1", + "cross-env": "^7.0.3", "data-uri-to-buffer": "^6.0.2", "enhanced-resolve": "^5.17.1", "error-stack-parser": "^2.1.4", @@ -44,6 +46,7 @@ "eslint-plugin-license-header": "^0.6.1", "eslint-plugin-prettier": "^5.2.1", "eslint-visitor-keys": "^4.1.0", + "extract-zip": "^2.0.1", "glob": "^11.0.0", "minimatch": "^10.0.1", "mocha": "^10.7.3", @@ -1600,6 +1603,16 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-Rvy84OCUrbGquSMH2a2ifbHB3CEu95LguiihLf0gc4uFaZ7psB6Khq+s8a7rsPGztSlxihu1om7+ZVxBh8iJcg==", + "deprecated": "This is a stub types definition. extract-zip provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "extract-zip": "*" + } + }, "node_modules/@types/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", @@ -1694,6 +1707,16 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", @@ -2199,6 +2222,15 @@ "node": ">=4" } }, + "node_modules/@vscode/vsce/node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3" + } + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -2960,6 +2992,24 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3270,7 +3320,6 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "optional": true, "dependencies": { "once": "^1.4.0" } @@ -3685,6 +3734,26 @@ "node": ">=6" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3926,6 +3995,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-tsconfig": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", @@ -6602,7 +6686,6 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, - "optional": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8519,15 +8602,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 0a254e0..f415e4a 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "publish:vsce:prerelease": "npx @vscode/vsce publish --pre-release", "publish:ovsx:release": "npx ovsx publish", "publish:ovsx:prerelease": "npx ovsx publish --pre-release", + "package:test": "npm run compile && tsx ./scripts/prerelease.mts && npx @vscode/vsce package && tsx ./scripts/extractVsix.mts", "package:release": "npm run compile && tsx ./scripts/prerelease.mts && npx @vscode/vsce package", "package:prerelease": "npm run compile && tsx ./scripts/prerelease.mts --pre-release && npx @vscode/vsce package --pre-release", "vscode:prepublish": "npm run compile", @@ -126,6 +127,7 @@ "watch:esbuild": "npm run clean && node .esbuild.js --watch", "watch": "npm run clean && tsc --watch", "test": "tsc && vscode-test", + "test:vsix": "tsc && cross-env TEST_MODE=vsix vscode-test", "prettier": "prettier --write src", "lint": "eslint .", "fix": "eslint . --fix" @@ -136,6 +138,7 @@ "@types/chai": "^4.3.17", "@types/eslint__js": "^8.42.3", "@types/estree": "^1.0.5", + "@types/extract-zip": "^2.0.1", "@types/glob": "^8.1.0", "@types/mocha": "^10.0.8", "@types/node": "22.x", @@ -155,6 +158,7 @@ "acorn-loose": "^8.4.0", "ansi-colors": "^4.1.3", "chai": "^4.4.1", + "cross-env": "^7.0.3", "data-uri-to-buffer": "^6.0.2", "enhanced-resolve": "^5.17.1", "error-stack-parser": "^2.1.4", @@ -163,6 +167,7 @@ "eslint-plugin-license-header": "^0.6.1", "eslint-plugin-prettier": "^5.2.1", "eslint-visitor-keys": "^4.1.0", + "extract-zip": "^2.0.1", "glob": "^11.0.0", "minimatch": "^10.0.1", "mocha": "^10.7.3", @@ -185,7 +190,7 @@ "esbuild": "^0.24.0" }, "mocha-vscode": { - "version": "1.1.0-preview+FFFFFFF", - "date": "2024-04-02T14:30:00Z" + "version": "v1.2.3+d27e65f", + "date": "2024-10-20T15:38:24.261Z" } } diff --git a/scripts/extractVsix.mts b/scripts/extractVsix.mts new file mode 100644 index 0000000..f3c5f32 --- /dev/null +++ b/scripts/extractVsix.mts @@ -0,0 +1,34 @@ +/** + * Copyright (C) Daniel Kuschny (Danielku15) and contributors. + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +import extract from 'extract-zip'; +import * as fs from 'fs'; +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +const dirname = fileURLToPath(new URL('.', import.meta.url)); + +const vsix = fs + .readdirSync(path.join(dirname, '..'), { + withFileTypes: true, + }) + .filter((f) => f.name.startsWith('mocha-vscode') && f.name.endsWith('.vsix')); + +if (vsix.length > 1) { + console.error('Multiple VSIX files found, cannot decide which is the one for testing'); + process.exit(1); +} + +const tempDir = process.env.TEST_TEMP ?? path.join(dirname, '..', 'tmp') +const extensionDir = path.join(tempDir, 'vsix'); +await fs.promises.rm(extensionDir, { recursive: true, force: true }); +await fs.promises.mkdir(extensionDir, { recursive: true }); + +await extract(path.join(vsix[0].parentPath, vsix[0].name), { + dir: extensionDir, +}); diff --git a/src/esbuild.ts b/src/esbuild.ts index 447b3f6..5b86518 100644 --- a/src/esbuild.ts +++ b/src/esbuild.ts @@ -184,7 +184,20 @@ export async function initESBuild( }); const targetPath = path.join(context.extensionPath, 'node_modules', platformPackageName); + try { + if (fs.existsSync(targetPath)) { + logChannel.debug(`Deleting existing files at ${targetPath}`); + await fs.promises.rm(targetPath, { recursive: true, force: true }); + } + } catch (e) { + logChannel.debug(`Error deleting files at ${targetPath}`, e); + } + logChannel.debug(`Moving files to ${targetPath}`); - await fs.promises.rm(targetPath, { recursive: true, force: true }); - await fs.promises.rename(path.join(temp, 'package'), targetPath); + try { + //await fs.promises.mkdir(path.dirname(targetPath)); + await fs.promises.rename(path.join(temp, 'package'), targetPath); + } catch (e) { + logChannel.debug(`Error moving files to ${targetPath}`, e); + } }