diff --git a/src/goTest.ts b/src/goTest.ts index 4899f3f9a..4f808388b 100644 --- a/src/goTest.ts +++ b/src/goTest.ts @@ -11,7 +11,7 @@ import vscode = require('vscode'); import util = require('util'); import os = require('os'); import { parseEnvFile, getGoRuntimePath, resolvePath } from './goPath'; -import { getToolsEnvVars } from './util'; +import { getToolsEnvVars, LineBuffer } from './util'; import { GoDocumentSymbolProvider } from './goOutline'; import { getNonVendorPackages } from './goPackages'; @@ -243,26 +243,22 @@ export function goTest(testconfig: TestConfig): Thenable { args.push(...targets); let proc = cp.spawn(goRuntimePath, args, { env: testEnvVars, cwd: testconfig.dir }); - let leftOver = ''; - let errChunks = []; - proc.stdout.on('data', chunk => { - let s = chunk.toString(); - let lastNewLineIndex = s.lastIndexOf('\n'); - if (lastNewLineIndex > -1) { - let sub = leftOver + s.substring(0, lastNewLineIndex); - leftOver = s.substring(lastNewLineIndex + 1); - - let testOutput = expandFilePathInOutput(sub, testconfig.dir); - outputChannel.appendLine(testOutput); - } else { - leftOver += s; - } - }); - proc.stderr.on('data', chunk => errChunks.push(chunk)); + const outBuf = new LineBuffer(); + const errBuf = new LineBuffer(); + + outBuf.onLine(line => outputChannel.appendLine(expandFilePathInOutput(line, testconfig.dir))); + outBuf.onDone(last => last && outputChannel.appendLine(expandFilePathInOutput(last, testconfig.dir))); + + errBuf.onLine(line => outputChannel.appendLine(line)); + errBuf.onDone(last => last && outputChannel.appendLine(last)); + + proc.stdout.on('data', chunk => outBuf.append(chunk.toString())); + proc.stderr.on('data', chunk => errBuf.append(chunk.toString())); + proc.on('close', code => { - if (errChunks.length) { - outputChannel.append(errChunks.toString()); - } + outBuf.done(); + errBuf.done(); + if (code) { outputChannel.appendLine('Error: Tests failed.'); } else { diff --git a/src/util.ts b/src/util.ts index 80d9d9ffd..a8b30ad55 100644 --- a/src/util.ts +++ b/src/util.ts @@ -306,4 +306,43 @@ export function getExtensionCommands(): any[] { } let extensionCommands: any[] = vscode.extensions.getExtension(extensionId).packageJSON.contributes.commands.filter(x => x.command !== 'go.show.commands'); return extensionCommands; -} \ No newline at end of file +} + +export class LineBuffer { + private buf: string = ''; + private lineListeners: { (line: string): void; }[] = []; + private lastListeners: { (last: string): void; }[] = []; + + append(chunk: string) { + this.buf += chunk; + do { + const idx = this.buf.indexOf('\n'); + if (idx === -1) { + break; + } + + this.fireLine(this.buf.substring(0, idx)); + this.buf = this.buf.substring(idx + 1); + } while (true); + } + + done() { + this.fireDone(this.buf !== '' ? this.buf : null); + } + + private fireLine(line: string) { + this.lineListeners.forEach(listener => listener(line)); + } + + private fireDone(last: string) { + this.lastListeners.forEach(listener => listener(last)); + } + + onLine(listener: (line: string) => void) { + this.lineListeners.push(listener); + } + + onDone(listener: (last: string) => void) { + this.lastListeners.push(listener); + } +}