From 44ed8273b7f139e13e7a6eb0b18ecaba566529b8 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Tue, 27 Jul 2021 04:06:27 +0000 Subject: [PATCH 1/7] Towards webworker tests --- .github/workflows/ci.yml | 5 ++ build.sbt | 87 +++++++++++++------ .../main/scala/cats/effect/IOSpecRunner.scala | 43 +++++++++ .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 +++++ .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 +++++ .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 +++++ .../scala/cats/effect/WebWorkerIOSpec.scala | 41 +++++++++ 7 files changed, 212 insertions(+), 27 deletions(-) create mode 100644 webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala create mode 100644 webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala create mode 100644 webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala create mode 100644 webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala create mode 100644 webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b5523c5fa..95af1eb851 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,6 +91,11 @@ jobs: with: node-version: 14 + - name: Start static file server + if: matrix.ci == 'ciFirefox' + shell: bash + run: python3 -m http.server & + - name: Check that workflows are up to date shell: bash run: sbt --client '++${{ matrix.scala }}; githubWorkflowCheck' diff --git a/build.sbt b/build.sbt index 220ac30514..7fa173fff1 100644 --- a/build.sbt +++ b/build.sbt @@ -59,18 +59,25 @@ val GraalVM8 = "graalvm-ce-java8@21.1" ThisBuild / githubWorkflowJavaVersions := Seq(ScalaJSJava, LTSJava, LatestJava, GraalVM8) ThisBuild / githubWorkflowOSes := Seq(PrimaryOS, Windows) -ThisBuild / githubWorkflowBuildPreamble += - WorkflowStep.Use( - UseRef.Public("actions", "setup-node", "v2.1.2"), - name = Some("Setup NodeJS v14 LTS"), - params = Map("node-version" -> "14"), - cond = Some("matrix.ci == 'ciJS'")) +ThisBuild / githubWorkflowBuildPreamble ++= + Seq( + WorkflowStep.Use( + UseRef.Public("actions", "setup-node", "v2.1.2"), + name = Some("Setup NodeJS v14 LTS"), + params = Map("node-version" -> "14"), + cond = Some("matrix.ci == 'ciJS'")), + WorkflowStep.Run( + List("python3 -m http.server &"), + name = Some("Start static file server"), + cond = Some("matrix.ci == 'ciFirefox'")) + ) ThisBuild / githubWorkflowBuild := Seq( WorkflowStep.Sbt(List("${{ matrix.ci }}")), WorkflowStep.Sbt( List("docs/mdoc"), - cond = Some(s"(matrix.scala == '$Scala213' || matrix.scala == '$Scala3') && matrix.ci == 'ciJVM'")), + cond = Some( + s"(matrix.scala == '$Scala213' || matrix.scala == '$Scala3') && matrix.ci == 'ciJVM'")), WorkflowStep.Sbt( List("exampleJVM/compile"), cond = Some(s"matrix.ci == 'ciJVM' && matrix.os == '$PrimaryOS'")), @@ -129,6 +136,7 @@ ThisBuild / Test / jsEnv := { if (useFirefoxEnv.value) { val options = new FirefoxOptions() + // options.getProfile().set ??? options.addArguments("-headless") new SeleniumJSEnv(options) } else { @@ -172,7 +180,16 @@ addCommandAlias( addCommandAlias("prePR", "; root/clean; +root/scalafmtAll; +root/headerCreate") val jsProjects: Seq[ProjectReference] = - Seq(kernel.js, kernelTestkit.js, laws.js, core.js, testkit.js, tests.js, std.js, example.js) + Seq( + kernel.js, + kernelTestkit.js, + laws.js, + core.js, + testkit.js, + tests.js, + webWorkerTests, + std.js, + example.js) val undocumentedRefs = jsProjects ++ Seq[ProjectReference](benchmarks, example.jvm) @@ -222,14 +239,14 @@ lazy val kernel = crossProject(JSPlatform, JVMPlatform) name := "cats-effect-kernel", libraryDependencies ++= Seq( ("org.specs2" %%% "specs2-core" % Specs2Version % Test).cross(CrossVersion.for3Use2_13), - "org.typelevel" %%% "cats-core" % CatsVersion)) - .jsSettings( - Compile / doc / sources := { - if (isDotty.value) - Seq() - else - (Compile / doc / sources).value - }) + "org.typelevel" %%% "cats-core" % CatsVersion) + ) + .jsSettings(Compile / doc / sources := { + if (isDotty.value) + Seq() + else + (Compile / doc / sources).value + }) /** * Reference implementations (including a pure ConcurrentBracket), generic ScalaCheck @@ -278,16 +295,21 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) ProblemFilters.exclude[MissingClassProblem]("cats.effect.AsyncPropagateCancelation$"), // introduced by #1913, striped fiber callback hashtable, changes to package private code ProblemFilters.exclude[MissingClassProblem]("cats.effect.unsafe.FiberErrorHashtable"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("cats.effect.unsafe.IORuntime.fiberErrorCbs"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "cats.effect.unsafe.IORuntime.fiberErrorCbs"), ProblemFilters.exclude[IncompatibleMethTypeProblem]("cats.effect.unsafe.IORuntime.this"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("cats.effect.unsafe.IORuntime.$default$6"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "cats.effect.unsafe.IORuntime.$default$6"), // introduced by #1928, wake up a worker thread before spawning a helper thread when blocking // changes to `cats.effect.unsafe` package private code - ProblemFilters.exclude[IncompatibleResultTypeProblem]("cats.effect.unsafe.WorkStealingThreadPool.notifyParked"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]( + "cats.effect.unsafe.WorkStealingThreadPool.notifyParked"), // introduced by #2041, Rewrite and improve `ThreadSafeHashtable` // changes to `cats.effect.unsafe` package private code - ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.unsafe.ThreadSafeHashtable.hashtable"), - ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.unsafe.ThreadSafeHashtable.hashtable_="), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "cats.effect.unsafe.ThreadSafeHashtable.hashtable"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "cats.effect.unsafe.ThreadSafeHashtable.hashtable_="), // introduced by #2051, Tracing // changes to package private code ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#Blocking.apply"), @@ -299,7 +321,8 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#FlatMap.apply"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#FlatMap.copy"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#FlatMap.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#HandleErrorWith.apply"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "cats.effect.IO#HandleErrorWith.apply"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#HandleErrorWith.copy"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#HandleErrorWith.this"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#Map.apply"), @@ -312,7 +335,9 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) ProblemFilters.exclude[MissingClassProblem]("cats.effect.SyncIO$Delay"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#IOCont.apply"), ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#IOCont.copy"), - ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#IOCont.this"))) + ProblemFilters.exclude[DirectMissingMethodProblem]("cats.effect.IO#IOCont.this") + ) + ) .jvmSettings( javacOptions ++= Seq("-source", "1.8", "-target", "1.8") ) @@ -345,6 +370,17 @@ lazy val tests = crossProject(JSPlatform, JVMPlatform) Test / fork := true, Test / javaOptions += s"-Dsbt.classpath=${(Test / fullClasspath).value.map(_.data.getAbsolutePath).mkString(File.pathSeparator)}") +lazy val webWorkerTests = project + .in(file("webworker-tests")) + .dependsOn(tests.js % "compile->test") + .enablePlugins(ScalaJSPlugin, NoPublishPlugin) + .settings( + name := "cats-effect-webworker-tests", + scalaJSUseMainModuleInitializer := true, + libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "1.1.0", + (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value + ) + /** * Implementations lof standard functionality (e.g. Semaphore, Console, Queue) * purely in terms of the typeclasses, with no dependency on IO. In most cases, @@ -388,7 +424,4 @@ lazy val benchmarks = project .settings(name := "cats-effect-benchmarks") .enablePlugins(NoPublishPlugin, JmhPlugin) -lazy val docs = project - .in(file("site-docs")) - .dependsOn(core.jvm) - .enablePlugins(MdocPlugin) +lazy val docs = project.in(file("site-docs")).dependsOn(core.jvm).enablePlugins(MdocPlugin) diff --git a/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala b/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala new file mode 100644 index 0000000000..d609aa9c8c --- /dev/null +++ b/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala @@ -0,0 +1,43 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 cats.effect + +import org.scalajs.dom.webworkers.DedicatedWorkerGlobalScope +import org.specs2.runner.ClassRunner +import org.specs2.specification.core.Env +import org.specs2.runner.Runner +import org.specs2.control.ExecuteActions +import org.specs2.reporter.LineLogger + +object IOSpecRunner extends IOApp.Simple with ClassRunner { + + override def run: IO[Unit] = IO.fromFuture { + IO { + val spec = new IOSpec + val env = Env(lineLogger = LineLogger.consoleLogger) + val loader = new ClassLoader() {} + val action = for { + printers <- createPrinters(env.arguments, loader).toAction + stats <- Runner.runSpecStructure(spec.structure(env), env, loader, printers) + // TODO I have no idea how to suspend effects in this + _ = DedicatedWorkerGlobalScope.self.postMessage(stats.isSuccess) + } yield () + ExecuteActions.runActionFuture(action)(env.executionEnv) + } + } + +} diff --git a/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala new file mode 100644 index 0000000000..8062c8257e --- /dev/null +++ b/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 cats.effect + +trait WebWorkerIOSpecPlatform { + val scalaVersion = "2.12" +} diff --git a/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala new file mode 100644 index 0000000000..54e8c6cbda --- /dev/null +++ b/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 cats.effect + +trait WebWorkerIOSpecPlatform { + val scalaVersion = "2.13" +} diff --git a/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala new file mode 100644 index 0000000000..5a335d8869 --- /dev/null +++ b/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 cats.effect + +trait WebWorkerIOSpecPlatform { + val scalaVersion = "3" +} diff --git a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala new file mode 100644 index 0000000000..5d08e5c222 --- /dev/null +++ b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala @@ -0,0 +1,41 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 cats.effect + +import cats.syntax.all._ +import org.scalajs.dom.window +import org.scalajs.dom.webworkers.Worker + +import scala.util.Try + +class WebWorkerIOSpec extends BaseSpec with WebWorkerIOSpecPlatform { + + Try(window).toOption.foreach { _ => + "io on webworker" should { + "pass the spec" in ticked { implicit ticker => + IO(new Worker( + s"http://localhost:8000/webworker-tests/target/scala-${scalaVersion}/cats-effect-webworker-tests-fastopt/main.js")) + .flatMap { worker => + IO.async_[Boolean] { cb => + worker.onmessage = { event => cb(Right(event.data.asInstanceOf[Boolean])) } + } + }.attempt.flatTap(IO.println).rethrow must completeAs(true) + } + } + } + +} From 1ef70a47b676c65b11a7b0b4527f7b97f730c817 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Tue, 27 Jul 2021 03:01:53 -0700 Subject: [PATCH 2/7] CrossVersion.for3Use2_13 for scala-js-dom --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7fa173fff1..04b28d3848 100644 --- a/build.sbt +++ b/build.sbt @@ -377,7 +377,7 @@ lazy val webWorkerTests = project .settings( name := "cats-effect-webworker-tests", scalaJSUseMainModuleInitializer := true, - libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "1.1.0", + libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").cross(CrossVersion.for3Use2_13), (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value ) From 3450bab6c16cf09ac395afbe0967f3081e14a998 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 00:20:00 +0000 Subject: [PATCH 3/7] Enable webworker tests on ciFirefox --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 04b28d3848..71777027e2 100644 --- a/build.sbt +++ b/build.sbt @@ -174,7 +174,7 @@ addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; te // we do the firefox ci *only* on core because we're only really interested in IO here addCommandAlias( "ciFirefox", - "; set Global / useFirefoxEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useFirefoxEnv := false" + "; set Global / useFirefoxEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; webWorkerTests/test; set Global / useFirefoxEnv := false" ) addCommandAlias("prePR", "; root/clean; +root/scalafmtAll; +root/headerCreate") From 7474f366904de5a0b436ede7c8e50531b24657fd Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 03:46:30 +0000 Subject: [PATCH 4/7] Set Firefox profile --- build.sbt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 71777027e2..192d46f30c 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,4 @@ +import org.openqa.selenium.firefox.FirefoxProfile /* * Copyright 2020-2021 Typelevel * @@ -135,8 +136,10 @@ ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value if (useFirefoxEnv.value) { + val profile = new FirefoxProfile() + profile.setPreference("privacy.file_unique_origin", false) val options = new FirefoxOptions() - // options.getProfile().set ??? + options.setProfile(profile) options.addArguments("-headless") new SeleniumJSEnv(options) } else { From d37e80bd8c304e45060532a2d9e0c80a7f8e9cba Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 05:23:00 +0000 Subject: [PATCH 5/7] Webworker tests are a go! --- build.sbt | 6 ++--- .../main/scala/cats/effect/IOSpecRunner.scala | 20 ++++++++++---- .../scala/cats/effect/WebWorkerIOSpec.scala | 26 ++++++++++++------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/build.sbt b/build.sbt index 192d46f30c..23cb02a4dd 100644 --- a/build.sbt +++ b/build.sbt @@ -136,12 +136,10 @@ ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value if (useFirefoxEnv.value) { - val profile = new FirefoxProfile() - profile.setPreference("privacy.file_unique_origin", false) val options = new FirefoxOptions() - options.setProfile(profile) options.addArguments("-headless") - new SeleniumJSEnv(options) + val config = SeleniumJSEnv.Config().withMaterializeInServer("target/selenium/", "http://localhost:8000/target/selenium/") + new SeleniumJSEnv(options, config) } else { old } diff --git a/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala b/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala index d609aa9c8c..4a187f7f7f 100644 --- a/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala +++ b/webworker-tests/src/main/scala/cats/effect/IOSpecRunner.scala @@ -17,24 +17,34 @@ package cats.effect import org.scalajs.dom.webworkers.DedicatedWorkerGlobalScope +import org.specs2.control.ExecuteActions +import org.specs2.reporter.BufferedLineLogger import org.specs2.runner.ClassRunner -import org.specs2.specification.core.Env import org.specs2.runner.Runner -import org.specs2.control.ExecuteActions -import org.specs2.reporter.LineLogger +import org.specs2.specification.core.Env + +import scala.scalajs.js object IOSpecRunner extends IOApp.Simple with ClassRunner { + def postMessage(msg: js.Any): Unit = DedicatedWorkerGlobalScope.self.postMessage(msg) + override def run: IO[Unit] = IO.fromFuture { IO { val spec = new IOSpec - val env = Env(lineLogger = LineLogger.consoleLogger) + val env = Env(lineLogger = new BufferedLineLogger { + override def infoLine(msg: String): Unit = postMessage(s"[info] $msg") + override def failureLine(msg: String): Unit = postMessage(s"[error] $msg") + override def errorLine(msg: String): Unit = postMessage(s"[error] $msg") + override def warnLine(msg: String): Unit = postMessage(s"[warn] $msg") + }) val loader = new ClassLoader() {} val action = for { printers <- createPrinters(env.arguments, loader).toAction stats <- Runner.runSpecStructure(spec.structure(env), env, loader, printers) // TODO I have no idea how to suspend effects in this - _ = DedicatedWorkerGlobalScope.self.postMessage(stats.isSuccess) + _ = postMessage(stats.toString) + _ = postMessage(stats.isSuccess) } yield () ExecuteActions.runActionFuture(action)(env.executionEnv) } diff --git a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala index 5d08e5c222..ef0025e32b 100644 --- a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala +++ b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala @@ -16,24 +16,32 @@ package cats.effect -import cats.syntax.all._ -import org.scalajs.dom.window import org.scalajs.dom.webworkers.Worker +import org.scalajs.dom.window +import scala.concurrent.duration._ import scala.util.Try class WebWorkerIOSpec extends BaseSpec with WebWorkerIOSpecPlatform { + override def executionTimeout = 5.minutes // This is to run the _entire_ IOSpec + Try(window).toOption.foreach { _ => "io on webworker" should { - "pass the spec" in ticked { implicit ticker => - IO(new Worker( - s"http://localhost:8000/webworker-tests/target/scala-${scalaVersion}/cats-effect-webworker-tests-fastopt/main.js")) - .flatMap { worker => - IO.async_[Boolean] { cb => - worker.onmessage = { event => cb(Right(event.data.asInstanceOf[Boolean])) } + "pass the spec" in real { + for { + worker <- IO(new Worker( + s"/webworker-tests/target/scala-${scalaVersion}/cats-effect-webworker-tests-fastopt/main.js")) + success <- IO.async_[Boolean] { cb => + worker.onmessage = { event => + event.data match { + case log: String => println(log) + case success: Boolean => cb(Right(success)) + case _ => () + } } - }.attempt.flatTap(IO.println).rethrow must completeAs(true) + } + } yield success mustEqual true } } } From 36bac709a7ef5447b2ac7bf611527d3c5b40afdc Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 06:19:50 +0000 Subject: [PATCH 6/7] Fix scala 3 --- build.sbt | 13 ++++++++---- project/plugins.sbt | 1 + .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 ------------------- .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 ------------------- .../cats/effect/WebWorkerIOSpecPlatform.scala | 21 ------------------- .../scala/cats/effect/WebWorkerIOSpec.scala | 7 ++++++- 6 files changed, 16 insertions(+), 68 deletions(-) delete mode 100644 webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala delete mode 100644 webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala delete mode 100644 webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala diff --git a/build.sbt b/build.sbt index 23cb02a4dd..390114a20f 100644 --- a/build.sbt +++ b/build.sbt @@ -138,7 +138,9 @@ ThisBuild / Test / jsEnv := { if (useFirefoxEnv.value) { val options = new FirefoxOptions() options.addArguments("-headless") - val config = SeleniumJSEnv.Config().withMaterializeInServer("target/selenium/", "http://localhost:8000/target/selenium/") + val config = SeleniumJSEnv + .Config() + .withMaterializeInServer("target/selenium/", "http://localhost:8000/target/selenium/") new SeleniumJSEnv(options, config) } else { old @@ -374,12 +376,15 @@ lazy val tests = crossProject(JSPlatform, JVMPlatform) lazy val webWorkerTests = project .in(file("webworker-tests")) .dependsOn(tests.js % "compile->test") - .enablePlugins(ScalaJSPlugin, NoPublishPlugin) + .enablePlugins(ScalaJSPlugin, BuildInfoPlugin, NoPublishPlugin) .settings( name := "cats-effect-webworker-tests", scalaJSUseMainModuleInitializer := true, - libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").cross(CrossVersion.for3Use2_13), - (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value + libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0") + .cross(CrossVersion.for3Use2_13), + (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value, + buildInfoKeys := Seq[BuildInfoKey](scalaVersion), + buildInfoPackage := "cats.effect" ) /** diff --git a/project/plugins.sbt b/project/plugins.sbt index 26fa3c8185..97417c72cb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -7,3 +7,4 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.2.22") addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.3") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") diff --git a/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala deleted file mode 100644 index 8062c8257e..0000000000 --- a/webworker-tests/src/test/scala-2.12/cats/effect/WebWorkerIOSpecPlatform.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-2021 Typelevel - * - * 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 cats.effect - -trait WebWorkerIOSpecPlatform { - val scalaVersion = "2.12" -} diff --git a/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala deleted file mode 100644 index 54e8c6cbda..0000000000 --- a/webworker-tests/src/test/scala-2.13/cats/effect/WebWorkerIOSpecPlatform.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-2021 Typelevel - * - * 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 cats.effect - -trait WebWorkerIOSpecPlatform { - val scalaVersion = "2.13" -} diff --git a/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala b/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala deleted file mode 100644 index 5a335d8869..0000000000 --- a/webworker-tests/src/test/scala-3/cats/effect/WebWorkerIOSpecPlatform.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-2021 Typelevel - * - * 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 cats.effect - -trait WebWorkerIOSpecPlatform { - val scalaVersion = "3" -} diff --git a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala index ef0025e32b..6a2459477e 100644 --- a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala +++ b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala @@ -22,10 +22,15 @@ import org.scalajs.dom.window import scala.concurrent.duration._ import scala.util.Try -class WebWorkerIOSpec extends BaseSpec with WebWorkerIOSpecPlatform { +class WebWorkerIOSpec extends BaseSpec { override def executionTimeout = 5.minutes // This is to run the _entire_ IOSpec + def scalaVersion = if (BuildInfo.scalaVersion.startsWith("2")) + BuildInfo.scalaVersion.split("\\.").init.mkString(".") + else + BuildInfo.scalaVersion + Try(window).toOption.foreach { _ => "io on webworker" should { "pass the spec" in real { From e4dd02aff86efede8791b97a1bb686f2be21b18c Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 14:59:47 +0000 Subject: [PATCH 7/7] Look ma no server! --- .github/workflows/ci.yml | 5 ---- build.sbt | 30 ++++++++----------- .../scala/cats/effect/WebWorkerIOSpec.scala | 6 ++-- .../src/test/scala/java/io/File.scala | 22 ++++++++++++++ 4 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 webworker-tests/src/test/scala/java/io/File.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95af1eb851..4b5523c5fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,11 +91,6 @@ jobs: with: node-version: 14 - - name: Start static file server - if: matrix.ci == 'ciFirefox' - shell: bash - run: python3 -m http.server & - - name: Check that workflows are up to date shell: bash run: sbt --client '++${{ matrix.scala }}; githubWorkflowCheck' diff --git a/build.sbt b/build.sbt index 390114a20f..f1711095da 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,3 @@ -import org.openqa.selenium.firefox.FirefoxProfile /* * Copyright 2020-2021 Typelevel * @@ -19,6 +18,7 @@ import java.io.File import com.typesafe.tools.mima.core._ import org.openqa.selenium.firefox.FirefoxOptions +import org.openqa.selenium.firefox.FirefoxProfile import org.scalajs.jsenv.selenium.SeleniumJSEnv ThisBuild / baseVersion := "3.1" @@ -60,18 +60,12 @@ val GraalVM8 = "graalvm-ce-java8@21.1" ThisBuild / githubWorkflowJavaVersions := Seq(ScalaJSJava, LTSJava, LatestJava, GraalVM8) ThisBuild / githubWorkflowOSes := Seq(PrimaryOS, Windows) -ThisBuild / githubWorkflowBuildPreamble ++= - Seq( - WorkflowStep.Use( - UseRef.Public("actions", "setup-node", "v2.1.2"), - name = Some("Setup NodeJS v14 LTS"), - params = Map("node-version" -> "14"), - cond = Some("matrix.ci == 'ciJS'")), - WorkflowStep.Run( - List("python3 -m http.server &"), - name = Some("Start static file server"), - cond = Some("matrix.ci == 'ciFirefox'")) - ) +ThisBuild / githubWorkflowBuildPreamble += + WorkflowStep.Use( + UseRef.Public("actions", "setup-node", "v2.1.2"), + name = Some("Setup NodeJS v14 LTS"), + params = Map("node-version" -> "14"), + cond = Some("matrix.ci == 'ciJS'")) ThisBuild / githubWorkflowBuild := Seq( WorkflowStep.Sbt(List("${{ matrix.ci }}")), @@ -136,12 +130,12 @@ ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value if (useFirefoxEnv.value) { + val profile = new FirefoxProfile() + profile.setPreference("privacy.file_unique_origin", false) val options = new FirefoxOptions() + options.setProfile(profile) options.addArguments("-headless") - val config = SeleniumJSEnv - .Config() - .withMaterializeInServer("target/selenium/", "http://localhost:8000/target/selenium/") - new SeleniumJSEnv(options, config) + new SeleniumJSEnv(options) } else { old } @@ -383,7 +377,7 @@ lazy val webWorkerTests = project libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0") .cross(CrossVersion.for3Use2_13), (Test / test) := (Test / test).dependsOn(Compile / fastOptJS).value, - buildInfoKeys := Seq[BuildInfoKey](scalaVersion), + buildInfoKeys := Seq[BuildInfoKey](scalaVersion, baseDirectory), buildInfoPackage := "cats.effect" ) diff --git a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala index 6a2459477e..a3778b98a9 100644 --- a/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala +++ b/webworker-tests/src/test/scala/cats/effect/WebWorkerIOSpec.scala @@ -31,12 +31,14 @@ class WebWorkerIOSpec extends BaseSpec { else BuildInfo.scalaVersion + def targetDir = s"${BuildInfo.baseDirectory}/target/scala-${scalaVersion}" + Try(window).toOption.foreach { _ => "io on webworker" should { "pass the spec" in real { for { - worker <- IO(new Worker( - s"/webworker-tests/target/scala-${scalaVersion}/cats-effect-webworker-tests-fastopt/main.js")) + worker <- IO( + new Worker(s"file://${targetDir}/cats-effect-webworker-tests-fastopt/main.js")) success <- IO.async_[Boolean] { cb => worker.onmessage = { event => event.data match { diff --git a/webworker-tests/src/test/scala/java/io/File.scala b/webworker-tests/src/test/scala/java/io/File.scala new file mode 100644 index 0000000000..b03c6cc7b3 --- /dev/null +++ b/webworker-tests/src/test/scala/java/io/File.scala @@ -0,0 +1,22 @@ +/* + * Copyright 2020-2021 Typelevel + * + * 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 +}