Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Commit

Permalink
Add support for gotests
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
clamoriniere committed Sep 29, 2016
1 parent a443750 commit 4ecc64c
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand Down
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
124 changes: 124 additions & 0 deletions src/goGenerateTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*---------------------------------------------------------
* 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() {
let editor = testEditor();
if (!editor) {
vscode.window.showInformationMessage('gotests: No editor selected');
return;
}
let dir = path.dirname(editor.document.uri.fsPath);
generateTests({dir: dir});
vscode.window.showInformationMessage('gotests: Unit tests generated for package:' + path.basename(dir));
}

export function generateTestCurrentFile() {
let editor = testEditor();
if (!editor) {
vscode.window.showInformationMessage('gotests: No editor selected');
return;
}
let file = editor.document.uri.fsPath;
generateTests({dir: file});
vscode.window.showInformationMessage('gotests: Unit tests generated for file:' + path.basename(file));
}

export function generateTestCurrentFunction() {
let editor = testEditor();
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;
}
generateTests({dir: file, func: currentFunction.name});
vscode.window.showInformationMessage('gotests: Unit test generated for function: ' + currentFunction.name + ' in file:' + path.basename(file));
}).then(null, err => {
console.error(err);
});
}

/**
* Input to goTests.
*/
interface Config {
/**
* The working directory for `gotests`.
*/
dir: 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);
}
return resolve(true);
} catch (e) {
vscode.window.showInformationMessage(e.msg);
reject(e);
}
});
});
}

function testEditor(): vscode.TextEditor {
let editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showInformationMessage('No editor is active.');
return;
}
return editor;
}

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)
);
}
3 changes: 2 additions & 1 deletion src/goInstallTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ let tools: { [key: string]: string } = {
'go-symbols': 'github.com/newhook/go-symbols',
'guru': 'golang.org/x/tools/cmd/guru',
'gorename': 'golang.org/x/tools/cmd/gorename',
'goimports': 'golang.org/x/tools/cmd/goimports'
'goimports': 'golang.org/x/tools/cmd/goimports',
'gotests': 'github.com/cweill/gotests/...'
};

export function installAllTools() {
Expand Down
13 changes: 13 additions & 0 deletions src/goMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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*\}.*$
Expand Down

0 comments on commit 4ecc64c

Please sign in to comment.