src/goTest: Add command Test Function At Cursor or Test Previous
This runs `Test Function At Cursor` if a unit test is found at the
cursor, otherwise it turns `Test Previous`.
Fixes golang/vscode-go#1508
Change-Id: I91305797dfeccd79c1f5ea14298a60803f24492b
GitHub-Last-Rev: 005415566932b373a994d7d39730f6996c97dab0
GitHub-Pull-Request: golang/vscode-go#1509
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/320769
Trust: Michael Knyszek <mknyszek@google.com>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/docs/commands.md b/docs/commands.md
index 6486617..23e0821 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -35,6 +35,10 @@
Runs a unit test at the cursor.
+### `Go: Test Function At Cursor or Test Previous`
+
+Runs a unit test at the cursor if one is found, otherwise re-runs the last executed test.
+
### `Go: Subtest At Cursor`
Runs a sub test at the cursor.
diff --git a/package.json b/package.json
index faab923..c620403 100644
--- a/package.json
+++ b/package.json
@@ -202,6 +202,11 @@
"description": "Runs a unit test at the cursor."
},
{
+ "command": "go.test.cursorOrPrevious",
+ "title": "Go: Test Function At Cursor or Test Previous",
+ "description": "Runs a unit test at the cursor if one is found, otherwise re-runs the last executed test."
+ },
+ {
"command": "go.subtest.cursor",
"title": "Go: Subtest At Cursor",
"description": "Runs a sub test at the cursor."
diff --git a/src/goMain.ts b/src/goMain.ts
index d03f863..b215f07 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -64,6 +64,7 @@
debugPrevious,
subTestAtCursor,
testAtCursor,
+ testAtCursorOrPrevious,
testCurrentFile,
testCurrentPackage,
testPrevious,
@@ -317,6 +318,13 @@
);
ctx.subscriptions.push(
+ vscode.commands.registerCommand('go.test.cursorOrPrevious', (args) => {
+ const goConfig = getGoConfig();
+ testAtCursorOrPrevious(goConfig, 'test', args);
+ })
+ );
+
+ ctx.subscriptions.push(
vscode.commands.registerCommand('go.subtest.cursor', (args) => {
const goConfig = getGoConfig();
subTestAtCursor(goConfig, args);
diff --git a/src/goTest.ts b/src/goTest.ts
index e25c9d7..bbf95c8 100644
--- a/src/goTest.ts
+++ b/src/goTest.ts
@@ -31,50 +31,68 @@
export type TestAtCursorCmd = 'debug' | 'test' | 'benchmark';
+class NotFoundError extends Error {}
+
+async function _testAtCursor(goConfig: vscode.WorkspaceConfiguration, cmd: TestAtCursorCmd, args: any) {
+ const editor = vscode.window.activeTextEditor;
+ if (!editor) {
+ throw new NotFoundError('No editor is active.');
+ }
+ if (!editor.document.fileName.endsWith('_test.go')) {
+ throw new NotFoundError('No tests found. Current file is not a test file.');
+ }
+
+ const getFunctions = cmd === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
+ const testFunctions = await getFunctions(editor.document, null);
+ // We use functionName if it was provided as argument
+ // Otherwise find any test function containing the cursor.
+ const testFunctionName =
+ args && args.functionName
+ ? args.functionName
+ : testFunctions.filter((func) => func.range.contains(editor.selection.start)).map((el) => el.name)[0];
+ if (!testFunctionName) {
+ throw new NotFoundError('No test function found at cursor.');
+ }
+
+ await editor.document.save();
+
+ if (cmd === 'debug') {
+ return debugTestAtCursor(editor, testFunctionName, testFunctions, goConfig);
+ } else if (cmd === 'benchmark' || cmd === 'test') {
+ return runTestAtCursor(editor, testFunctionName, testFunctions, goConfig, cmd, args);
+ } else {
+ throw new Error(`Unsupported command: ${cmd}`);
+ }
+}
+
/**
* Executes the unit test at the primary cursor using `go test`. Output
* is sent to the 'Go' channel.
* @param goConfig Configuration for the Go extension.
- * @param cmd Whether the command is test , benchmark or debug.
+ * @param cmd Whether the command is test, benchmark, or debug.
* @param args
*/
export function testAtCursor(goConfig: vscode.WorkspaceConfiguration, cmd: TestAtCursorCmd, args: any) {
- const editor = vscode.window.activeTextEditor;
- if (!editor) {
- vscode.window.showInformationMessage('No editor is active.');
- return;
- }
- if (!editor.document.fileName.endsWith('_test.go')) {
- vscode.window.showInformationMessage('No tests found. Current file is not a test file.');
- return;
- }
+ _testAtCursor(goConfig, cmd, args).catch((err) => {
+ if (err instanceof NotFoundError) {
+ vscode.window.showInformationMessage(err.message);
+ } else {
+ console.error(err);
+ }
+ });
+}
- const getFunctions = cmd === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
-
- editor.document.save().then(async () => {
- try {
- const testFunctions = await getFunctions(editor.document, null);
- // We use functionName if it was provided as argument
- // Otherwise find any test function containing the cursor.
- const testFunctionName =
- args && args.functionName
- ? args.functionName
- : testFunctions
- .filter((func) => func.range.contains(editor.selection.start))
- .map((el) => el.name)[0];
- if (!testFunctionName) {
- vscode.window.showInformationMessage('No test function found at cursor.');
- return;
- }
-
- if (cmd === 'debug') {
- await debugTestAtCursor(editor, testFunctionName, testFunctions, goConfig);
- } else if (cmd === 'benchmark' || cmd === 'test') {
- await runTestAtCursor(editor, testFunctionName, testFunctions, goConfig, cmd, args);
- } else {
- throw new Error('Unsupported command.');
- }
- } catch (err) {
+/**
+ * Executes the unit test at the primary cursor if found, otherwise re-runs the previous test.
+ * @param goConfig Configuration for the Go extension.
+ * @param cmd Whether the command is test, benchmark, or debug.
+ * @param args
+ */
+export function testAtCursorOrPrevious(goConfig: vscode.WorkspaceConfiguration, cmd: TestAtCursorCmd, args: any) {
+ _testAtCursor(goConfig, cmd, args).catch((err) => {
+ if (err instanceof NotFoundError) {
+ testPrevious();
+ } else {
console.error(err);
}
});