This commit is contained in:
Pine Wu 2019-03-14 11:33:54 -07:00
Коммит e3f3426298
17 изменённых файлов: 2172 добавлений и 0 удалений

15
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,15 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Tab indentation
[*]
indent_style = tab
trim_trailing_whitespace = true
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[{*.yml,*.yaml,package.json}]
indent_style = space
indent_size = 2

5
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
.vscode-test
node_modules
vscode.d.ts
out

6
.npmignore Normal file
Просмотреть файл

@ -0,0 +1,6 @@
.vscode
.npmignore
lib/shared.ts
lib/testrunner.ts
tsconfig.json
tslint.json

14
.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
// Place your settings in this file to overwrite default and user settings.
{
"editor.insertSpaces": true,
"files.eol": "\n",
"files.trimTrailingWhitespace": true,
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/*.js": {
"when": "$(basename).ts"
}
},
"prettier.semi": true
}

9
.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
{
"version": "0.1.0",
"command": "npm",
"isWatching": true,
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "watch"],
"problemMatcher": "$tsc-watch"
}

21
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

44
README.md Normal file
Просмотреть файл

@ -0,0 +1,44 @@
# vscode-test
This module helps you testing VS Code extensions.
## Usage
```ts
import * as path from 'path'
import { runTests } from 'vscode-test'
async function go() {
const extensionPath = path.resolve(__dirname, '../../')
const testRunnerPath = path.resolve(__dirname, './suite')
const testWorkspace = path.resolve(__dirname, '../../test-fixtures/fixture1')
await runTests({
extensionPath,
testRunnerPath,
testWorkspace
})
}
go()
```
## License
[MIT](LICENSE)
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

136
lib/download.js Normal file
Просмотреть файл

@ -0,0 +1,136 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var downloadPlatform;
switch (process.platform) {
case 'darwin':
downloadPlatform = 'darwin';
break;
case 'win32':
downloadPlatform = 'win32-archive';
break;
default:
downloadPlatform = 'linux-x64';
}
var url = "https://update.code.visualstudio.com/latest/" + downloadPlatform + "/stable";
var https = require("https");
var fs = require("fs");
var path = require("path");
var cp = require("child_process");
var extensionRoot = process.cwd();
var vscodeTestDir = path.resolve(extensionRoot, '.vscode-test');
var vscodeExecutableDir = path.resolve(extensionRoot, '.vscode-test/stable');
function downloadVSCode() {
fs.mkdirSync(vscodeTestDir, { recursive: true });
return new Promise(function (resolve, reject) {
https.get(url, function (res) {
if (res.statusCode !== 302) {
reject('Failed to get VS Code archive location');
}
var archiveUrl = res.headers.location;
if (!archiveUrl) {
reject('Failed to get VS Code archive location');
return;
}
if (archiveUrl.endsWith('.zip')) {
var archivePath_1 = path.resolve(vscodeTestDir, 'vscode.zip');
var outStream_1 = fs.createWriteStream(archivePath_1);
outStream_1.on('close', function () {
resolve(archivePath_1);
});
https.get(archiveUrl, function (res) {
res.pipe(outStream_1);
});
}
else {
var zipPath_1 = path.resolve(vscodeTestDir, 'vscode.tgz');
var outStream_2 = fs.createWriteStream(zipPath_1);
https.get(archiveUrl, function (res) {
res.pipe(outStream_2);
});
outStream_2.on('close', function () {
resolve(zipPath_1);
});
}
});
});
}
function unzipVSCode(vscodeArchivePath) {
if (vscodeArchivePath.endsWith('.zip')) {
if (process.platform === 'win32') {
cp.spawnSync('powershell.exe', [
'-Command',
"Expand-Archive -Path " + vscodeArchivePath + " -DestinationPath " + vscodeExecutableDir
]);
}
else {
cp.spawnSync('unzip', [vscodeArchivePath, '-d', "" + vscodeExecutableDir]);
}
}
else {
cp.spawnSync('tar', ['-xzf', vscodeArchivePath, '-C', vscodeExecutableDir]);
}
}
function downloadAndUnzipVSCode() {
return __awaiter(this, void 0, void 0, function () {
var vscodeArchivePath;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!fs.existsSync(vscodeTestDir)) return [3 /*break*/, 2];
return [4 /*yield*/, downloadVSCode()];
case 1:
vscodeArchivePath = _a.sent();
unzipVSCode(vscodeArchivePath);
fs.unlinkSync(vscodeArchivePath);
_a.label = 2;
case 2:
if (process.platform === 'win32') {
return [2 /*return*/, path.resolve(vscodeExecutableDir, 'Code.exe')];
}
else if (process.platform === 'darwin') {
return [2 /*return*/, path.resolve(vscodeExecutableDir, 'Visual Studio Code.app/Contents/MacOS/Electron')];
}
else {
return [2 /*return*/, path.resolve(vscodeExecutableDir, 'VSCode-linux-x64/code')];
}
return [2 /*return*/];
}
});
});
}
exports.downloadAndUnzipVSCode = downloadAndUnzipVSCode;

187
lib/download.ts Normal file
Просмотреть файл

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
let downloadPlatform;
switch (process.platform) {
case 'darwin':
downloadPlatform = 'darwin';
break;
case 'win32':
downloadPlatform = 'win32-archive';
break;
default:
downloadPlatform = 'linux-x64';
}
const vscodeDownloadUrl = `https://update.code.visualstudio.com/latest/${downloadPlatform}/stable`;
import * as https from 'https';
import * as fs from 'fs';
import * as path from 'path';
import * as cp from 'child_process';
import { getJSON } from './request';
const extensionRoot = process.cwd();
const vscodeTestDir = path.resolve(extensionRoot, '.vscode-test');
const vscodeStableReleasesAPI = `https://update.code.visualstudio.com/api/releases/stable`;
async function fetchLatestStableRelease(): Promise<VSCodeVersion> {
const versions = await getJSON(vscodeStableReleasesAPI);
if (!versions || !Array.isArray(versions) || !versions[0]) {
throw Error('Failed to get latest VS Code version');
}
return versions[0] as VSCodeVersion;
}
export type VSCodeVersion =
| 'Insiders'
| '1.32.2'
| '1.32.1'
| '1.32.0'
| '1.31.1'
| '1.31.0'
| '1.30.2'
| '1.30.1'
| '1.30.0'
| '1.29.1'
| '1.29.0'
| '1.28.2'
| '1.28.1'
| '1.28.0'
| '1.27.2'
| '1.27.1'
| '1.27.0'
| '1.26.1'
| '1.26.0'
| '1.25.1'
| '1.25.0'
| '1.24.1'
| '1.24.0'
| '1.23.1'
| '1.23.0'
| '1.22.2'
| '1.22.1'
| '1.22.0'
| '1.21.1'
| '1.21.0'
| '1.20.1'
| '1.20.0'
| '1.19.3'
| '1.19.2'
| '1.19.1'
| '1.19.0'
| '1.18.1'
| '1.18.0'
| '1.17.2'
| '1.17.1'
| '1.17.0'
| '1.16.1'
| '1.16.0'
| '1.15.1'
| '1.15.0'
| '1.14.2'
| '1.14.1'
| '1.14.0';
/**
* Download a copy of VS Code.
*
* @param version The version of VS Code to download such as '1.32.0'. You can also use
* 'insiders' for downloading latest Insiders.
*/
async function downloadVSCode(version: VSCodeVersion): Promise<string> {
if (fs.existsSync(path.resolve(vscodeTestDir, version))) {
return Promise.resolve(path.resolve(vscodeTestDir, version));
}
console.log(`Downloading VS Code ${version}`);
if (!fs.existsSync(vscodeTestDir)) {
fs.mkdirSync(vscodeTestDir, { recursive: true });
}
return new Promise((resolve, reject) => {
https.get(vscodeDownloadUrl, res => {
if (res.statusCode !== 302) {
reject('Failed to get VS Code archive location');
}
const archiveUrl = res.headers.location;
if (!archiveUrl) {
reject('Failed to get VS Code archive location');
return;
}
if (archiveUrl.endsWith('.zip')) {
const archivePath = path.resolve(vscodeTestDir, `vscode-${version}.zip`);
const outStream = fs.createWriteStream(archivePath);
outStream.on('close', () => {
resolve(archivePath);
});
https.get(archiveUrl, res => {
res.pipe(outStream);
});
} else {
const zipPath = path.resolve(vscodeTestDir, `vscode-${version}.tgz`);
const outStream = fs.createWriteStream(zipPath);
https.get(archiveUrl, res => {
res.pipe(outStream);
});
outStream.on('close', () => {
resolve(zipPath);
});
}
});
});
}
/**
* Unzip a .zip or .tar.gz VS Code archive
*/
function unzipVSCode(vscodeArchivePath: string) {
// The 'vscode-1.32' out of '.../vscode-1.32.zip'
const dirName = path.parse(vscodeArchivePath).name;
const extractDir = path.resolve(vscodeTestDir, dirName);
if (vscodeArchivePath.endsWith('.zip')) {
if (process.platform === 'win32') {
cp.spawnSync('powershell.exe', [
'-Command',
`Expand-Archive -Path ${vscodeArchivePath} -DestinationPath ${extractDir}`
]);
} else {
cp.spawnSync('unzip', [vscodeArchivePath, '-d', `${extractDir}`]);
}
} else {
cp.spawnSync('tar', ['-xzf', vscodeArchivePath, '-C', extractDir]);
}
}
/**
* Download and unzip a copy of VS Code in `./.vscode-test`
*
* @param version The version of VS Code to download such as '1.32.0'. You can also use
* 'insiders' for downloading latest Insiders.
*/
export async function downloadAndUnzipVSCode(version?: VSCodeVersion): Promise<string> {
if (!version) {
version = await fetchLatestStableRelease();
}
const vscodeArchivePath = await downloadVSCode(version);
unzipVSCode(vscodeArchivePath);
// Remove archive
fs.unlinkSync(vscodeArchivePath);
if (process.platform === 'win32') {
return path.resolve(vscodeTestDir, `vscode-${version}`, 'Code.exe');
} else if (process.platform === 'darwin') {
return path.resolve(vscodeTestDir, `vscode-${version}`, 'Visual Studio Code.app/Contents/MacOS/Electron');
} else {
return path.resolve(vscodeTestDir, `vscode-${version}`, 'VSCode-linux-x64/code');
}
}

7
lib/index.ts Normal file
Просмотреть файл

@ -0,0 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export { downloadAndUnzipVSCode } from './download';
export { runTests } from './runTest';

30
lib/request.ts Normal file
Просмотреть файл

@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as https from 'https';
export async function getJSON(api: string) {
return new Promise((resolve, reject) => {
https.get(api, res => {
if (res.statusCode !== 200) {
reject('Failed to get JSON');
}
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
resolve(JSON.parse(data));
});
res.on('error', err => {
reject(err);
});
});
});
}

32
lib/runTest.js Normal file
Просмотреть файл

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var cp = require("child_process");
function runTests(vscodeExecutablePath, extPath, testPath, testWorkspace) {
return new Promise(function (resolve, reject) {
var args = [
testWorkspace,
'--extensionDevelopmentPath=' + extPath,
'--extensionTestsPath=' + testPath,
'--locale=en'
];
var cmd = cp.spawn(vscodeExecutablePath, args);
cmd.stdout.on('data', function (data) {
var s = data.toString();
if (!s.includes('update#setState idle')) {
console.log(s);
}
});
cmd.on('error', function (data) {
console.log('Test error: ' + data.toString());
});
cmd.on('close', function (code) {
console.log("Exit code: " + code);
if (code !== 0) {
reject('Failed');
}
console.log('Done\n');
resolve(code);
});
});
}
exports.runTests = runTests;

99
lib/runTest.ts Normal file
Просмотреть файл

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { downloadAndUnzipVSCode, VSCodeVersion } from './download';
export interface TestOptions {
/**
* The VS Code executable being used for testing.
*
* If not passed, will use options.version for downloading a copy of
* VS Code for testing. If `version` is not specified either, will
* download and use latest stable release.
*/
vscodeExecutablePath?: string;
/**
* The VS Code version to download. Default to latest stable version.
*/
version?: VSCodeVersion;
/**
* Absolute path to the extension root. Must include a `package.json`
* Extension Manifest.
*/
extensionPath: string;
/**
* Absolute path to the test suite folder. Must include an `index.js` that
* exports a test runner, such as:
*
* ```ts
* import * as testRunner from 'vscode/lib/testrunner';
* module.exports = testRunner;
* ```
*/
testRunnerPath: string;
/**
* Absolute path of the fixture workspace to launch for testing
*/
testWorkspace: string;
/**
* A list of arguments passed to `code` executable.
* See `code --help` for possible arguments.
*
* ```ts
* [
* options.testWorkspace,
* '--extensionDevelopmentPath=' + options.extPath,
* '--extensionTestsPath=' + options.testPath,
* '--locale=en'
* ];
* ```
*/
vscodeLaunchArgs?: string[];
}
export async function runTests(options: TestOptions): Promise<number> {
if (!options.vscodeExecutablePath) {
options.vscodeExecutablePath = await downloadAndUnzipVSCode(options.version);
}
return new Promise((resolve, reject) => {
const args = [
options.testWorkspace,
'--extensionDevelopmentPath=' + options.extensionPath,
'--extensionTestsPath=' + options.testRunnerPath,
'--locale=en'
];
const cmd = cp.spawn(options.vscodeExecutablePath, args);
cmd.stdout.on('data', function(data) {
const s = data.toString();
if (!s.includes('update#setState idle')) {
console.log(s);
}
});
cmd.on('error', function(data) {
console.log('Test error: ' + data.toString());
});
cmd.on('close', function(code) {
console.log(`Exit code: ${code}`);
if (code !== 0) {
reject('Failed');
}
console.log('Done\n');
resolve(code);
});
});
}

34
package.json Normal file
Просмотреть файл

@ -0,0 +1,34 @@
{
"name": "vscode-test",
"version": "0.0.1",
"scripts": {
"compile": "tsc -p ./",
"watch": "tsc -w -p ./",
"prepublish": "tsc -p ./"
},
"main": "./out/index.js",
"engines": {
"node": ">=8.9.3"
},
"dependencies": {
"glob": "^7.1.2",
"mocha": "^6.0.2",
"semver": "^5.4.1",
"source-map-support": "^0.5.0",
"url-parse": "^1.4.3"
},
"devDependencies": {
"@types/glob": "^5.0.33",
"@types/mocha": "^5.2.6",
"@types/node": "^10.12.21"
},
"license": "MIT",
"author": "Visual Studio Code Team",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-test.git"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-test/issues"
}
}

13
tsconfig.json Normal file
Просмотреть файл

@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["es2015"],
"outDir": "out",
"declaration": true
},
"include": [
"lib"
],
"exclude": ["node_modules"]
}

21
tslint.json Normal file
Просмотреть файл

@ -0,0 +1,21 @@
{
"rules": {
"no-unused-expression": true,
"no-unreachable": true,
"no-duplicate-variable": true,
"no-duplicate-key": true,
"no-unused-variable": true,
"curly": true,
"class-name": true,
"semicolon": true,
"triple-equals": true,
"no-unexternalized-strings": [
true,
{
"signatures": ["localize", "nls.localize"],
"keyIndex": 0,
"messageIndex": 1
}
]
}
}

1499
yarn.lock Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу