From e99fe1999c3545da4c4eb97aa84612ac30c5b7ea Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 5 Jun 2022 03:27:10 +0000 Subject: [PATCH] Port tests to JUnit --- build.sbt | 30 +++++--- ...ite.scala => MacrotaskExecutorTests.scala} | 26 ++++--- webworker/src/main/scala/java/io/File.scala | 22 ------ .../MacrotaskExecutorSuiteRunner.scala | 75 ------------------- .../MacrotaskExecutorTestsRunner.scala | 43 +++++++++++ .../WebWorkerMacrotaskSuite.scala | 57 -------------- .../WebWorkerMacrotaskTests.scala | 63 ++++++++++++++++ 7 files changed, 141 insertions(+), 175 deletions(-) rename core/src/test/scala/org/scalajs/macrotaskexecutor/{MacrotaskExecutorSuite.scala => MacrotaskExecutorTests.scala} (73%) delete mode 100644 webworker/src/main/scala/java/io/File.scala delete mode 100644 webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuiteRunner.scala create mode 100644 webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTestsRunner.scala delete mode 100644 webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskSuite.scala create mode 100644 webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskTests.scala diff --git a/build.sbt b/build.sbt index f551212..da51adc 100644 --- a/build.sbt +++ b/build.sbt @@ -24,9 +24,6 @@ import org.scalajs.jsenv.selenium.SeleniumJSEnv import java.util.concurrent.TimeUnit -val MUnitFramework = new TestFramework("munit.Framework") -val MUnitVersion = "0.7.29" - ThisBuild / baseVersion := "1.0" ThisBuild / organization := "org.scala-js" @@ -136,7 +133,7 @@ ThisBuild / Test / jsEnv := { } } -ThisBuild / Test / testOptions += Tests.Argument(MUnitFramework, "+l") +ThisBuild / testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s", "-v") // project structure @@ -148,9 +145,8 @@ lazy val core = project .in(file("core")) .settings( name := "scala-js-macrotask-executor", - libraryDependencies += "org.scalameta" %%% "munit" % MUnitVersion % Test, ) - .enablePlugins(ScalaJSPlugin) + .enablePlugins(ScalaJSPlugin, ScalaJSJUnitPlugin) // this project solely exists for testing purposes lazy val webworker = project @@ -161,9 +157,21 @@ lazy val webworker = project scalaJSUseMainModuleInitializer := true, libraryDependencies ++= Seq( "org.scala-js" %%% "scalajs-dom" % "2.0.0", - "org.scalameta" %%% "munit" % MUnitVersion % Test, ), - (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value, - buildInfoKeys := Seq(scalaVersion, baseDirectory, BuildInfoKey("isBrowser" -> useJSEnv.value.isBrowser)), - buildInfoPackage := "org.scalajs.macrotaskexecutor") - .enablePlugins(ScalaJSPlugin, BuildInfoPlugin, NoPublishPlugin) + (Test / test) := { + if (useJSEnv.value.isBrowser) + (Test / test).dependsOn(Compile / fastOptJS).value + else + () + }, + buildInfoKeys := Seq( + BuildInfoKey( + "workerDir" -> { + val outputDir = (Compile / fastLinkJS / scalaJSLinkerOutputDirectory).value + outputDir.getAbsolutePath() + } + ) + ), + buildInfoPackage := "org.scalajs.macrotaskexecutor", + ) + .enablePlugins(ScalaJSPlugin, ScalaJSJUnitPlugin, BuildInfoPlugin, NoPublishPlugin) diff --git a/core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuite.scala b/core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTests.scala similarity index 73% rename from core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuite.scala rename to core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTests.scala index 1e31239..95a4ff3 100644 --- a/core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuite.scala +++ b/core/src/test/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTests.scala @@ -16,16 +16,18 @@ package org.scalajs.macrotaskexecutor -import munit.FunSuite +import org.junit.Test import scala.concurrent.Future import scala.concurrent.duration._ import scala.scalajs.js +import scala.util.Try -class MacrotaskExecutorSuite extends FunSuite { +class MacrotaskExecutorTests { import MacrotaskExecutor.Implicits._ - test("sequence a series of 10,000 recursive executions without clamping") { + @Test + def `sequence a series of 10,000 recursive executions without clamping` = { def loop(n: Int): Future[Int] = if (n <= 0) Future(0) @@ -39,20 +41,23 @@ class MacrotaskExecutorSuite extends FunSuite { Future { val end = System.currentTimeMillis() - assert(res == 10000) - assert((end - start).toDouble / MinimumClamp < 0.25) // we should beat the clamping by at least 4x even on slow environments + Try { + assert(res == 10000) + assert((end - start).toDouble / MinimumClamp < 0.25) // we should beat the clamping by at least 4x even on slow environments + } } } } // this test fails to terminate with a Promise-based executor - test("preserve fairness with setTimeout") { + @Test + def `preserve fairness with setTimeout` = { var cancel = false - def loop(): Future[Unit] = + def loop(): Future[Try[Unit]] = Future(cancel) flatMap { canceled => if (canceled) - Future.successful(()) + Future.successful(Try(())) else loop() } @@ -64,12 +69,13 @@ class MacrotaskExecutorSuite extends FunSuite { loop() } - test("execute a bunch of stuff in 'parallel' and ensure it all runs") { + @Test + def `execute a bunch of stuff in 'parallel' and ensure it all runs` = { var i = 0 Future.sequence(List.fill(10000)(Future { i += 1 })) flatMap { _ => Future { - assert(i == 10000) + Try(assert(i == 10000)) } } } diff --git a/webworker/src/main/scala/java/io/File.scala b/webworker/src/main/scala/java/io/File.scala deleted file mode 100644 index 1126746..0000000 --- a/webworker/src/main/scala/java/io/File.scala +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2021 Scala.js (https://www.scala-js.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.io - -// hack hack buildinfo hack -class File(path: String) { - override def toString() = path -} diff --git a/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuiteRunner.scala b/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuiteRunner.scala deleted file mode 100644 index dc6cfd0..0000000 --- a/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorSuiteRunner.scala +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2021 Scala.js (https://www.scala-js.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.scalajs.macrotaskexecutor - -import munit.MUnitRunner -import org.junit.runner.Description -import org.junit.runner.notification.Failure -import org.junit.runner.notification.RunNotifier -import org.scalajs.dom.DedicatedWorkerGlobalScope - -import scala.scalajs.js - -object MacrotaskExecutorSuiteRunner { - - def postMessage(msg: js.Any): Unit = - DedicatedWorkerGlobalScope.self.postMessage(msg) - - def main(args: Array[String]): Unit = { - new MUnitRunner( - classOf[MacrotaskExecutorSuite], - () => new MacrotaskExecutorSuite - ).runAsync(new RunNotifier { - - var count = new MacrotaskExecutorSuite().munitTests().size - var overallSuccess = true - def reportTest(success: Boolean): Unit = { - overallSuccess &= success - count -= 1 - if (count == 0) postMessage(overallSuccess) - } - - def fireTestStarted(description: Description): Unit = () - - def fireTestSuiteStarted(description: Description): Unit = - postMessage(s"${classOf[MacrotaskExecutorSuite].getName}:") - - // This doesn't account for async and fires before any tests are run! - def fireTestSuiteFinished(description: Description): Unit = () - - def fireTestIgnored(description: Description): Unit = () - - def fireTestFinished(description: Description): Unit = { - postMessage(s" + ${description.getMethodName}") - reportTest(success = true) - } - - def fireTestFailure(failure: Failure): Unit = { - postMessage( - s"==> X ${classOf[MacrotaskExecutorSuite].getName}.${failure.description.getMethodName}" - ) - reportTest(success = false) - } - - def fireTestAssumptionFailed(failure: Failure): Unit = - reportTest(success = false) - - }) - - () - } -} diff --git a/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTestsRunner.scala b/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTestsRunner.scala new file mode 100644 index 0000000..9c6ce11 --- /dev/null +++ b/webworker/src/main/scala/org/scalajs/macrotaskexecutor/MacrotaskExecutorTestsRunner.scala @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Scala.js (https://www.scala-js.org/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.scalajs.macrotaskexecutor + +import org.scalajs.dom.DedicatedWorkerGlobalScope + +import scala.scalajs.concurrent.QueueExecutionContext.timeouts +import scala.scalajs.js + +object MacrotaskExecutorTestsRunner { + + def main(args: Array[String]): Unit = { + val tests = new MacrotaskExecutorTests + + implicit val ec = timeouts() + + for { + clamping <- tests.`sequence a series of 10,000 recursive executions without clamping` + fairness <- tests.`preserve fairness with setTimeout` + parallel <- tests.`execute a bunch of stuff in 'parallel' and ensure it all runs` + } yield DedicatedWorkerGlobalScope.self.postMessage(js.Dictionary( + "clamping" -> clamping.isSuccess, + "fairness" -> fairness.isSuccess, + "parallel" -> parallel.isSuccess + )) + + () + } +} diff --git a/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskSuite.scala b/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskSuite.scala deleted file mode 100644 index 258bdc0..0000000 --- a/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskSuite.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2021 Scala.js (https://www.scala-js.org/) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.scalajs.macrotaskexecutor - -import munit.FunSuite -import org.scalajs.dom.MessageEvent -import org.scalajs.dom.Worker - -import scala.concurrent.Promise - -class WebWorkerMacrotaskSuite extends FunSuite { - - import MacrotaskExecutor.Implicits._ - - def scalaVersion = if (BuildInfo.scalaVersion.startsWith("2")) - BuildInfo.scalaVersion.split('.').init.mkString(".") - else - BuildInfo.scalaVersion - - def targetDir = s"${BuildInfo.baseDirectory}/target/scala-${scalaVersion}" - - override def munitIgnore = !BuildInfo.isBrowser - - test("pass the MacrotaskSuite in a web worker") { - val p = Promise[Boolean]() - - val worker = new Worker( - s"file://${targetDir}/scala-js-macrotask-executor-webworker-fastopt/main.js" - ) - - worker.onmessage = { (event: MessageEvent) => - event.data match { - case log: String => println(log) - case success: Boolean => p.success(success) - case _ => () - } - } - - p.future.map(assert(_)) - - } - -} diff --git a/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskTests.scala b/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskTests.scala new file mode 100644 index 0000000..90f5912 --- /dev/null +++ b/webworker/src/test/scala/org/scalajs/macrotaskexecutor/WebWorkerMacrotaskTests.scala @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Scala.js (https://www.scala-js.org/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.scalajs.macrotaskexecutor + +import org.junit.Test +import org.scalajs.dom.MessageEvent +import org.scalajs.dom.Worker + +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.scalajs.concurrent.QueueExecutionContext.timeouts +import scala.scalajs.js +import scala.util.Failure +import scala.util.Success +import scala.util.Try + +class WebWorkerMacrotaskTests { + + implicit val ec: ExecutionContext = timeouts() + + val worker = new Worker(s"file://${BuildInfo.workerDir}/main.js") + + val testsResult = Promise[js.Dictionary[Boolean]]() + worker.onmessage = { (event: MessageEvent) => + testsResult.success(event.data.asInstanceOf[js.Dictionary[Boolean]]) + } + + def getTestResult(id: String): Future[Try[Unit]] = + testsResult.future.map { results => + if (results.getOrElse(id, false)) + Success(()) + else + Failure(new AssertionError) + } + + @Test + def `sequence a series of 10,000 recursive executions without clamping` = + getTestResult("clamping") + + @Test + def `preserve fairness with setTimeout` = + getTestResult("fairness") + + @Test + def `execute a bunch of stuff in 'parallel' and ensure it all runs` = + getTestResult("parallel") + +}