diff --git a/src/editor/commands.ts b/src/editor/commands.ts index 23860741..80adfe7b 100644 --- a/src/editor/commands.ts +++ b/src/editor/commands.ts @@ -61,7 +61,7 @@ export const createCommands = ({ extensionPath, workspaceState, workspaceRoot }: }, onFail: (payload: Payload, message: string) => { // send test fail message back to client - vscode.window.showWarningMessage(`FAIL: ${message}`) + vscode.window.showWarningMessage(`FAIL ${message}`) webview.send({ type: 'TEST_FAIL', payload }) }, onError: (payload: Payload) => { diff --git a/src/services/testRunner/index.ts b/src/services/testRunner/index.ts index 6d8ecb72..3453491a 100644 --- a/src/services/testRunner/index.ts +++ b/src/services/testRunner/index.ts @@ -1,7 +1,7 @@ import node from '../../services/node' import { getOutputChannel } from '../../editor/outputChannel' import parser from './parser' -import { setLatestProcess, isLatestProcess } from './throttle' +// import { setLatestProcess, isLatestProcess } from './throttle' export interface Payload { stepId: string @@ -22,7 +22,7 @@ const createTestRunner = (config: TestRunnerConfig, callbacks: Callbacks) => { const outputChannelName = 'TEST_OUTPUT' return async (payload: Payload, onSuccess?: () => void): Promise => { - console.log('------------------- run test ------------------') + console.log('------------------- RUN TEST -------------------') // flag as running callbacks.onRun(payload) @@ -31,41 +31,36 @@ const createTestRunner = (config: TestRunnerConfig, callbacks: Callbacks) => { try { result = await node.exec(config.command) } catch (err) { - result = err + result = { stdout: err.stdout, stderr: err.stack } } const { stdout, stderr } = result - // simple way to throttle requests - if (!stdout) { - return - } - + const tap = parser(stdout || '') if (stderr) { - callbacks.onError(payload) - - // open terminal with error string - const channel = getOutputChannel(outputChannelName) - channel.show(false) - channel.appendLine(stderr) - return + // failures also trigger stderr + if (stdout && stdout.length && !tap.ok) { + const message = tap.message ? tap.message : '' + callbacks.onFail(payload, message) + return + } else { + callbacks.onError(payload) + // open terminal with error string + const channel = getOutputChannel(outputChannelName) + channel.show(false) + channel.appendLine(stderr) + return + } } - // pass or fail? - const tap = parser(stdout) + // success! if (tap.ok) { callbacks.onSuccess(payload) if (onSuccess) { onSuccess() } } else { - // TODO: consider logging output to channel - // open terminal with failed test string - // const channel = getOutputChannel(outputChannelName) - // channel.show(false) - // channel.appendLine(tap.message) - - const message = tap.message ? tap.message : '' - callbacks.onFail(payload, message) + // should never get here + callbacks.onError(payload) } } } diff --git a/src/services/testRunner/parser.test.ts b/src/services/testRunner/parser.test.ts index 260786df..2ff13afd 100644 --- a/src/services/testRunner/parser.test.ts +++ b/src/services/testRunner/parser.test.ts @@ -15,6 +15,17 @@ ok 2 - Should also pass ok 1 - Should pass not ok 2 - This one fails ok 3 - Also passes +` + expect(parser(example).ok).toBe(false) + }) + test('should detect failure if no tests passed', () => { + const example = ` +# Starting... +# 1 test suites found. + +# FAIL __tests__/sum.test.js + +not ok 1 ● sum › should add two numbers together ` expect(parser(example).ok).toBe(false) }) diff --git a/src/services/testRunner/parser.ts b/src/services/testRunner/parser.ts index f77ce10c..63dd8eed 100644 --- a/src/services/testRunner/parser.ts +++ b/src/services/testRunner/parser.ts @@ -3,16 +3,27 @@ interface ParserOutput { message?: string } +const fail = /^not ok \d+ .{1} (.+)+$/ +const ok = /^ok \d+ .{1} / + const parser = (text: string): ParserOutput => { const lines = text.split('\n') + let hasPass = false for (const line of lines) { - // parse failed test - const match = line.match(/^not ok \d+ - (.+)+/) - if (!!match) { - return { ok: false, message: match[1] } + if (line.length) { + // parse failed test + const failRegex = fail.exec(line) + if (!!failRegex) { + return { ok: false, message: failRegex[1] } + } + if (!hasPass) { + if (!!ok.exec(line)) { + hasPass = true + } + } } } - return { ok: true } + return { ok: hasPass } } export default parser