Skip to content

Commit

Permalink
add support for multi-file test suite
Browse files Browse the repository at this point in the history
When evaluating whether a symbol is a document or not, check if testify was imported by any file of the directory (which is the go package).

Fixes golang#1130
  • Loading branch information
nirhaas committed Jul 12, 2022
1 parent 2de6d67 commit a5aebe1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/goTest/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { getCurrentGoPath } from '../util';
import { getGoConfig } from '../config';
import { dispose, disposeIfEmpty, FileSystem, GoTest, GoTestKind, findModuleName, isInTest, Workspace } from './utils';
import { walk, WalkStop } from './walk';
import { importsTestify } from '../testUtils';
import { isPackageTestify } from '../testUtils';

export type ProvideSymbols = (doc: TextDocument, token?: CancellationToken) => Thenable<DocumentSymbol[]>;

Expand Down Expand Up @@ -205,7 +205,7 @@ export class GoTestResolver {
const seen = new Set<string>();
const item = await this.getFile(doc.uri);
const symbols = await this.provideDocumentSymbols(doc);
const testify = importsTestify(symbols);
const testify = await isPackageTestify(this.provideDocumentSymbols, doc);
for (const symbol of symbols) {
await this.processSymbol(doc, item, seen, testify, symbol);
}
Expand Down
35 changes: 33 additions & 2 deletions src/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import cp = require('child_process');
import path = require('path');
import util = require('util');
import fs = require('fs');
import vscode = require('vscode');

import { applyCodeCoverageToAllEditors } from './goCover';
Expand Down Expand Up @@ -149,6 +150,8 @@ export async function getTestFunctions(
token?: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[] | undefined> {
const documentSymbolProvider = GoDocumentSymbolProvider(goCtx, true);

const testify = await isPackageTestify(documentSymbolProvider.provideDocumentSymbols, doc, token);
const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
if (!symbols || symbols.length === 0) {
return;
Expand All @@ -158,7 +161,6 @@ export async function getTestFunctions(
return;
}
const children = symbol.children;
const testify = importsTestify(symbols);
return children.filter(
(sym) =>
(sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) &&
Expand Down Expand Up @@ -586,6 +588,35 @@ export function cancelRunningTests(): Thenable<boolean> {
});
}

export type ProvideSymbols = (
doc: vscode.TextDocument,
token?: vscode.CancellationToken
) => Thenable<vscode.DocumentSymbol[]>;

/**
* Returns whether a file in the package imports testify.
*/
export async function isPackageTestify(
symbolsProvier: ProvideSymbols,
doc: vscode.TextDocument,
token?: vscode.CancellationToken | undefined
) {
const fsReaddir = util.promisify(fs.readdir);

// Get all the package documents.
const packageDir = path.parse(doc.fileName).dir;
const packageFilenames = await fsReaddir(packageDir);
const packageDocs = await Promise.all(
packageFilenames.map((e) => path.join(packageDir, e)).map(vscode.workspace.openTextDocument)
);

// Parse the symbols of each document.
const docSymbols = await Promise.all(packageDocs.map((e) => symbolsProvier(e, token)));

// One file is enough.
return docSymbols.some(importsTestify);
}

/**
* Get the test target arguments.
*
Expand Down Expand Up @@ -640,7 +671,7 @@ function removeRunFlag(flags: string[]): void {
}
}

export function importsTestify(syms: vscode.DocumentSymbol[]): boolean {
function importsTestify(syms: vscode.DocumentSymbol[]): boolean {
if (!syms || syms.length === 0 || !syms[0]) {
return false;
}
Expand Down

0 comments on commit a5aebe1

Please sign in to comment.