diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000000..5339fdd0c3 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,11 @@ +{ + "color": true, + "enable-source-maps": true, + "extensions": [ + ".js", + ".jsx" + ], + "require": "source-map-support/register", + "timeout": 10000, + "spec": "out/test/**/*.test.js" +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..c1b8d2d443 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,127 @@ +{ + "version": "0.2.0", + "configurations": [ + // NOTE: These are not in the code-workspace file because StartDebugging cannot current resolve configs stored there so they have to be here for the Mocha Test Explorer feature. + // Ref: https://github.com/microsoft/vscode/issues/150663 + { + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "env": { + "__TEST_WORKSPACE_PATH": "${workspaceFolder}/examples", + }, + "sourceMaps": true, + // This speeds up source map detection and makes smartStep work correctly + "outFiles": [ + "${workspaceFolder}/out/**/*.js", + "!**/node_modules/**", + "!**/.vscode-test/**" + ], + "skipFiles": [ + "/**", + "**/node_modules/**", + "**/.vscode-test/**" + ], + "presentation": { + "hidden": false, + "group": "test", + "order": 2 + } + }, + { + // Runs the extension in an empty temp profile that is automatically cleaned up after use + // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220 + "name": "Launch Extension - Temp Profile", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--profile-temp", + "--extensionDevelopmentPath=${workspaceFolder}", + "${workspaceFolder}/examples" + ], + "sourceMaps": true, + // This speeds up source map detection and makes smartStep work correctly + "outFiles": [ + "${workspaceFolder}/out/**/*.js", + "!**/node_modules/**", + "!**/.vscode-test/**" + ], + "skipFiles": [ + "/**", + "**/node_modules/**", + "**/.vscode-test/**" + ], + "presentation": { + "hidden": false, + "group": "test", + "order": 2 + } + }, + { + // Runs the extension in an isolated but persistent profile separate from the user settings + // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220 + "name": "Launch Extension - Isolated Profile", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--profile=debug", + "--extensionDevelopmentPath=${workspaceFolder}", + "${workspaceFolder}/examples" + ], + "sourceMaps": true, + // This speeds up source map detection and makes smartStep work correctly + "outFiles": [ + "${workspaceFolder}/out/**/*.js", + "!**/node_modules/**", + "!**/.vscode-test/**" + ], + "skipFiles": [ + "/**", + "**/node_modules/**", + "**/.vscode-test/**" + ], + "presentation": { + "hidden": false, + "group": "test", + "order": 2 + } + }, + { + "name": "Test Extension", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/out/test/runTests.js", + "cascadeTerminateToConfigurations": [ + "ExtensionTests", + ], + // This speeds up source map detection and makes smartStep work correctly + "outFiles": [ + "${workspaceFolder}/out/**/*.js", + "!**/node_modules/**", + "!**/.vscode-test/**" + ], + "skipFiles": [ + "/**", + "**/node_modules/**", + "**/.vscode-test/**" + ], + "attachSimplePort": 59229, // THe default is 9229 but we want to avoid conflicts because we will have two vscode instances running. + "env": { + "__TEST_DEBUG_INSPECT_PORT": "59229" // Needs to match attachSimplePort + }, + "presentation": { + "hidden": false, + }, + "internalConsoleOptions": "neverOpen", + "console": "integratedTerminal", + "autoAttachChildProcesses": false, + "preLaunchTask": "test-watch" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..f5ae0aa296 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,30 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "test-watch", + "icon": { + "color": "terminal.ansiCyan", + "id": "sync" + }, + "type": "npm", + "script": "build-test-watch", + "group": "test", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "dependsOn": "build-watch" // We need to also build main.js extension for testing or it leads to sourcemap errors + }, + { + "label": "build-watch", + "icon": { + "color": "terminal.ansiCyan", + "id": "sync" + }, + "type": "npm", + "script": "build-watch", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + } + ] +} diff --git a/extension-dev.code-workspace b/extension-dev.code-workspace index 2a552513f0..899528d116 100644 --- a/extension-dev.code-workspace +++ b/extension-dev.code-workspace @@ -17,7 +17,8 @@ "josefpihrt-vscode.roslynator", "ms-azure-devops.azure-pipelines", "ms-dotnettools.csharp", - "ms-vscode.powershell" + "ms-vscode.powershell", + "hbenl.vscode-mocha-test-adapter" ] }, "settings": { @@ -28,9 +29,7 @@ "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.associations": { - // Use JSONC instead of JSON because (1) that's how VS Code interprets - // snippet files, and (2) it enables better source documentation. - "**/snippets/*.json": "jsonc", + "**/snippets/*.json": "jsonc", // Use JSONC instead of JSON because that's how VS Code interprets snippet files, and it enables better source documentation. "**/.vsts-ci/**/*.yml": "azure-pipelines", }, // Ignore the Markdown rule: @@ -45,18 +44,26 @@ "powershell.codeFormatting.whitespaceBeforeOpenBrace": false, "powershell.codeFormatting.whitespaceBetweenParameters": true, "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline", - // Lock the TypeScript SDK path to the version we use - "typescript.tsdk": "Client/node_modules/typescript/lib", - // Code actions like "organize imports" ignore ESLint, so we need this here - "typescript.format.semicolons": "insert", - // Enable ESLint as defaut formatter so quick fixes can be applied directly - "eslint.format.enable": true, + "typescript.tsdk": "Client/node_modules/typescript/lib", // Lock the TypeScript SDK path to the version we use + "typescript.format.semicolons": "insert", // Code actions like "organize imports" ignore ESLint, so we need this here + "eslint.format.enable": true, // Enable ESLint as defaut formatter so quick fixes can be applied directly "[typescript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint", "editor.formatOnPaste": true, "editor.formatOnSave": true, "editor.formatOnSaveMode": "modificationsIfAvailable" - } + }, + "mochaExplorer.configFile": ".mocharc.json", + "mochaExplorer.launcherScript": "out/test/runTests", + "mochaExplorer.autoload": false, // The test instance pops up every time discovery or run is done, this could be annoying on startup. + "mochaExplorer.debuggerPort": 59229, // Matches the launch config, we dont want to use the default port as we are launching a duplicate instance of vscode and it might conflict. + "mochaExplorer.ipcRole": "server", + "mochaExplorer.ipcTimeout": 10000, + "testExplorer.useNativeTesting": true, + "mochaExplorer.env": { + "VSCODE_VERSION": "insiders", + "ELECTRON_RUN_AS_NODE": null + }, }, "tasks": { "version": "2.0.0", @@ -160,39 +167,7 @@ }, "command": "Invoke-Build ${input:serverBuildCommand}", "group": "build" - }, - // HACK: Can't use task type npm in workspace config: https://github.com/microsoft/vscode/issues/96086 - { - "label": "test-watch", - "icon": { - "color": "terminal.ansiCyan", - "id": "sync" - }, - "type": "shell", - "options": { - "cwd": "${workspaceFolder:Client}" - }, - "command": "npm run-script build-test-watch", - "group": "test", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "dependsOn": "build-watch" // We need to also build main.js extension for testing or it leads to sourcemap errors - }, - { - "label": "build-watch", - "icon": { - "color": "terminal.ansiCyan", - "id": "sync" - }, - "type": "shell", - "options": { - "cwd": "${workspaceFolder:Client}" - }, - "command": "npm run-script build-watch", - "group": "build", - "problemMatcher": "$esbuild-watch", - "isBackground": true, - }, + } ], "inputs": [ { @@ -228,52 +203,7 @@ }, "launch": { "version": "0.2.0", - "compounds": [ - { - "name": "Test Extension", - "configurations": [ - "ExtensionTests", - "ExtensionTestRunner", - ], - "stopAll": true, - "presentation": { - "group": "test", - "order": 1 - }, - // This is here so instead of under TestRunner so that the attach doesn't start until the compile is complete - "preLaunchTask": "test-watch" - } - ], "configurations": [ - { - "name": "Launch Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder:Client}" - ], - "env": { - "__TEST_WORKSPACE_PATH": "${workspaceFolder:Client}/examples", - }, - "sourceMaps": true, - // This speeds up source map detection and makes smartStep work correctly - "outFiles": [ - "${workspaceFolder:Client}/out/**/*.js", - "!**/node_modules/**", - "!**/.vscode-test/**" - ], - "skipFiles": [ - "/**", - "**/node_modules/**", - "**/.vscode-test/**" - ], - "presentation": { - "hidden": false, - "group": "test", - "order": 2 - } - }, { // https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md "name": "Attach to Editor Services", @@ -292,123 +222,6 @@ "group": "test", "order": 3 } - }, - { - // Runs the extension in an empty temp profile that is automatically cleaned up after use - // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220 - "name": "Launch Extension - Temp Profile", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--profile-temp", - "--extensionDevelopmentPath=${workspaceFolder:Client}", - "${workspaceFolder:Client}/examples" - ], - "sourceMaps": true, - // This speeds up source map detection and makes smartStep work correctly - "outFiles": [ - "${workspaceFolder:Client}/out/**/*.js", - "!**/node_modules/**", - "!**/.vscode-test/**" - ], - "skipFiles": [ - "/**", - "**/node_modules/**", - "**/.vscode-test/**" - ], - "presentation": { - "hidden": false, - "group": "test", - "order": 2 - } - }, - { - // Runs the extension in an isolated but persistent profile separate from the user settings - // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220 - "name": "Launch Extension - Isolated Profile", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--profile=debug", - "--extensionDevelopmentPath=${workspaceFolder:Client}", - "${workspaceFolder:Client}/examples" - ], - "sourceMaps": true, - // This speeds up source map detection and makes smartStep work correctly - "outFiles": [ - "${workspaceFolder:Client}/out/**/*.js", - "!**/node_modules/**", - "!**/.vscode-test/**" - ], - "skipFiles": [ - "/**", - "**/node_modules/**", - "**/.vscode-test/**" - ], - "presentation": { - "hidden": false, - "group": "test", - "order": 2 - } - }, - { - "name": "ExtensionTestRunner", - "type": "node", - "request": "launch", - "program": "${workspaceFolder:Client}/out/test/runTests.js", - "cascadeTerminateToConfigurations": [ - "ExtensionTests", - ], - // This speeds up source map detection and makes smartStep work correctly - "outFiles": [ - "${workspaceFolder:Client}/out/**/*.js", - "!**/node_modules/**", - "!**/.vscode-test/**" - ], - "skipFiles": [ - "/**", - "**/node_modules/**", - "**/.vscode-test/**" - ], - "args": [ - "59229" // Wait on this port for the separate debugger task to attach - ], - "presentation": { - "hidden": true, - }, - "internalConsoleOptions": "neverOpen", - "console": "integratedTerminal", - "autoAttachChildProcesses": false // Doesnt work with the extension host for whatever reason, hence the separate attach. - }, - { - "name": "ExtensionTests", - "type": "node", - "request": "attach", - "port": 59229, - "autoAttachChildProcesses": true, - "outputCapture": "console", - "continueOnAttach": true, - // Sometimes we may need to install extensions or reload the window which requires reconnecting - "restart": { - "delay": 1000, - "maxAttempts": 3 - }, - "presentation": { - "hidden": true, - }, - // This speeds up source map detection and makes smartStep work correctly - "outFiles": [ - "${workspaceFolder:Client}/out/**/*.js", - "!**/node_modules/**", - "!**/.vscode-test/**" - ], - "skipFiles": [ - "/**", - "**/node_modules/**", - "**/.vscode-test/**" - ], } ] } diff --git a/package-lock.json b/package-lock.json index 2a56cd8f95..6644f0df47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "powershell", - "version": "2023.3.3", + "version": "2023.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "powershell", - "version": "2023.3.3", + "version": "2023.4.0", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@vscode/extension-telemetry": "0.6.2", @@ -17,7 +17,6 @@ "vscode-languageserver-protocol": "3.17.3" }, "devDependencies": { - "@types/glob": "8.0.1", "@types/mocha": "10.0.1", "@types/mock-fs": "4.13.1", "@types/node": "16.18.12", @@ -36,12 +35,14 @@ "esbuild": "0.17.16", "eslint": "8.38.0", "eslint-plugin-header": "3.1.1", - "glob": "8.1.0", + "glob": "9.3.4", "mocha": "10.2.0", + "mocha-explorer-launcher-scripts": "0.4.0", "mocha-multi-reporters": "1.5.1", "mock-fs": "5.2.0", "rewire": "6.0.0", "sinon": "15.0.3", + "source-map-support": "0.5.21", "typescript": "5.0.4" }, "engines": { @@ -642,28 +643,12 @@ "node": ">= 6" } }, - "node_modules/@types/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==", - "dev": true, - "dependencies": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "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/mocha": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", @@ -1274,6 +1259,12 @@ "node": "*" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2281,19 +2272,18 @@ "optional": true }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.4.tgz", + "integrity": "sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2321,15 +2311,27 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/globals": { @@ -3044,6 +3046,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -3091,6 +3102,15 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha-explorer-launcher-scripts": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mocha-explorer-launcher-scripts/-/mocha-explorer-launcher-scripts-0.4.0.tgz", + "integrity": "sha512-cik/K4r+7WlhpzRmaecA5MWBPOgFRqCdZ95Tvbc5HBohj1I8vgRvBSfAIKdLVJes0PooFlrOzn7Alh4lEELSjg==", + "dev": true, + "dependencies": { + "vscode-test-adapter-remoting-util": "^0.13.0" + } + }, "node_modules/mocha-multi-reporters": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz", @@ -3480,6 +3500,31 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", + "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", + "dev": true, + "dependencies": { + "lru-cache": "^9.0.0", + "minipass": "^5.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.2.tgz", + "integrity": "sha512-7zYMKApzQ9qQE13xQUzbXVY3p2C5lh+9V+bs8M9fRf1TF59id+8jkljRWtIPfBfNP4yQAol5cqh/e8clxatdXw==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -4335,6 +4380,37 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4474,6 +4550,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -4703,6 +4785,32 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "node_modules/vscode-test-adapter-api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/vscode-test-adapter-api/-/vscode-test-adapter-api-1.9.0.tgz", + "integrity": "sha512-lltjehUP0J9H3R/HBctjlqeUCwn2t9Lbhj2Y500ib+j5Y4H3hw+hVTzuSsfw16LtxY37knlU39QIlasa7svzOQ==", + "dev": true, + "engines": { + "vscode": "^1.23.0" + } + }, + "node_modules/vscode-test-adapter-remoting-util": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vscode-test-adapter-remoting-util/-/vscode-test-adapter-remoting-util-0.13.0.tgz", + "integrity": "sha512-7yI+A+v4K24j+X/pJLgIlAGCIY1tOs9B/lBpPXMvukfPSJibMGts5t2BNb2Kh1wLe2tJBOADs4pu5oWnXKPvzQ==", + "dev": true, + "dependencies": { + "split": "^1.0.1", + "tslib": "^2.0.0", + "vscode-test-adapter-api": "^1.9.0" + } + }, + "node_modules/vscode-test-adapter-remoting-util/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -5261,28 +5369,12 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, - "@types/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==", - "dev": true, - "requires": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@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/mocha": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", @@ -5713,6 +5805,12 @@ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -6469,16 +6567,15 @@ "optional": true }, "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.4.tgz", + "integrity": "sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "dependencies": { "brace-expansion": { @@ -6491,13 +6588,19 @@ } }, "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } + }, + "minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true } } }, @@ -7046,6 +7149,12 @@ "dev": true, "optional": true }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -7156,6 +7265,15 @@ } } }, + "mocha-explorer-launcher-scripts": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mocha-explorer-launcher-scripts/-/mocha-explorer-launcher-scripts-0.4.0.tgz", + "integrity": "sha512-cik/K4r+7WlhpzRmaecA5MWBPOgFRqCdZ95Tvbc5HBohj1I8vgRvBSfAIKdLVJes0PooFlrOzn7Alh4lEELSjg==", + "dev": true, + "requires": { + "vscode-test-adapter-remoting-util": "^0.13.0" + } + }, "mocha-multi-reporters": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz", @@ -7378,6 +7496,24 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-scurry": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz", + "integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==", + "dev": true, + "requires": { + "lru-cache": "^9.0.0", + "minipass": "^5.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.2.tgz", + "integrity": "sha512-7zYMKApzQ9qQE13xQUzbXVY3p2C5lh+9V+bs8M9fRf1TF59id+8jkljRWtIPfBfNP4yQAol5cqh/e8clxatdXw==", + "dev": true + } + } + }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -7994,6 +8130,31 @@ } } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8110,6 +8271,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -8292,6 +8459,31 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "vscode-test-adapter-api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/vscode-test-adapter-api/-/vscode-test-adapter-api-1.9.0.tgz", + "integrity": "sha512-lltjehUP0J9H3R/HBctjlqeUCwn2t9Lbhj2Y500ib+j5Y4H3hw+hVTzuSsfw16LtxY37knlU39QIlasa7svzOQ==", + "dev": true + }, + "vscode-test-adapter-remoting-util": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vscode-test-adapter-remoting-util/-/vscode-test-adapter-remoting-util-0.13.0.tgz", + "integrity": "sha512-7yI+A+v4K24j+X/pJLgIlAGCIY1tOs9B/lBpPXMvukfPSJibMGts5t2BNb2Kh1wLe2tJBOADs4pu5oWnXKPvzQ==", + "dev": true, + "requires": { + "split": "^1.0.1", + "tslib": "^2.0.0", + "vscode-test-adapter-api": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + } + } + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 6d705e137e..3c05fded22 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "vscode-languageserver-protocol": "3.17.3" }, "devDependencies": { - "@types/glob": "8.0.1", "@types/mocha": "10.0.1", "@types/mock-fs": "4.13.1", "@types/node": "16.18.12", @@ -101,12 +100,14 @@ "esbuild": "0.17.16", "eslint": "8.38.0", "eslint-plugin-header": "3.1.1", - "glob": "8.1.0", + "glob": "9.3.4", "mocha": "10.2.0", + "mocha-explorer-launcher-scripts": "0.4.0", "mocha-multi-reporters": "1.5.1", "mock-fs": "5.2.0", "rewire": "6.0.0", "sinon": "15.0.3", + "source-map-support": "0.5.21", "typescript": "5.0.4" }, "extensionDependencies": [ diff --git a/test/features/CustomViews.test.ts b/test/features/CustomViews.test.ts index 88ccbc7b1a..00d9cd1382 100644 --- a/test/features/CustomViews.test.ts +++ b/test/features/CustomViews.test.ts @@ -30,6 +30,7 @@ function convertToVSCodeResourceScheme(filePath: string): string { } describe("CustomViews feature", function () { + this.slow(1500); const testCases: IHtmlContentViewTestCase[] = [ { name: "with no JavaScript or CSS", diff --git a/test/features/DebugSession.test.ts b/test/features/DebugSession.test.ts index d44b48a7eb..0695f57243 100644 --- a/test/features/DebugSession.test.ts +++ b/test/features/DebugSession.test.ts @@ -431,6 +431,7 @@ describe("DebugSessionFeature", () => { describe("DebugSessionFeature E2E", function slowTests() { this.slow(20000); // Will warn if test takes longer than 10s and show red if longer than 20s + this.timeout(30000); if (process.platform == "darwin") { this.timeout(60000); // The MacOS test runner is sloooow in Azure Devops diff --git a/test/features/ISECompatibility.test.ts b/test/features/ISECompatibility.test.ts index 792c3dd7bb..dbf3df1fd8 100644 --- a/test/features/ISECompatibility.test.ts +++ b/test/features/ISECompatibility.test.ts @@ -73,6 +73,7 @@ describe("ISE compatibility feature", function () { }); describe("Color theme interactions", function () { + this.slow(4000); beforeEach(enableISEMode); function assertISESettings(): void { diff --git a/test/features/UpdatePowerShell.test.ts b/test/features/UpdatePowerShell.test.ts index 2961699530..e4cf7220a8 100644 --- a/test/features/UpdatePowerShell.test.ts +++ b/test/features/UpdatePowerShell.test.ts @@ -107,6 +107,7 @@ describe("UpdatePowerShell feature", function () { }); describe("Which version it gets", function () { + this.slow(2000); it("Would update to LTS", async function() { process.env.POWERSHELL_UPDATECHECK = "LTS"; const version: IPowerShellVersionDetails = { diff --git a/test/index.ts b/test/index.ts deleted file mode 100644 index c179b9d65b..0000000000 --- a/test/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// NOTE: This code is borrowed under permission from: -// https://github.com/microsoft/vscode-extension-samples/tree/main/helloworld-test-sample/src/test - -import * as path from "path"; -import Mocha from "mocha"; -import glob from "glob"; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - color: !process.env.TF_BUILD, // colored output from test results - reporter: "mocha-multi-reporters", - timeout: 30000, // 30s because PowerShell startup is slow! - reporterOptions: { - // NOTE: The XML output by Mocha's xUnit reporter is actually in the - // JUnit style. I'm unsure how no one else has noticed this. - reporterEnabled: "spec, xunit", - xunitReporterOptions: { - output: path.join(__dirname, "..", "..", "test-results.xml"), - } - }, - }); - - return new Promise((c, e) => { - glob("**/**.test.js", { cwd: __dirname }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - for (const file of files) { - mocha.addFile(path.resolve(__dirname, file)); - } - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/test/runTests.ts b/test/runTests.ts index 9057ee2026..a4d7d360bc 100644 --- a/test/runTests.ts +++ b/test/runTests.ts @@ -9,7 +9,20 @@ import { ConsoleReporter, downloadAndUnzipVSCode, resolveCliArgsFromVSCodeExecut import { existsSync } from "fs"; import { spawnSync } from "child_process"; +/** This is the main test entrypoint that: + * - Prepares the test environment by downloading a testing instance of vscode and any additional extensions + * - Starts the test environment with runTestsInner injected into the extensionsTestsPath which will in turn start the Mocha test runner inside the environment. + * + * Tools like npm run test and vscode tasks should point to this script to begin the testing process. It is assumed you have built the extension prior to this step, it will error if it does not find the built extension or related test scaffolding. + * */ async function main(): Promise { + // Verify that the extension is built + const compiledExtensionPath = path.resolve(__dirname, "../main.js"); + if (!existsSync(compiledExtensionPath)) { + console.error("ERROR: The extension is not built yet. Please run a build first, using either the 'Run Build Task' in VSCode or ./build.ps1 in PowerShell."); + process.exit(1); + } + // Test for the presence of modules folder and error if not found const PSESPath = path.resolve(__dirname, "../../modules/PowerShellEditorServices.VSCode/bin/Microsoft.PowerShell.EditorServices.VSCode.dll"); if (!existsSync(PSESPath)) { @@ -21,10 +34,10 @@ async function main(): Promise { /** The folder containing the Extension Manifest package.json. Passed to `--extensionDevelopmentPath */ const extensionDevelopmentPath = path.resolve(__dirname, "../../"); - /** The path to the extension test script. Passed to --extensionTestsPath */ - const extensionTestsPath = path.resolve(__dirname, "./index"); + /** The path to the test script that will run inside the vscode instance. Passed to --extensionTestsPath */ + const extensionTestsPath = path.resolve(__dirname, "./runTestsInner"); - /** The starting workspace/folder to open in vscode. */ + /** The starting workspace/folder to open in vscode. By default this is a testing instance pointed to the Examples folder */ const workspacePath = process.env.__TEST_WORKSPACE_PATH ?? "test/TestEnvironment.code-workspace"; const workspaceToOpen = path.resolve(extensionDevelopmentPath, workspacePath); @@ -39,10 +52,31 @@ async function main(): Promise { workspaceToOpen ]; - // Allow to wait for extension test debugging - const port = process.argv[2]; - if (port) {launchArgs.push(`--inspect-brk-extensions=${port}`);} - + /** This is fed to runTestsInner so it knows the extension context to find config files */ + const extensionTestsEnv: Record = { + __TEST_EXTENSION_DEVELOPMENT_PATH: extensionDevelopmentPath + }; + + // This info is provided by the Mocha test explorer so it can communicate with the mocha running inside the vscode test instance. + // Adapted from: https://github.com/hbenl/mocha-explorer-launcher-scripts/blob/bd3ace403e729de1be31f46afddccc477f82a178/vscode-test/index.ts#L33-L37 + if (process.argv[2]) { + const mochaIPCInfo = JSON.parse(process.argv[2]); + extensionTestsEnv.MOCHA_WORKER_IPC_ROLE = mochaIPCInfo.role; + extensionTestsEnv.MOCHA_WORKER_IPC_HOST = mochaIPCInfo.host; + extensionTestsEnv.MOCHA_WORKER_IPC_PORT = String(mochaIPCInfo.port); + } + + /** This env var should be passed by launch configurations for debugging the extension tests. If specified, we should wait for it to connect because it means something explicitly asked for debugging **/ + const debugPort = process.env.__TEST_DEBUG_INSPECT_PORT; + console.log("DebugPort", debugPort); + if (debugPort !== undefined) { + console.log(`__TEST_DEBUG_INSPECT_PORT is set to ${debugPort}`); + launchArgs.push(`--inspect-brk-extensions=${debugPort}`); + } else { + // Make debugger optionally available. Mocha Test adapter will use this when debugging because it provides no indicator when it is debugging vs. just running + // FIXME: Because the mocha test explorer often doesn't attach until after the tests start and it provides no indicator of debug vs run, it may be flaky for debug until https://github.com/hbenl/vscode-mocha-test-adapter/pull/240 is merged. To workaround, start debugging sessions using "Test Extensions" launch config. We could use a timeout here but it would slow down everything including normal runs. + launchArgs.push("--inspect-extensions=59229"); + } // Download VS Code, unzip it and run the integration test await runTests({ @@ -52,13 +86,14 @@ async function main(): Promise { // This is necessary because the tests fail if more than once // instance of Code is running. version: vsCodeVersion, - extensionTestsEnv: { - __TEST_EXTENSIONDEVELOPMENTPATH: extensionDevelopmentPath - } + extensionTestsEnv: extensionTestsEnv }); } catch (err) { - console.error(`Failed to run tests: ${err}`); + console.error(`RunTests failed to run tests: ${err}`); process.exit(1); + } finally { + // Clean this up because runTests sets it on the current process, not the child one. + process.env.__TEST_DEBUG_INSPECT_PORT = undefined; } } @@ -83,5 +118,4 @@ function InstallExtension(vscodeExePath: string, extensionIdOrVSIXPath: string): return installResult.stdout; } - void main(); diff --git a/test/runTestsInner.ts b/test/runTestsInner.ts new file mode 100644 index 0000000000..8ae49a0ec6 --- /dev/null +++ b/test/runTestsInner.ts @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { globSync } from "glob"; +import path from "path"; +import Mocha from "mocha"; +/** This is the entrypoint into the standalone vscode instance that should be passed to the --extensionsTestPath parameter of the test VSCode instance. */ +export function run(testsRoot: string): Promise { + return runTestsInner(testsRoot); +} + +/** Runs inside of the test vscode instance, and should set up and activate the test runner */ +function runTestsInner(testsRoot: string): Promise { + // Allow tools like Mocha Test Explorer to inject their own Mocha worker + if (process.env.MOCHA_WORKER_PATH) { + return require(process.env.MOCHA_WORKER_PATH); + } + + console.log(`\n\n=====\nTest Runner START\n${testsRoot}\n=====`); + + /** Passed from RunTests */ + const rootDir = process.env.__TEST_EXTENSION_DEVELOPMENT_PATH; + if (!rootDir) { + throw new Error("Missing environment variable __TEST_EXTENSIONDEVELOPMENTPATH, this is probably a bug in runTests.ts"); + } + + interface MochaOptionsWithFiles extends Mocha.MochaOptions { + spec?: string; + } + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const config: MochaOptionsWithFiles = require(path.resolve(rootDir, ".mocharc.json")); + if (config.spec === undefined) { + throw new Error("spec must be specified in the config options when running vscode launch tests"); + } + + const mocha = new Mocha(config); + // if (process.env.TF_BUILD) { + // console.log("Detected Azure DevOps, disabling color output as ANSI escapes do not make Azure Devops happy."); + // config.color = false; + // } + + // Test if files is empty + const files = globSync(config.spec, { cwd: rootDir }); + if (files.length === 0) { + console.log("No tests found for glob pattern: test.ts in directory: " + rootDir); + throw new Error("No tests found for glob pattern: test.ts in directory: " + rootDir); + } + + // Add files to the test suite + for (const file of files) { + const testFile = path.resolve(rootDir, file); + mocha.addFile(testFile); + } + + mocha.reporter("mocha-multi-reporters", { + reporterEnabled: "spec, xunit", + xunitReporterOptions: { + output: path.resolve(rootDir, "test-results.xml"), + } + }); + + return new Promise((c, e) => { + try { + mocha.run(failures => { + console.log(`Mocha Run Finished with ${failures} failures.`); + if (failures > 0) { + throw new Error(`${failures} tests failed.`); + } else { + console.log("\n\n=====\nTest Runner STOP\n====="); + return c(); + } + }); + } catch (err) { + console.error("Failed to run tests"); + e(err); + } + }); +} diff --git a/test/utils.ts b/test/utils.ts index fe6c685479..d0beb09aac 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -77,10 +77,14 @@ export function stubInterface(object?: Partial): T { /** Builds the sample binary module code. We need to do this because the source maps have absolute paths so they are not portable between machines, and while we could do deterministic with source maps, that's way more complicated and everywhere we build has dotnet already anyways */ export function BuildBinaryModuleMock(): void { - console.log("==BUILDING: Binary Module Mock=="); const projectPath = path.resolve(`${__dirname}/../../test/mocks/BinaryModule/BinaryModule.csproj`); //Relative to "out/test" when testing. - const buildResult = execSync(`dotnet publish ${projectPath}`); - console.log(buildResult.toString()); + try { + execSync(`dotnet publish ${projectPath}`, { + encoding: "utf8" + }); + } catch (err) { + throw new Error(`Failed to build the binary module mock. Please ensure that you have the .NET Core SDK installed: ${err}`); + } } /** Waits until the registered vscode event is fired and returns the trigger result of the event. diff --git a/tsconfig.json b/tsconfig.json index 4db014f3af..a63f48ea46 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,8 @@ "noUnusedLocals": true, "noUnusedParameters": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "useUnknownInCatchVariables": true }, "include": [ "src", "test" ], }