Skip to content

Commit

Permalink
Add reproduction for #285
Browse files Browse the repository at this point in the history
The bug appears to be fixed with the recent changes to async fixtures.
  • Loading branch information
olafurpg committed Oct 16, 2021
1 parent 11ee9d1 commit b462569
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 6 deletions.
13 changes: 9 additions & 4 deletions munit/js/src/main/scala/munit/internal/PlatformCompat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import sbt.testing.Logger
import scala.concurrent.Promise
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext
import scala.scalajs.js.timers.clearTimeout
import scala.scalajs.js.timers.setTimeout
import scala.scalajs.js.timers
import java.util.concurrent.TimeoutException

object PlatformCompat {
Expand All @@ -31,7 +30,7 @@ object PlatformCompat {
ec: ExecutionContext
): Future[T] = {
val onComplete = Promise[T]()
val timeoutHandle = setTimeout(duration.toMillis) {
val timeoutHandle = timers.setTimeout(duration.toMillis) {
onComplete.tryFailure(
new TimeoutException(s"test timed out after $duration")
)
Expand All @@ -40,13 +39,19 @@ object PlatformCompat {
def run(): Unit = {
startFuture().onComplete { result =>
onComplete.tryComplete(result)
clearTimeout(timeoutHandle)
timers.clearTimeout(timeoutHandle)
}(ec)
}
})
onComplete.future
}

def setTimeout(ms: Int)(body: => Unit): () => Unit = {
val timeoutHandle = timers.setTimeout(ms)(body)

() => timers.clearTimeout(timeoutHandle)
}

// Scala.js does not support looking up annotations at runtime.
def isIgnoreSuite(cls: Class[_]): Boolean = false

Expand Down
10 changes: 10 additions & 0 deletions munit/jvm/src/main/scala/munit/internal/PlatformCompat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ object PlatformCompat {
onComplete.future
}

def setTimeout(ms: Int)(body: => Unit): () => Unit = {
val scheduled = sh.schedule[Unit](
() => body,
ms,
TimeUnit.MILLISECONDS
)

() => scheduled.cancel(false)
}

def isIgnoreSuite(cls: Class[_]): Boolean =
cls.getAnnotationsByType(classOf[munit.IgnoreSuite]).nonEmpty
def isJVM: Boolean = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ object PlatformCompat {
): Future[T] = {
startFuture()
}
def setTimeout(ms: Int)(body: => Unit): () => Unit = {
Thread.sleep(ms)
body

() => ()
}

// Scala Native does not support looking up annotations at runtime.
def isIgnoreSuite(cls: Class[_]): Boolean = false
Expand Down
62 changes: 62 additions & 0 deletions tests/shared/src/main/scala/munit/Issue285FrameworkSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package munit

import scala.concurrent.duration.Duration
import munit.internal.PlatformCompat
import scala.concurrent.Promise

class Issue285FrameworkSuite extends FunSuite {
def println(msg: String): Unit = TestingConsole.out.println(msg)
val hello: Fixture[Unit] = new Fixture[Unit]("hello") {
def apply(): Unit = ()
override def beforeAll(): Unit = {
println("beforeAll")
}
override def beforeEach(context: BeforeEach): Unit = {
println("beforeEach - " + context.test.name)
}
override def afterEach(context: AfterEach): Unit = {
println("afterEach - " + context.test.name)
}
override def afterAll(): Unit = {
println("afterAll")
}
}
override def munitFixtures: List[Fixture[Unit]] = List(hello)
override def munitTimeout: Duration = Duration(1, "ms")
test("issue-285-ok") {
()
}
test("issue-285-fail") {
val promise = Promise[Unit]()
PlatformCompat.setTimeout(3) {
promise.trySuccess(())
}
promise.future
}
test("issue-285-ok") {
()
}
}

object Issue285FrameworkSuite
extends FrameworkTest(
classOf[Issue285FrameworkSuite],
"""|munit.Issue285FrameworkSuite:
|beforeAll
|beforeEach - issue-285-ok
|afterEach - issue-285-ok
| + issue-285-ok <elapsed time>
|beforeEach - issue-285-fail
|afterEach - issue-285-fail
|==> X munit.Issue285FrameworkSuite.issue-285-fail <elapsed time>java.util.concurrent.TimeoutException: test timed out after 1 millisecond
|beforeEach - issue-285-ok
|afterEach - issue-285-ok
| + issue-285-ok-1 <elapsed time>
|afterAll
|""".stripMargin,
tags = Set(
// Skipped on Native because we don't support `PlatformCompat.setTimeout`
NoNative
),
format = StdoutFormat
)
3 changes: 2 additions & 1 deletion tests/shared/src/main/scala/munit/Tags.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package munit

object OnlyJVM extends Tag("OnlyJVm") {}
object OnlyJVM extends Tag("OnlyJVM") {}
object NoDotty extends Tag("NoDotty") {}
object Only213 extends Tag("Only213") {}
object NoNative extends Tag("NoNative") {}
2 changes: 1 addition & 1 deletion tests/shared/src/test/scala/munit/BaseFrameworkSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ abstract class BaseFrameworkSuite extends BaseSuite {
}
implicit val ec = munitExecutionContext
val elapsedTimePattern =
Pattern.compile(" \\d+\\.\\d+s$", Pattern.MULTILINE)
Pattern.compile(" \\d+\\.\\d+s ?", Pattern.MULTILINE)
TestingConsole.out = out
TestingConsole.err = out
for {
Expand Down
2 changes: 2 additions & 0 deletions tests/shared/src/test/scala/munit/BaseSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class BaseSuite extends FunSuite {
test.tag(Ignore)
} else if (test.tags(OnlyJVM) && !PlatformCompat.isJVM) {
test.tag(Ignore)
} else if (test.tags(NoNative) && PlatformCompat.isNative) {
test.tag(Ignore)
} else {
test
}
Expand Down
1 change: 1 addition & 0 deletions tests/shared/src/test/scala/munit/FrameworkSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class FrameworkSuite extends BaseFrameworkSuite {
SmallStackTraceFrameworkSuite,
AssertionsFrameworkSuite,
Issue179FrameworkSuite,
Issue285FrameworkSuite,
ScalaCheckExceptionFrameworkSuite,
BoxedFrameworkSuite
)
Expand Down

0 comments on commit b462569

Please sign in to comment.