From a8870ecc937385e5d26b71f4ea27f2410a11e9ff Mon Sep 17 00:00:00 2001 From: Sebastian Aas Date: Thu, 26 Dec 2024 16:36:35 +0100 Subject: [PATCH] #1007: show diff between expected and actual in test runner --- CHANGELOG.md | 4 ++- src/extension-test/unit/test-runner-test.ts | 31 ++++++++++++++++++++ src/nrepl/cider.ts | 32 +++++++++++++++++++++ src/testRunner.ts | 2 ++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5c75dfc..c67d7e2ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Changes to Calva. ## [Unreleased] +- Fix: [Have test runner show diff between "actual" and "expected"](https://github.com/BetterThanTomorrow/calva/issues/1007) + ## [2.0.483] - 2025-01-08 - Fix: [Paredit garbles while backspacing rapidly](https://github.com/BetterThanTomorrow/calva/issues/2611) @@ -12,7 +14,7 @@ Changes to Calva. ## [2.0.482] - 2024-12-03 -- Fix: [Added 'replace-refer-all-with-alias' & 'replace-refer-all-with-refer' actions to calva.](https://github.com/BetterThanTomorrow/calva/issues/2667) +- Fix: [Added 'replace-refer-all-with-alias' & 'replace-refer-all-with-refer' actions to calva.](https://github.com/BetterThanTomorrow/calva/issues/2667) ## [2.0.481] - 2024-10-29 diff --git a/src/extension-test/unit/test-runner-test.ts b/src/extension-test/unit/test-runner-test.ts index 714649f90..3c7a6018b 100644 --- a/src/extension-test/unit/test-runner-test.ts +++ b/src/extension-test/unit/test-runner-test.ts @@ -167,4 +167,35 @@ orange` apple` ); }); + + it('can produce detailed messages with diffs', () => { + expect( + cider.detailedMessage({ + type: 'fail', + ns: 'core', + context: 'ctx', + index: 2, + expected: '{:key1 "value1", :key2 "value2"}', + actual: '{:key1 "wrongValue", :key2 "value2"}', + var: 'test', + file: 'core.clj', + line: 10, + message: 'Values do not match', + diffs: [ + [ + '{:key1 "wrongValue", :key2 "value2"}', + ['{:key1 "value1", :key2 "value2"}', '{:key1 "wrongValue"}'], + ], + ], + }) + ).toBe(`; FAIL in core/test (core.clj:10): +; ctx: Values do not match +; expected: +{:key1 "value1", :key2 "value2"} +; actual: +{:key1 "wrongValue", :key2 "value2"} +; diff: +- {:key1 "value1", :key2 "value2"} ++ {:key1 "wrongValue"}`); + }); }); diff --git a/src/nrepl/cider.ts b/src/nrepl/cider.ts index 5c0e23a0c..d29488e79 100644 --- a/src/nrepl/cider.ts +++ b/src/nrepl/cider.ts @@ -142,6 +142,33 @@ export function lineInformation(result: TestResult): string { return ` (${result.file}:${result.line})`; } +function getDiffMessages(result: TestResult): string[] { + const diffs = result.diffs; + const messages: string[] = []; + + if (!diffs || !Array.isArray(diffs) || diffs.length === 0) { + return messages; + } + + diffs.forEach((diffPair: [string, [string, string]]) => { + if (Array.isArray(diffPair) && diffPair.length === 2) { + const [_, [removed, added]] = diffPair; + + if (removed || added) { + messages.push('; diff:'); + messages.push(removed ? `- ${removed}` : ''); + if (added) { + messages.push(`+ ${added}`); + } + } + } else { + console.warn('Invalid diff pair format:', diffPair); + } + }); + + return messages; +} + // Return a detailed message about why a test failed. // If the test passed, return the empty string. // The message contains "comment" lines that are prepended with ; @@ -173,6 +200,11 @@ export function detailedMessage(result: TestResult): string | undefined { if (result.actual) { messages.push(`; actual:\n${result.actual}`); } + + const diffMessages = getDiffMessages(result); + if (diffMessages.length > 0) { + messages.push(...diffMessages); + } } return messages.length > 0 ? messages.join('\n') : undefined; } diff --git a/src/testRunner.ts b/src/testRunner.ts index a929ca1b9..d71e94d44 100644 --- a/src/testRunner.ts +++ b/src/testRunner.ts @@ -139,6 +139,8 @@ async function onTestResult( run.errored(assertion, new vscode.TestMessage(cider.shortMessage(result))); break; case 'fail': + run.failed(assertion, new vscode.TestMessage(cider.detailedMessage(result))); + break; default: run.failed(assertion, new vscode.TestMessage(cider.shortMessage(result))); break;