From 8abea48b5c1cf76e08b6fd071fb19bf25bb35a6a Mon Sep 17 00:00:00 2001 From: memeplex Date: Tue, 21 Dec 2021 17:08:09 -0300 Subject: [PATCH] Improve testing experience (#881) * Improve testing experience * Support vscode-jest for unit tests --- .gitignore | 1 + .vscode/launch.json | 38 +++++++++++++++---- .vscode/settings.json | 6 +-- .yarnrc | 1 + packages/foam-vscode/.test-workspace/.keep | 0 packages/foam-vscode/babel.config.js | 7 ---- packages/foam-vscode/jest.config.js | 13 ++++--- packages/foam-vscode/package.json | 4 +- packages/foam-vscode/src/test/run-tests.ts | 12 +----- packages/foam-vscode/src/test/suite-unit.ts | 18 ++++----- packages/foam-vscode/src/test/suite.ts | 33 +++++++++------- ...e-environment.js => vscode-environment.js} | 14 +++---- .../foam-vscode/src/test/test-utils-vscode.ts | 2 +- yarn.lock | 7 +--- 14 files changed, 82 insertions(+), 74 deletions(-) create mode 100644 .yarnrc create mode 100644 packages/foam-vscode/.test-workspace/.keep delete mode 100644 packages/foam-vscode/babel.config.js rename packages/foam-vscode/src/test/support/{extended-vscode-environment.js => vscode-environment.js} (67%) diff --git a/.gitignore b/.gitignore index 2ca25d415..b531b3f9e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ dist docs/_site docs/.sass-cache docs/.jekyll-metadata +.test-workspace diff --git a/.vscode/launch.json b/.vscode/launch.json index 9438aa39d..b5fb63c9f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,15 +6,20 @@ "version": "0.2.0", "configurations": [ { - "type": "node", "name": "Debug Jest Tests", + "type": "extensionHost", "request": "launch", - "runtimeArgs": ["workspace", "foam-vscode", "run", "test"], // ${yarnWorkspaceName} is what we're missing - "args": ["--runInBand"], - "runtimeExecutable": "yarn", - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "disableOptimisticBPs": true + "args": [ + "${workspaceFolder}/packages/foam-vscode/.test-workspace", + "--disable-extensions", + "--disable-workspace-trust", + "--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode", + "--extensionTestsPath=${workspaceFolder}/packages/foam-vscode/out/test/suite" + ], + "outFiles": [ + "${workspaceFolder}/packages/foam-vscode/out/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" }, { "name": "Run VSCode Extension", @@ -24,8 +29,25 @@ "args": [ "--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode" ], - "outFiles": ["${workspaceFolder}/packages/foam-vscode/out/**/*.js"], + "outFiles": [ + "${workspaceFolder}/packages/foam-vscode/out/**/*.js" + ], "preLaunchTask": "${defaultBuildTask}" + }, + { + "type": "node", + "name": "vscode-jest-tests", + "request": "launch", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true, + "cwd": "${workspaceFolder}/packages/foam-vscode", + "runtimeExecutable": "yarn", + "args": [ + "jest", + "--runInBand", + "--watchAll=false" + ] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 74f1bd4d4..93cecc394 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,9 +24,9 @@ "prettier.requireConfig": true, "editor.formatOnSave": true, "editor.tabSize": 2, - "jest.debugCodeLens.showWhenTestStateIn": ["fail", "unknown", "pass"], + "jest.autoRun": "off", + "jest.rootPath": "packages/foam-vscode", + "jest.jestCommandLine": "yarn jest" "gitdoc.enabled": false, - "jest.autoEnable": false, - "jest.runAllTestsFirst": false, "search.mode": "reuseEditor" } diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 000000000..4f14322dc --- /dev/null +++ b/.yarnrc @@ -0,0 +1 @@ +--ignore-engines true diff --git a/packages/foam-vscode/.test-workspace/.keep b/packages/foam-vscode/.test-workspace/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/foam-vscode/babel.config.js b/packages/foam-vscode/babel.config.js deleted file mode 100644 index 9a22839e7..000000000 --- a/packages/foam-vscode/babel.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - presets: [ - ["@babel/preset-env", { targets: { node: "current" } }], - "@babel/preset-typescript" - ], - plugins: [["@babel/plugin-transform-runtime", { helpers: false }]] -}; diff --git a/packages/foam-vscode/jest.config.js b/packages/foam-vscode/jest.config.js index ad42db60f..7febf5896 100644 --- a/packages/foam-vscode/jest.config.js +++ b/packages/foam-vscode/jest.config.js @@ -82,7 +82,7 @@ module.exports = { // moduleNameMapper: {}, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], + modulePathIgnorePatterns: ['.vscode-test'], // Activates notifications for test results // notify: false, @@ -91,7 +91,7 @@ module.exports = { // notifyMode: "failure-change", // A preset that is used as a base for Jest's configuration - // preset: undefined, + preset: 'ts-jest', // Run tests from one or more projects // projects: undefined, @@ -126,13 +126,13 @@ module.exports = { // setupFiles: [], // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], + setupFilesAfterEnv: ['jest-extended'], // 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" + testEnvironment: 'node', // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, @@ -152,7 +152,10 @@ module.exports = { // ], // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], + // This is overridden in every runCLI invocation but it's here as the default + // for vscode-jest. We only want unit tests in the test explorer (sidebar), + // since spec tests require the entire extension host to be launched before. + testRegex: ['\\.test\\.ts$'], // This option allows the use of a custom results processor // testResultsProcessor: undefined, diff --git a/packages/foam-vscode/package.json b/packages/foam-vscode/package.json index bf396f3b2..04a5751ec 100644 --- a/packages/foam-vscode/package.json +++ b/packages/foam-vscode/package.json @@ -356,7 +356,9 @@ "build": "tsc -p ./", "pretest": "yarn build", "test": "node ./out/test/run-tests.js", + "pretest:unit": "yarn build", "test:unit": "node ./out/test/run-tests.js --unit", + "pretest:e2e": "yarn build", "test:e2e": "node ./out/test/run-tests.js --e2e", "lint": "tsdx lint src", "clean": "rimraf out", @@ -388,12 +390,10 @@ "@types/vscode": "^1.47.1", "@typescript-eslint/eslint-plugin": "^2.30.0", "@typescript-eslint/parser": "^2.30.0", - "babel-jest": "^26.2.2", "eslint": "^6.8.0", "eslint-plugin-import": "^2.24.2", "husky": "^4.2.5", "jest": "^26.2.2", - "jest-environment-vscode": "^1.0.0", "jest-extended": "^0.11.5", "markdown-it": "^12.0.4", "rimraf": "^3.0.2", diff --git a/packages/foam-vscode/src/test/run-tests.ts b/packages/foam-vscode/src/test/run-tests.ts index 0830040e0..2d6bdd1f1 100644 --- a/packages/foam-vscode/src/test/run-tests.ts +++ b/packages/foam-vscode/src/test/run-tests.ts @@ -1,5 +1,3 @@ -import fs from 'fs'; -import os from 'os'; import path from 'path'; import { runTests } from 'vscode-test'; import { runUnit } from './suite-unit'; @@ -35,23 +33,17 @@ async function main() { // The path to the extension test script // Passed to --extensionTestsPath const extensionTestsPath = path.join(__dirname, 'suite'); - const tmpWorkspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'foam-')); // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [ - tmpWorkspaceDir, + path.join(extensionDevelopmentPath, '.test-workspace'), '--disable-extensions', '--disable-workspace-trust', ], - // Running the tests with vscode 1.53.0 is causing issues in the output/error stream management, - // which is causing a stack overflow, possibly due to a recursive callback. - // Also see https://github.com/foambubble/foam/pull/479#issuecomment-774167127 - // Forcing the version to 1.52.0 solves the problem. - // TODO: to review, further investigate, and roll back this workaround. - version: '1.52.0', + version: '1.60.0', }); } catch (err) { console.log('Error occurred while running Foam e2e tests:', err); diff --git a/packages/foam-vscode/src/test/suite-unit.ts b/packages/foam-vscode/src/test/suite-unit.ts index 831d5a680..bac75da8e 100644 --- a/packages/foam-vscode/src/test/suite-unit.ts +++ b/packages/foam-vscode/src/test/suite-unit.ts @@ -8,32 +8,28 @@ * they will make direct use of the vscode API to be invoked as commands, create editors, * and so on.. */ + +/* eslint-disable import/first */ + +// Set before imports, see https://github.com/facebook/jest/issues/12162 +process.env.FORCE_COLOR = '1'; +process.env.NODE_ENV = 'test'; + import path from 'path'; import { runCLI } from '@jest/core'; const rootDir = path.join(__dirname, '..', '..'); export function runUnit(): Promise { - process.env.FORCE_COLOR = '1'; - process.env.NODE_ENV = 'test'; - process.env.BABEL_ENV = 'test'; - return new Promise(async (resolve, reject) => { try { const { results } = await runCLI( { rootDir, roots: ['/src'], - transform: JSON.stringify({ '^.+\\.ts$': 'ts-jest' }), runInBand: true, testRegex: '\\.(test)\\.ts$', setupFiles: ['/src/test/support/jest-setup.ts'], - setupFilesAfterEnv: ['jest-extended'], - globals: JSON.stringify({ - 'ts-jest': { - tsconfig: path.join(rootDir, 'tsconfig.json'), - }, - }), testTimeout: 20000, verbose: false, silent: false, diff --git a/packages/foam-vscode/src/test/suite.ts b/packages/foam-vscode/src/test/suite.ts index bf4de1afe..f1cf81371 100644 --- a/packages/foam-vscode/src/test/suite.ts +++ b/packages/foam-vscode/src/test/suite.ts @@ -9,42 +9,46 @@ * and so on.. */ +/* eslint-disable import/first */ + +// Set before imports, see https://github.com/facebook/jest/issues/12162 +process.env.FORCE_COLOR = '1'; +process.env.NODE_ENV = 'test'; + import path from 'path'; import { runCLI } from '@jest/core'; +import { cleanWorkspace } from './test-utils-vscode'; -const rootDir = path.resolve(__dirname, '../..'); +const rootDir = path.join(__dirname, '../..'); export function run(): Promise { const errWrite = process.stderr.write; + + let remaining = ''; process.stderr.write = (buffer: string) => { - console.log(buffer); + const lines = (remaining + buffer).split('\n'); + remaining = lines.pop() as string; + // Trim long lines because some uninformative code dumps will flood the + // console or, worse, be suppressed altogether because of their size. + lines.forEach(l => console.log(l.substr(0, 300))); return true; }; + // process.on('unhandledRejection', err => { // throw err; // }); - process.env.FORCE_COLOR = '1'; - process.env.NODE_ENV = 'test'; - process.env.BABEL_ENV = 'test'; return new Promise(async (resolve, reject) => { + await cleanWorkspace(); try { const { results } = await runCLI( { rootDir, roots: ['/src'], - transform: JSON.stringify({ '^.+\\.ts$': 'ts-jest' }), runInBand: true, testRegex: '\\.(test|spec)\\.ts$', - testEnvironment: - '/src/test/support/extended-vscode-environment.js', + testEnvironment: '/src/test/support/vscode-environment.js', setupFiles: ['/src/test/support/jest-setup.ts'], - setupFilesAfterEnv: ['jest-extended'], - globals: JSON.stringify({ - 'ts-jest': { - tsconfig: path.resolve(rootDir, './tsconfig.json'), - }, - }), testTimeout: 30000, useStderr: true, verbose: true, @@ -71,6 +75,7 @@ export function run(): Promise { return reject(error); } finally { process.stderr.write = errWrite.bind(process.stderr); + await cleanWorkspace(); } }); } diff --git a/packages/foam-vscode/src/test/support/extended-vscode-environment.js b/packages/foam-vscode/src/test/support/vscode-environment.js similarity index 67% rename from packages/foam-vscode/src/test/support/extended-vscode-environment.js rename to packages/foam-vscode/src/test/support/vscode-environment.js index 5528575e7..5cb4e2782 100644 --- a/packages/foam-vscode/src/test/support/extended-vscode-environment.js +++ b/packages/foam-vscode/src/test/support/vscode-environment.js @@ -1,27 +1,27 @@ -// Based on https://github.com/svsool/vscode-memo/blob/master/src/test/env/ExtendedVscodeEnvironment.js -const VscodeEnvironment = require('jest-environment-vscode'); +const NodeEnvironment = require('jest-environment-node'); const vscode = require('vscode'); -const initialVscode = vscode; -class ExtendedVscodeEnvironment extends VscodeEnvironment { +class VscodeEnvironment extends NodeEnvironment { async setup() { await super.setup(); + this.global.vscode = vscode; + // Expose RegExp otherwise document.getWordRangeAtPosition won't work as supposed. // Implementation of getWordRangeAtPosition uses "instanceof RegExp" which returns false // due to Jest running tests in the different vm context. // See https://github.com/nodejs/node-v0.x-archive/issues/1277. // And also https://github.com/microsoft/vscode-test/issues/37#issuecomment-700167820 this.global.RegExp = RegExp; - this.global.vscode = vscode; vscode.workspace .getConfiguration() .update('foam.edit.linkReferenceDefinitions', 'off'); } + async teardown() { - this.global.vscode = initialVscode; + this.global.vscode = {}; await super.teardown(); } } -module.exports = ExtendedVscodeEnvironment; +module.exports = VscodeEnvironment; diff --git a/packages/foam-vscode/src/test/test-utils-vscode.ts b/packages/foam-vscode/src/test/test-utils-vscode.ts index 711a11a3b..509766195 100644 --- a/packages/foam-vscode/src/test/test-utils-vscode.ts +++ b/packages/foam-vscode/src/test/test-utils-vscode.ts @@ -13,7 +13,7 @@ import { randomString, wait } from './test-utils'; Logger.setLevel('error'); export const cleanWorkspace = async () => { - const files = await vscode.workspace.findFiles('**', '.vscode'); + const files = await vscode.workspace.findFiles('**', '{.vscode,.keep}'); await Promise.all(files.map(f => vscode.workspace.fs.delete(f))); }; diff --git a/yarn.lock b/yarn.lock index 695d9a549..67111e97d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2954,7 +2954,7 @@ babel-jest@^24.9.0: chalk "^2.4.2" slash "^2.0.0" -babel-jest@^26.2.2, babel-jest@^26.6.3: +babel-jest@^26.6.3: version "26.6.3" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== @@ -6515,11 +6515,6 @@ jest-environment-node@^26.6.2: jest-mock "^26.6.2" jest-util "^26.6.2" -jest-environment-vscode@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-vscode/-/jest-environment-vscode-1.0.0.tgz#96367fe8531047e64359e0682deafc973bfaea91" - integrity sha512-VKlj5j5pNurFEwWPaDiX1kBgmhWqcJTAZsvEX1x5lh0/+5myjk+qipEs/dPJVRbBPb3XFxiR48XzGn+wOU7SSQ== - jest-extended@^0.11.5: version "0.11.5" resolved "https://registry.yarnpkg.com/jest-extended/-/jest-extended-0.11.5.tgz#f063b3f1eaadad8d7c13a01f0dfe0f538d498ccf"