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

Commit

Permalink
Find matching test functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mhr3 committed Jun 12, 2018
1 parent 29f7268 commit 273966b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
13 changes: 11 additions & 2 deletions src/goRunTestCodelens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import vscode = require('vscode');
import path = require('path');
import { TextDocument, CancellationToken, CodeLens, Command } from 'vscode';
import { getTestFunctions, getBenchmarkFunctions, getTestFlags, extractInstanceTestName } from './testUtils';
import { getTestFunctions, getBenchmarkFunctions, getTestFlags, extractInstanceTestName, findTestFnForInstanceTest } from './testUtils';
import { GoDocumentSymbolProvider } from './goOutline';
import { getCurrentGoPath } from './util';
import { GoBaseCodeLensProvider } from './goBaseCodelens';
Expand Down Expand Up @@ -94,8 +94,17 @@ export class GoRunTestCodeLensProvider extends GoBaseCodeLensProvider {

codelens.push(new CodeLens(func.location.range, runTestCmd));

let args: string[] = [];
let instanceMethod = extractInstanceTestName(func.name);
let args = !instanceMethod ? ['-test.run', `^${func.name}$`] : ['-testify.m', `^${instanceMethod}$`];
if (instanceMethod) {
const testFn = findTestFnForInstanceTest(func.name, document, testFunctions);
if (testFn) {
args = args.concat('-test.run', `^${testFn.name}$`);
}
args = args.concat('-testify.m', `^${instanceMethod}$`);
} else {
args = args.concat('-test.run', `^${func.name}$`);
}

let debugTestCmd: Command = {
title: 'debug test',
Expand Down
14 changes: 12 additions & 2 deletions src/goTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import path = require('path');
import vscode = require('vscode');
import os = require('os');
import { goTest, TestConfig, getTestFlags, getTestFunctions, getBenchmarkFunctions } from './testUtils';
import { goTest, TestConfig, getTestFlags, getTestFunctions, getBenchmarkFunctions, extractInstanceTestName, findTestFnForInstanceTest } from './testUtils';
import { getCoverage } from './goCover';

// lastTestConfig holds a reference to the last executed TestConfig which allows
Expand Down Expand Up @@ -59,11 +59,21 @@ export function testAtCursor(goConfig: vscode.WorkspaceConfiguration, isBenchmar
return;
}

const testConfigFns = [testFunctionName];

if (!isBenchmark && extractInstanceTestName(testFunctionName)) {
// find test function with corresponding suite.Run
const t = findTestFnForInstanceTest(testFunctionName, editor.document, testFunctions);
if (t) {
testConfigFns.push(t.name);
}
}

const testConfig: TestConfig = {
goConfig: goConfig,
dir: path.dirname(editor.document.fileName),
flags: testFlags,
functions: [testFunctionName],
functions: testConfigFns,
isBenchmark: isBenchmark,
};

Expand Down
45 changes: 42 additions & 3 deletions src/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { getNonVendorPackages } from './goPackages';

let outputChannel = vscode.window.createOutputChannel('Go Tests');

const testSuiteMethodRegex = /^\([^)]+\)\.(Test.*)$/;
const testSuiteMethodRegex = /^\(([^)]+)\)\.(Test.*)$/;

/**
* Input to goTest.
Expand Down Expand Up @@ -103,10 +103,49 @@ export function getTestFunctions(doc: vscode.TextDocument, token: vscode.Cancell
*/
export function extractInstanceTestName(symbolName: string): string {
const match = symbolName.match(testSuiteMethodRegex);
if (!match || match.length !== 2) {
if (!match || match.length !== 3) {
return null;
}
return match[1];
return match[2];
}

/**
* Finds test method containing suite.Run() call for the given instance test name.
*
* @param symbolName Instance test function name (including the type name)
* @param doc Editor document
* @param allTests All test functions
*/
export function findTestFnForInstanceTest(symbolName: string, doc: vscode.TextDocument, allTests: vscode.SymbolInformation[]): vscode.SymbolInformation {
// get non-instance test functions
const testFunctions = allTests.filter(t => !testSuiteMethodRegex.test(t.name));
// filter further to ones containing suite.Run()
const candidates = testFunctions.filter(t => {
const text = doc.getText(t.location.range);
return /suite\.Run\(/.test(text);
});

switch (candidates.length) {
case 0: return null;
case 1: return candidates[0];
}

// we have multiple matches, filter even more
const match = symbolName.match(testSuiteMethodRegex);
if (!match || match.length !== 3) {
return candidates[0];
}
// drop pointers, lowercase for more lenient matching
const instanceType = match[1].replace(/[*]/g, '').toLowerCase();
const filtered = candidates.filter(t => {
const text = doc.getText(t.location.range).toLowerCase();
if (text.includes(instanceType)) {
return true;
}
// try the test name as well
return t.name.substring(4).includes(instanceType);
});
return filtered.length > 0 ? filtered[0] : candidates[0];
}

/**
Expand Down

0 comments on commit 273966b

Please sign in to comment.