Implements three new commands that use gotests:
- go.test.generate.package: generates all unit-test squeletons for
  the current package.
- go.test.generate.file: generates all unit-test squeletons for
  the current file.
- go.test.generate.function: generates unit-test squeleton for the
  selected function in the current file.
This commit is contained in:
Cedric Lamoriniere 2016-09-13 08:17:21 +02:00
Родитель bca4ff159e
Коммит 241c2dfdd7
7 изменённых файлов: 196 добавлений и 0 удалений

Просмотреть файл

@ -31,6 +31,7 @@ install:
- go get -u -v github.com/newhook/go-symbols
- go get -u -v golang.org/x/tools/cmd/guru
- go get -u -v github.com/alecthomas/gometalinter
- go get -u -v github.com/cweill/gotests/...
- GO15VENDOREXPERIMENT=1 gometalinter --install
script:

Просмотреть файл

@ -19,6 +19,7 @@ This extension adds rich language support for the Go language to VS Code, includ
- Build-on-save (using `go build` and `go test`)
- Lint-on-save (using `golint` or `gometalinter`)
- Format (using `goreturns` or `goimports` or `gofmt`)
- Generate unit tests squeleton (using `gotests`)
- Add Imports (using `gopkgs`)
- [_partially implemented_] Debugging (using `delve`)
@ -98,6 +99,9 @@ In addition to integrated editing features, the extension also provides several
* `Go: Run test at cursor` to run a test at the current cursor position in the active document
* `Go: Run tests in current package` to run all tests in the package containing the active document
* `Go: Run tests in current file` to run all tests in the current active document
* `Go: Generates unit tests (package)` Generates unit tests for the current package
* `Go: Generates unit tests (file)` Generates unit tests for the current file
* `Go: Generates unit tests (function)` Generates unit tests for the selected function in the current file
### _Optional_: Debugging
@ -200,6 +204,7 @@ The extension uses the following tools, installed in the current GOPATH. If any
- gopkgs: `go get -u -v github.com/tpng/gopkgs`
- go-symbols: `go get -u -v github.com/newhook/go-symbols`
- guru: `go get -u -v golang.org/x/tools/cmd/guru`
- gotests: `go get -u -v github.com/cweill/gotests/...`
To install them just paste and run:
```bash
@ -212,6 +217,7 @@ go get -u -v golang.org/x/tools/cmd/gorename
go get -u -v github.com/tpng/gopkgs
go get -u -v github.com/newhook/go-symbols
go get -u -v golang.org/x/tools/cmd/guru
go get -u -v github.com/cweill/gotests/...
```
And for debugging:

Просмотреть файл

@ -107,6 +107,21 @@
"title": "Go: Test coverage in current package",
"description": "Displays test coverage in the current package."
},
{
"command": "go.test.generate.package",
"title": "Go: Generate unit tests for current package",
"description": "Generates unit tests for the current package"
},
{
"command": "go.test.generate.file",
"title": "Go: Generate unit tests for current file",
"description": "Generates unit tests for the current file"
},
{
"command": "go.test.generate.function",
"title": "Go: Generate unit tests for current function",
"description": "Generates unit tests for the selected function in the current file"
},
{
"command": "go.import.add",
"title": "Go: Add Import",

121
src/goGenerateTests.ts Normal file
Просмотреть файл

@ -0,0 +1,121 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------*/
'use strict';
import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
import util = require('util');
import { getBinPath } from './goPath';
import { promptForMissingTool } from './goInstallTools';
import { GoDocumentSymbolProvider } from './goOutline';
export function generateTestCurrentPackage(): Thenable<boolean> {
let editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showInformationMessage('gotests: No editor selected');
return;
}
let dir = path.dirname(editor.document.uri.fsPath);
let message = 'Unit tests generated for package:' + path.basename(dir);
return generateTests({dir: dir, msg: message });
}
export function generateTestCurrentFile(): Thenable<boolean> {
let editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showInformationMessage('gotests: No editor selected');
return;
}
let file = editor.document.uri.fsPath;
let message = 'Unit tests generated for file:' + path.basename(file);
return generateTests({dir: file, msg: message });
}
export function generateTestCurrentFunction(): Thenable<boolean> {
let editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showInformationMessage('gotests: No selected Editor');
return;
}
let file = editor.document.uri.fsPath;
getFunctions(editor.document).then(functions => {
let currentFunction: vscode.SymbolInformation;
for (let func of functions) {
let selection = editor.selection;
if (selection && func.location.range.contains(selection.start)) {
currentFunction = func;
break;
}
};
if (!currentFunction) {
vscode.window.setStatusBarMessage('No function found at cursor.', 5000);
return;
}
let message = 'Unit test generated for function: ' + currentFunction.name + ' in file:' + path.basename(file);
return generateTests({dir: file, msg: message, func: currentFunction.name});
}).then(null, err => {
console.error(err);
});
}
/**
* Input to goTests.
*/
interface Config {
/**
* The working directory for `gotests`.
*/
dir: string;
/**
* The Message that show up in case of success
*/
msg: string;
/**
* Specific function names to generate tests squeleton.
*/
func?: string;
}
function generateTests(conf: Config): Thenable<boolean> {
return new Promise<boolean>((resolve, reject) => {
let cmd = getBinPath('gotests');
let args;
if (conf.func) {
args = ['-w', '-only', conf.func, conf.dir];
} else {
args = ['-w', '-all', conf.dir];
}
cp.execFile(cmd, args, {}, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gotests');
return resolve(false);
}
if (err) {
return reject('Cannot generate test due to errors: ' + stderr);
}
let message = 'gotests: ' + conf.msg;
vscode.window.showInformationMessage(message);
return resolve(true);
} catch (e) {
vscode.window.showInformationMessage(e.msg);
reject(e);
}
});
});
}
function getFunctions(doc: vscode.TextDocument): Thenable<vscode.SymbolInformation[]> {
let documentSymbolProvider = new GoDocumentSymbolProvider();
return documentSymbolProvider
.provideDocumentSymbols(doc, null)
.then(symbols =>
symbols.filter(sym =>
sym.kind === vscode.SymbolKind.Function)
);
}

Просмотреть файл

@ -43,6 +43,7 @@ function getTools(): { [key: string]: string } {
// golint is no longer supported in go1.5
if (goVersion && (goVersion.major > 1 || (goVersion.major === 1 && goVersion.minor > 5))) {
tools['golint'] = 'github.com/golang/lint/golint';
tools['gotests'] = 'github.com/cweill/gotests/...';
}
return tools;
}

Просмотреть файл

@ -25,6 +25,7 @@ import { GO_MODE } from './goMode';
import { showHideStatus } from './goStatus';
import { coverageCurrentPackage, getCodeCoverage, removeCodeCoverage } from './goCover';
import { testAtCursor, testCurrentPackage, testCurrentFile, testPrevious } from './goTest';
import { generateTestCurrentPackage, generateTestCurrentFile, generateTestCurrentFunction } from './goGenerateTests';
import { addImport } from './goImport';
import { installAllTools } from './goInstallTools';
@ -92,6 +93,18 @@ export function activate(ctx: vscode.ExtensionContext): void {
updateGoPathGoRootFromConfig();
}));
ctx.subscriptions.push(vscode.commands.registerCommand('go.test.generate.package', () => {
generateTestCurrentPackage();
}));
ctx.subscriptions.push(vscode.commands.registerCommand('go.test.generate.file', () => {
generateTestCurrentFile();
}));
ctx.subscriptions.push(vscode.commands.registerCommand('go.test.generate.function', () => {
generateTestCurrentFunction();
}));
vscode.languages.setLanguageConfiguration(GO_MODE.language, {
indentationRules: {
// ^(.*\*/)?\s*\}.*$

Просмотреть файл

@ -18,6 +18,7 @@ import { testCurrentFile } from '../src/goTest';
import { getGoVersion } from '../src/goInstallTools';
import { documentSymbols } from '../src/goOutline';
import { listPackages } from '../src/goImport';
import { generateTestCurrentFile, generateTestCurrentPackage } from '../src/goGenerateTests';
suite('Go Extension Tests', () => {
let gopath = process.env['GOPATH'];
@ -144,6 +145,44 @@ encountered.
});
test('Test Generate unit tests squeleton for file', (done) => {
getGoVersion().then(version => {
if (version.major === 1 && version.minor === 5) {
// gotests is not supported in Go 1.5, so skip the test
return Promise.resolve();
}
let uri = vscode.Uri.file(path.join(fixturePath, 'test.go'));
vscode.workspace.openTextDocument(uri).then(document => {
return vscode.window.showTextDocument(document).then(editor => {
return generateTestCurrentFile().then((result: boolean) => {
assert.equal(result, true);
return Promise.resolve();
});
});
});
}).then(() => done(), done);
});
test('Test Generate unit tests squeleton for package', (done) => {
getGoVersion().then(version => {
if (version.major === 1 && version.minor === 5) {
// gotests is not supported in Go 1.5, so skip the test
return Promise.resolve();
}
let uri = vscode.Uri.file(path.join(fixturePath, 'test.go'));
vscode.workspace.openTextDocument(uri).then(document => {
return vscode.window.showTextDocument(document).then(editor => {
return generateTestCurrentPackage().then((result: boolean) => {
assert.equal(result, true);
return Promise.resolve();
});
});
});
}).then(() => done(), done);
});
test('Gometalinter error checking', (done) => {
let config = Object.create(vscode.workspace.getConfiguration('go'), {
'lintTool': { value: 'gometalinter' }