diff options
author | Nikolay Tatarinov <5min4eq.unity@gmail.com> | 2018-02-01 22:07:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-01 22:07:39 +0300 |
commit | 5be2c5aea4527cf637948e6bf2e4c56e3273fbd9 (patch) | |
tree | 38d9c675c68ac7505708f182170589119453db21 /scalajslib/src | |
parent | bc777b3c4e83149f45df7edda245868e22495eb3 (diff) | |
download | mill-5be2c5aea4527cf637948e6bf2e4c56e3273fbd9.tar.gz mill-5be2c5aea4527cf637948e6bf2e4c56e3273fbd9.tar.bz2 mill-5be2c5aea4527cf637948e6bf2e4c56e3273fbd9.zip |
WIP: Scala js testing (#119)
fixes #102. Use scala js testing framework to launch tests
Diffstat (limited to 'scalajslib/src')
-rw-r--r-- | scalajslib/src/mill/scalajslib/ScalaJSBridge.scala (renamed from scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala) | 62 | ||||
-rw-r--r-- | scalajslib/src/mill/scalajslib/ScalaJSModule.scala | 127 |
2 files changed, 134 insertions, 55 deletions
diff --git a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala b/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala index ae282152..10dd42d6 100644 --- a/scalajslib/src/mill/scalajslib/ScalaJSLinkerBridge.scala +++ b/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala @@ -11,41 +11,33 @@ sealed trait OptimizeMode object FastOpt extends OptimizeMode object FullOpt extends OptimizeMode -class ScalaJSLinkerWorker { - var scalaInstanceCache = Option.empty[(Long, ScalaJSLinkerBridge)] - def link(toolsClasspath: Agg[Path], - sources: Agg[Path], - libraries: Agg[Path], - dest: File, - main: Option[String], - fullOpt: Boolean): Unit = { +class ScalaJSWorker { + private var scalaInstanceCache = Option.empty[(Long, ScalaJSBridge)] - val classloaderSig = { + private def bridge(toolsClasspath: Agg[Path]) = { + val classloaderSig = toolsClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum - } - - val bridge = scalaInstanceCache match{ + scalaInstanceCache match { case Some((sig, bridge)) if sig == classloaderSig => bridge case _ => - val outerClassLoader = getClass.getClassLoader - val cl = new URLClassLoader(toolsClasspath.map(_.toIO.toURI.toURL).toArray){ - override def findClass(name: String) = { - if (name.startsWith("mill.scalajslib.ScalaJSLinkerBridge")){ - outerClassLoader.loadClass(name) - }else{ - super.findClass(name) - } - } - } + val cl = new URLClassLoader(toolsClasspath.map(_.toIO.toURI.toURL).toArray) val bridge = cl - .loadClass("mill.scalajslib.bridge.ScalaJSLinkerBridge") + .loadClass("mill.scalajslib.bridge.ScalaJSBridge") .getDeclaredConstructor() .newInstance() - .asInstanceOf[ScalaJSLinkerBridge] + .asInstanceOf[ScalaJSBridge] scalaInstanceCache = Some((classloaderSig, bridge)) bridge } - bridge.link( + } + + def link(toolsClasspath: Agg[Path], + sources: Agg[Path], + libraries: Agg[Path], + dest: File, + main: Option[String], + fullOpt: Boolean): Unit = { + bridge(toolsClasspath).link( sources.items.map(_.toIO).toArray, libraries.items.map(_.toIO).toArray, dest, @@ -54,19 +46,27 @@ class ScalaJSLinkerWorker { ) } + def getFramework(toolsClasspath: Agg[Path], + frameworkName: String, + linkedFile: File): sbt.testing.Framework = { + bridge(toolsClasspath).getFramework(frameworkName, linkedFile) + } + } -trait ScalaJSLinkerBridge { +trait ScalaJSBridge { def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit + + def getFramework(frameworkName: String, + linkedFile: File): sbt.testing.Framework + } -object ScalaJSLinkerBridge extends mill.define.BaseModule(ammonite.ops.pwd){ +object ScalaJSBridge extends mill.define.BaseModule(ammonite.ops.pwd) { - def scalaJSLinkerBridge = T.worker{ - new ScalaJSLinkerWorker() - } -}
\ No newline at end of file + def scalaJSBridge = T.worker { new ScalaJSWorker() } +} diff --git a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala index d76a50db..82000c6e 100644 --- a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala +++ b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala @@ -1,24 +1,25 @@ package mill package scalajslib -import java.io.File - -import mill.scalalib.DepSyntax import ammonite.ops.{Path, ls, mkdir, rm} import coursier.Cache import coursier.maven.MavenRepository import mill.eval.PathRef import mill.eval.Result.Success import mill.scalalib.Lib.resolveDependencies -import mill.scalalib.{Dep, PublishModule, ScalaModule, TestModule} -import mill.util.Loose - -import scala.collection.breakOut +import mill.scalalib.{CompilationResult, Dep, DepSyntax, TestModule} +import mill.util.{Ctx, Loose} trait ScalaJSModule extends scalalib.ScalaModule { outer => def scalaJSVersion: T[String] + trait Tests extends TestScalaJSModule { + override def scalaVersion = outer.scalaVersion() + override def scalaJSVersion = outer.scalaJSVersion() + override def moduleDeps = Seq(outer) + } + private val ReleaseVersion = raw"""(\d+)\.(\d+)\.(\d+)""".r private val MinorSnapshotVersion = raw"""(\d+)\.(\d+)\.([1-9]\d*)-SNAPSHOT""".r @@ -32,7 +33,7 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer => def scalaJSBridgeVersion = T{ scalaJSVersion().split('.').dropRight(1).mkString(".") } - def sjsLinkerBridgeClasspath = T { + def sjsBridgeClasspath = T { val jsBridgeKey = "MILL_SCALAJS_BRIDGE_" + scalaJSBridgeVersion().replace('.', '_') val jsBridgePath = sys.props(jsBridgeKey) if (jsBridgePath != null) Success( @@ -49,41 +50,78 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer => ).map(_.find(_.path.toString.contains("mill-jsbridge")).get) } - def scalaJSLinkerClasspath: T[Loose.Agg[PathRef]] = T{ + val commonDeps = Seq( + ivy"org.scala-js::scalajs-tools:${scalaJSVersion()}", + ivy"org.scala-js::scalajs-sbt-test-adapter:${scalaJSVersion()}" + ) + val envDep = scalaJSBinaryVersion() match { + case v if v.startsWith("0.6") => ivy"org.scala-js::scalajs-js-envs:${scalaJSVersion()}" + case v if v.startsWith("1.0") => ivy"org.scala-js::scalajs-env-nodejs:${scalaJSVersion()}" + } resolveDependencies( repositories, "2.12.4", "2.12", - Seq(ivy"org.scala-js::scalajs-tools:${scalaJSVersion()}") + commonDeps :+ envDep + ) + } + + def toolsClasspath = T { Agg(sjsBridgeClasspath()) ++ scalaJSLinkerClasspath() } + + def fastOpt = T { + link( + ScalaJSBridge.scalaJSBridge(), + toolsClasspath(), + Seq(compile()), + compileDepClasspath(), + mainClass(), + FastOpt + ) + } + + def fullOpt = T { + link( + ScalaJSBridge.scalaJSBridge(), + toolsClasspath(), + Seq(compile()), + compileDepClasspath(), + mainClass(), + FullOpt ) } - def genericOpt(mode: OptimizeMode) = T.task{ - val outputPath = T.ctx().dest / "out.js" + def link(worker: ScalaJSWorker, + toolsClasspath: Agg[PathRef], + input: Seq[CompilationResult], + libraries: Agg[PathRef], + mainClass: Option[String], + mode: OptimizeMode)(implicit ctx: Ctx.DestCtx): PathRef = { + val outputPath = ctx.dest / "out.js" - mkdir(T.ctx().dest) + mkdir(ctx.dest) rm(outputPath) - val inputFiles = Agg.from(ls(compile().classes.path).filter(_.ext == "sjsir")) - val inputLibraries = compileDepClasspath().map(_.path).filter(_.ext == "jar") - mill.scalajslib.ScalaJSLinkerBridge.scalaJSLinkerBridge().link( - (Agg(sjsLinkerBridgeClasspath()) ++ scalaJSLinkerClasspath()).map(_.path), + + val inputFiles = Agg.from(for { + compiled <- input + file <- ls(compiled.classes.path) + if file.ext == "sjsir" + } yield file) + val inputLibraries = libraries.map(_.path).filter(_.ext == "jar") + worker.link( + toolsClasspath.map(_.path), inputFiles, inputLibraries, outputPath.toIO, - mainClass(), + mainClass, mode == FullOpt ) PathRef(outputPath) } - def fastOpt = T{ genericOpt(FastOpt)() } - - def fullOpt = T{ genericOpt(FullOpt)() } - override def scalacPluginIvyDeps = T{ Loose.Agg(Dep.Point("org.scala-js", "scalajs-compiler", scalaJSVersion())) } - override def ivyDeps = T{ Loose.Agg(Dep("org.scala-js", "scalajs-library", scalaJSVersion())) } + override def ivyDeps = T{ Loose.Agg(ivy"org.scala-js::scalajs-library:${scalaJSVersion()}") } // publish artifact with name "mill_sjs0.6.4_2.12" instead of "mill_sjs0.6_2.12" def crossFullScalaJSVersion: T[Boolean] = false @@ -96,4 +134,45 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer => } -trait TestScalaJSModule extends ScalaJSModule with TestModule
\ No newline at end of file +trait TestScalaJSModule extends ScalaJSModule with TestModule { + def scalaJSTestDeps = T { + resolveDeps(T.task { + Loose.Agg( + ivy"org.scala-js::scalajs-library:${scalaJSVersion()}", + ivy"org.scala-js::scalajs-test-interface:${scalaJSVersion()}" + ) + }) + } + + def fastOptTest = T { + link( + ScalaJSBridge.scalaJSBridge(), + toolsClasspath(), + compile() +: upstreamCompileOutput(), + scalaJSTestDeps() ++ compileDepClasspath(), + None, + FastOpt + ) + } + + override def testLocal(args: String*) = T.command { test(args:_*) } + + override def test(args: String*) = T.command { + val framework = mill.scalajslib.ScalaJSBridge.scalaJSBridge().getFramework( + toolsClasspath().map(_.path), + testFramework(), + fastOptTest().path.toIO + ) + + val (doneMsg, results) = mill.scalalib.ScalaWorkerApi + .scalaWorker() + .apply( + _ => framework, + runClasspath().map(_.path), + Agg(compile().classes.path), + args + ) + TestModule.handleResults(doneMsg, results) + } + +} |