[release] src/testUtil.ts: switch to -json mode only if -v is set
CL/242540 made runTest uses -json mode to ease streaming
test output processing. However, it turned out -json makes
the test output more verbose than the standard test output.
(golang/go#40588)
Verbose output by default is not ideal especially when
running tests on many packages. This change brings back
the old test output processing logic when users do not use
the `-v` flag. The `go test` command will stream test
output only if the `-v` flag is specified, so the original
issue CL/242540 remains addressed.
Fixes golang/vscode-go#471
Updates golang/vscode-go#316
Updates golang/go#40588
Change-Id: I29d6d1319acccab2457300c118216ceebb4c4033
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/246918
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
(cherry picked from commit bec9cf3fa2c4306217ba1d79c6c476b0b3909fe7)
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/247017
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/src/testUtils.ts b/src/testUtils.ts
index aafe427..cd00956 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -21,7 +21,7 @@
resolvePath
} from './util';
import { envPath, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH, parseEnvFile } from './utils/goPath';
-import {killProcessTree} from './utils/processUtils';
+import { killProcessTree } from './utils/processUtils';
const testOutputChannel = vscode.window.createOutputChannel('Go Tests');
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
@@ -326,8 +326,11 @@
outTargets.push(...targets);
}
+ if (args.includes('-v') && !args.includes('-json')) {
+ args.push('-json');
+ }
+
args.push(...targets);
- args.push('-json');
// ensure that user provided flags are appended last (allow use of -args ...)
// ignore user provided -run flag if we are already using it
@@ -345,29 +348,9 @@
const errBuf = new LineBuffer();
const testResultLines: string[] = [];
- const processTestResultLine = (line: string) => {
- try {
- const m = <GoTestOutput>(JSON.parse(line));
- if (m.Action !== 'output' || !m.Output) {
- return;
- }
- const out = m.Output;
- const pkg = m.Package;
- if (pkg && (pkgMap.has(pkg) || currentGoWorkspace)) {
- const pkgNameArr = pkg.split('/');
- const baseDir = pkgMap.get(pkg) || path.join(currentGoWorkspace, ...pkgNameArr);
- // go test emits test results on stdout, which contain file names relative to the package under test
- outputChannel.appendLine(expandFilePathInOutput(out, baseDir).trimRight());
- } else {
- outputChannel.appendLine(out.trimRight());
- }
- } catch (e) {
- // TODO: disable this log if it becomes too spammy.
- console.log(`failed to parse JSON: ${e}: ${line}`);
- // Build failures or other messages come in non-JSON format. So, output as they are.
- outputChannel.appendLine(line);
- }
- };
+ const processTestResultLine = args.includes('-json') ?
+ processTestResultLineInJSONMode(pkgMap, currentGoWorkspace, outputChannel) :
+ processTestResultLineInStandardMode(pkgMap, currentGoWorkspace, testResultLines, outputChannel);
outBuf.onLine((line) => processTestResultLine(line));
outBuf.onDone((last) => {
@@ -421,6 +404,63 @@
return testResult;
}
+function processTestResultLineInJSONMode(
+ pkgMap: Map<string, string>,
+ currentGoWorkspace: string,
+ outputChannel: vscode.OutputChannel) {
+ return (line: string) => {
+ try {
+ const m = <GoTestOutput>(JSON.parse(line));
+ if (m.Action !== 'output' || !m.Output) {
+ return;
+ }
+ const out = m.Output;
+ const pkg = m.Package;
+ if (pkg && (pkgMap.has(pkg) || currentGoWorkspace)) {
+ const pkgNameArr = pkg.split('/');
+ const baseDir = pkgMap.get(pkg) || path.join(currentGoWorkspace, ...pkgNameArr);
+ // go test emits test results on stdout, which contain file names relative to the package under test
+ outputChannel.appendLine(expandFilePathInOutput(out, baseDir).trimRight());
+ } else {
+ outputChannel.appendLine(out.trimRight());
+ }
+ } catch (e) {
+ // TODO: disable this log if it becomes too spammy.
+ console.log(`failed to parse JSON: ${e}: ${line}`);
+ // Build failures or other messages come in non-JSON format. So, output as they are.
+ outputChannel.appendLine(line);
+ }
+ };
+}
+
+function processTestResultLineInStandardMode(
+ pkgMap: Map<string, string>,
+ currentGoWorkspace: string,
+ testResultLines: string[],
+ outputChannel: vscode.OutputChannel) {
+ // 1=ok/FAIL, 2=package, 3=time/(cached)
+ const packageResultLineRE = /^(ok|FAIL)\s+(\S+)\s+([0-9\.]+s|\(cached\))/;
+ const lineWithErrorRE = /^(\t|\s\s\s\s)\S/;
+
+ return (line: string) => {
+ testResultLines.push(line);
+ const result = line.match(packageResultLineRE);
+ if (result && (pkgMap.has(result[2]) || currentGoWorkspace)) {
+ const hasTestFailed = line.startsWith('FAIL');
+ const packageNameArr = result[2].split('/');
+ const baseDir = pkgMap.get(result[2]) || path.join(currentGoWorkspace, ...packageNameArr);
+ testResultLines.forEach((testResultLine) => {
+ if (hasTestFailed && lineWithErrorRE.test(testResultLine)) {
+ outputChannel.appendLine(expandFilePathInOutput(testResultLine, baseDir));
+ } else {
+ outputChannel.appendLine(testResultLine);
+ }
+ });
+ testResultLines.splice(0);
+ }
+ };
+}
+
/**
* Reveals the output channel in the UI.
*/