From 0d7584ffdd20e120ba29232d0f11b85f637c6e22 Mon Sep 17 00:00:00 2001 From: Albert Meltzer Date: Sat, 17 Feb 2024 10:48:06 -0800 Subject: [PATCH] FormatTests: improve idempotency and other errors --- .../test/scala/org/scalafmt/FormatTests.scala | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/scalafmt-tests/src/test/scala/org/scalafmt/FormatTests.scala b/scalafmt-tests/src/test/scala/org/scalafmt/FormatTests.scala index 5a7170940e..f025c00742 100644 --- a/scalafmt-tests/src/test/scala/org/scalafmt/FormatTests.scala +++ b/scalafmt-tests/src/test/scala/org/scalafmt/FormatTests.scala @@ -3,6 +3,9 @@ package org.scalafmt import java.io.File import munit.FunSuite +import munit.internal.console.AnsiColors +import munit.internal.difflib.Diff + import org.scalafmt.Error.{Incomplete, SearchStateExploded} import org.scalafmt.rewrite.FormatTokensRewrite import org.scalafmt.sysops.FileOps @@ -45,19 +48,22 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { filename = t.filename ) debug.printTest() - val obtained = result.formatted match { - case Formatted.Failure(e) - if t.style.onTestFailure.nonEmpty && - e.getMessage.contains(t.style.onTestFailure) => - t.expected - case Formatted.Failure(e: Incomplete) => e.formattedCode - case Formatted.Failure(e: SearchStateExploded) => - logger.elem(e) - e.partialOutput - case Formatted.Failure(e) => throw FormatException(e, t.original) - case Formatted.Success(code) => code + val resultEither = result.formatted.toEither + val err = t.style.onTestFailure + val obtained = resultEither match { + case Left(e) if err.nonEmpty && e.getMessage.contains(err) => t.expected + case Left(e: Incomplete) => e.formattedCode + case Left(e: SearchStateExploded) => logger.elem(e); e.partialOutput + case Left(e) => throw FormatException(e, t.original) + case Right(code) => code } + def assertObtained(implicit loc: munit.Location) = + assertEquals(obtained, t.expected) debugResults += saveResult(t, obtained, debug) + if (resultEither.isLeft) { + assertObtained + return + } val debug2 = new Debug(onlyOne) val result2 = Scalafmt.formatCode( obtained, @@ -66,21 +72,30 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { ) debug2.printTest() val result2Either = result2.formatted.toEither - def getFormattedAgain(failOK: Boolean) = result2Either match { - case Left(e: ParseException) if !failOK => - "test does not parse: " + parseException2Message(e, obtained) + result2Either match { + case Left(e: ParseException) if !onlyManual => + assertEquals( + "test does not parse: " + parseException2Message(e, obtained), + t.expected + ) case Left(e) => throw FormatException(e, obtained) - case Right(code) => code - } - val formattedAgain = getFormattedAgain(onlyManual) - if (onlyManual) - assertEquals(formattedAgain, obtained, "Idempotency violated") - else { - assertEquals( - if (formattedAgain == obtained || result2Either.isLeft) formattedAgain - else "Idempotency violated\n" + formattedAgain, - t.expected - ) + case Right(code) => + if (onlyManual) { + assertEquals(code, obtained, "Idempotency violated") + assertObtained + } else if (code == obtained) + assertObtained + else { + val diff = new Diff(code, obtained) + if (diff.isEmpty) assertObtained + else { + val report = AnsiColors.filterAnsi(diff.createDiffOnlyReport()) + val eol = if (report.last == '\n') "" else "\n" + val error = "Idempotency violated\n" + report + eol + if (error != t.expected) + failComparison(error, code, obtained) + } + } } if ( result2Either.isRight && @@ -88,7 +103,7 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { FormatTokensRewrite.getEnabledFactories(t.style).isEmpty && !t.style.assumeStandardLibraryStripMargin && !FileOps.isMarkdown(t.filename) && - t.style.onTestFailure.isEmpty + err.isEmpty ) assertFormatPreservesAst( t.filename,