From 5abcf82eca129ef337c8fc9a6a41f305d3d93bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Zu=CC=88hlke?= Date: Wed, 19 Apr 2023 01:02:25 +0200 Subject: [PATCH] Handle a StackOverflowError in addition to NonFatal errors if they are happening inside a test I only execute the test on the JVM, because - on JS the error message is different - on Native the runner just terminates --- .../src/main/scala/munit/MUnitRunner.scala | 32 +++++++++++-------- .../scala/munit/Issue583FrameworkSuite.scala | 25 +++++++++++++++ .../src/test/scala/munit/FrameworkSuite.scala | 1 + 3 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 tests/shared/src/main/scala/munit/Issue583FrameworkSuite.scala diff --git a/munit/shared/src/main/scala/munit/MUnitRunner.scala b/munit/shared/src/main/scala/munit/MUnitRunner.scala index 9a2bd48a..a438577d 100644 --- a/munit/shared/src/main/scala/munit/MUnitRunner.scala +++ b/munit/shared/src/main/scala/munit/MUnitRunner.scala @@ -285,25 +285,31 @@ class MUnitRunner(val cls: Class[_ <: Suite], newInstance: () => Suite) } notifier.fireTestStarted(description) + def handleNonFatalOrStackOverflow(ex: Throwable): Future[Unit] = { + trimStackTrace(ex) + val cause = Exceptions.rootCause(ex) + val failure = new Failure(description, cause) + cause match { + case _: AssumptionViolatedException => + notifier.fireTestAssumptionFailed(failure) + case _: FailSuiteException => + suiteAborted = true + notifier.fireTestFailure(failure) + case _ => + notifier.fireTestFailure(failure) + } + Future.successful(()) + } + val onError: PartialFunction[Throwable, Future[Unit]] = { case ex: AssumptionViolatedException => trimStackTrace(ex) notifier.fireTestAssumptionFailed(new Failure(description, ex)) Future.successful(()) case NonFatal(ex) => - trimStackTrace(ex) - val cause = Exceptions.rootCause(ex) - val failure = new Failure(description, cause) - cause match { - case _: AssumptionViolatedException => - notifier.fireTestAssumptionFailed(failure) - case _: FailSuiteException => - suiteAborted = true - notifier.fireTestFailure(failure) - case _ => - notifier.fireTestFailure(failure) - } - Future.successful(()) + handleNonFatalOrStackOverflow(ex) + case ex: StackOverflowError => + handleNonFatalOrStackOverflow(ex) } val result: Future[Unit] = try runTestBody(notifier, description, test).recoverWith(onError) diff --git a/tests/shared/src/main/scala/munit/Issue583FrameworkSuite.scala b/tests/shared/src/main/scala/munit/Issue583FrameworkSuite.scala new file mode 100644 index 00000000..1fbc3085 --- /dev/null +++ b/tests/shared/src/main/scala/munit/Issue583FrameworkSuite.scala @@ -0,0 +1,25 @@ +package munit + +class Issue583FrameworkSuite extends FunSuite { + test("simple test") { + () + } + test("infinite loop test") { + def loop(x: Int): Int = loop(x) + loop(x) + + loop(0) + } + test("another test") { + () + } +} + +object Issue583FrameworkSuite + extends FrameworkTest( + classOf[Issue583FrameworkSuite], + """|==> success munit.Issue583FrameworkSuite.simple test + |==> failure munit.Issue583FrameworkSuite.infinite loop test - null + |==> success munit.Issue583FrameworkSuite.another test + |""".stripMargin, + tags = Set(OnlyJVM) + ) diff --git a/tests/shared/src/test/scala/munit/FrameworkSuite.scala b/tests/shared/src/test/scala/munit/FrameworkSuite.scala index d91ef2df..e0f1c44f 100644 --- a/tests/shared/src/test/scala/munit/FrameworkSuite.scala +++ b/tests/shared/src/test/scala/munit/FrameworkSuite.scala @@ -30,6 +30,7 @@ class FrameworkSuite extends BaseFrameworkSuite { Issue179FrameworkSuite, Issue285FrameworkSuite, Issue497FrameworkSuite, + Issue583FrameworkSuite, ScalaCheckExceptionFrameworkSuite, BoxedFrameworkSuite, SkippedFrameworkSuite