diff --git a/CHANGELOG.md b/CHANGELOG.md index 209524127..6881c05f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Changes to Calva. - [A more flexible evaluate-to-cursor command](https://github.com/BetterThanTomorrow/calva/ issues/1901) +- [Test runner does not show stacktrace on error](https://github.com/BetterThanTomorrow/calva/issues/424) ## [2.0.307] - 2022-10-11 diff --git a/src/nrepl/index.ts b/src/nrepl/index.ts index 945ebc85b..395a63287 100644 --- a/src/nrepl/index.ts +++ b/src/nrepl/index.ts @@ -515,6 +515,24 @@ export class NReplSession { }); } + testStacktrace(ns: string, test: string, index: number) { + return new Promise((resolve, reject) => { + const id = this.client.nextId; + this.messageHandlers[id] = (msg) => { + resolve(msg); + return true; + }; + this.client.write({ + op: 'test-stacktrace', + id, + session: this.sessionId, + ns, + var: test, + index: index, + }); + }); + } + testNs(ns: string) { return this.testVarQuery({ 'ns-query': { diff --git a/src/testRunner.ts b/src/testRunner.ts index 0c3195d63..d86db5d24 100644 --- a/src/testRunner.ts +++ b/src/testRunner.ts @@ -168,7 +168,7 @@ function useTestExplorer(): boolean | undefined { return vscode.workspace.getConfiguration('calva').get('useTestExplorer'); } -function reportTests( +async function reportTests( controller: vscode.TestController, session: NReplSession, possibleResults: cider.TestResults[] @@ -208,7 +208,15 @@ function reportTests( cider.cleanUpWhiteSpace(a); const messages = cider.detailedMessage(a); - if (messages) { + + if (a.type == 'error') { + const stackTrace = await session.testStacktrace(ns, test, a.index); + + outputWindow.saveStacktrace(stackTrace.stacktrace); + outputWindow.append(messages, (_, afterResultLocation) => { + outputWindow.markLastStacktraceRange(afterResultLocation); + }); + } else if (messages) { outputWindow.append(messages); } @@ -237,7 +245,7 @@ async function runAllTests(controller: vscode.TestController, document = {}) { const session = getSession(util.getFileType(document)); outputWindow.append('; Running all project tests…'); try { - reportTests(controller, session, [await session.testAll()]); + await reportTests(controller, session, [await session.testAll()]); } catch (e) { outputWindow.append('; ' + e); } @@ -298,7 +306,7 @@ async function runNamespaceTestsImpl( return session.testNs(ns); }); try { - reportTests(controller, session, await Promise.all(resultPromises)); + await reportTests(controller, session, await Promise.all(resultPromises)); } catch (e) { outputWindow.append('; ' + e); } @@ -335,7 +343,7 @@ async function runTestUnderCursor(controller: vscode.TestController) { if (test) { outputWindow.append(`; Running test: ${test}…`); try { - reportTests(controller, session, [await session.test(ns, test)]); + await reportTests(controller, session, [await session.test(ns, test)]); } catch (e) { outputWindow.append('; ' + e); } @@ -373,7 +381,7 @@ async function rerunTests(controller: vscode.TestController, document = {}) { const session = getSession(util.getFileType(document)); outputWindow.append('; Running previously failed tests…'); try { - reportTests(controller, session, [await session.retest()]); + await reportTests(controller, session, [await session.retest()]); } catch (e) { outputWindow.append('; ' + e); }