From cf5fb5fdfd477e0bb4ffa0e4fec3a8ec01bf5cf1 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sun, 31 Dec 2017 22:56:45 -0800 Subject: Split Acyclic/Jawn/BetterFiles tests into their own `integration/` test suite. Those tests now download a snapshot of the relevant git repo rather than vendoring the files, and use a bare `build.sc` instead of having the build object be included in the test classpath. Tests pass using `sbt integration/test`, but `mill integration.test` still doesn't work --- integration/src/test/resource/acyclic/build.sc | 38 ++++++++++ .../src/test/resource/better-files/build.sc | 83 ++++++++++++++++++++++ integration/src/test/resource/jawn/build.sc | 58 +++++++++++++++ .../test/scala/mill/integration/AcyclicTests.scala | 34 +++++++++ .../scala/mill/integration/BetterFilesTests.scala | 21 ++++++ .../mill/integration/IntegrationTestSuite.scala | 23 ++++++ .../test/scala/mill/integration/JawnTests.scala | 33 +++++++++ 7 files changed, 290 insertions(+) create mode 100644 integration/src/test/resource/acyclic/build.sc create mode 100644 integration/src/test/resource/better-files/build.sc create mode 100644 integration/src/test/resource/jawn/build.sc create mode 100644 integration/src/test/scala/mill/integration/AcyclicTests.scala create mode 100644 integration/src/test/scala/mill/integration/BetterFilesTests.scala create mode 100644 integration/src/test/scala/mill/integration/IntegrationTestSuite.scala create mode 100644 integration/src/test/scala/mill/integration/JawnTests.scala (limited to 'integration/src') diff --git a/integration/src/test/resource/acyclic/build.sc b/integration/src/test/resource/acyclic/build.sc new file mode 100644 index 00000000..603f8f06 --- /dev/null +++ b/integration/src/test/resource/acyclic/build.sc @@ -0,0 +1,38 @@ +import mill.define.Cross +import mill.scalalib.{SbtModule, PublishModule, Dep} +import mill.scalalib.publish.{PomSettings, License, Developer, SCM} +val acyclic = for{ + crossVersion <- Cross("2.10.6", "2.11.8", "2.12.3", "2.12.4") +} yield new SbtModule with PublishModule {outer => + def basePath = ammonite.ops.pwd / 'target / 'workspace / 'acyclic + def artifactName = "acyclic" + def publishVersion = "0.1.7" + + def pomSettings = PomSettings( + description = artifactName(), + organization = "com.lihaoyi", + url = "https://github.com/lihaoyi/acyclic", + licenses = Seq( + License("MIT license", "http://www.opensource.org/licenses/mit-license.php") + ), + scm = SCM( + "git://github.com/lihaoyi/acyclic.git", + "scm:git://github.com/lihaoyi/acyclic.git" + ), + developers = Seq( + Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") + ) + ) + + def scalaVersion = crossVersion + def ivyDeps = Seq( + Dep.Java("org.scala-lang", "scala-compiler", scalaVersion()) + ) + object test extends this.Tests{ + def forkWorkingDir = ammonite.ops.pwd / 'target / 'workspace / 'acyclic + def ivyDeps = Seq( + Dep("com.lihaoyi", "utest", "0.6.0") + ) + def testFramework = "utest.runner.Framework" + } +} \ No newline at end of file diff --git a/integration/src/test/resource/better-files/build.sc b/integration/src/test/resource/better-files/build.sc new file mode 100644 index 00000000..6ce3ebf4 --- /dev/null +++ b/integration/src/test/resource/better-files/build.sc @@ -0,0 +1,83 @@ +import mill.define.Cross +import mill.scalalib.{SbtModule, PublishModule, Dep} +import mill.scalalib.publish.{PomSettings, License, Developer, SCM} +trait BetterFilesModule extends SbtModule{ outer => + def scalaVersion = "2.12.4" + def scalacOptions = Seq( + "-deprecation", // Emit warning and location for usages of deprecated APIs. + "-encoding", "utf-8", // Specify character encoding used by source files. + "-explaintypes", // Explain type errors in more detail. + "-feature", // Emit warning and location for usages of features that should be imported explicitly. + "-language:existentials", // Existential types (besides wildcard types) can be written and inferred + "-language:experimental.macros", // Allow macro definition (besides implementation and application) + "-language:higherKinds", // Allow higher-kinded types + "-language:implicitConversions", // Allow definition of implicit functions called views + "-unchecked", // Enable additional warnings where generated code depends on assumptions. + "-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. + "-Xfatal-warnings", // Fail the compilation if there are any warnings. + "-Xfuture", // Turn on future language features. + "-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver. + "-Xlint:by-name-right-associative", // By-name parameter of right associative operator. + "-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error. + "-Xlint:delayedinit-select", // Selecting member of DelayedInit. + "-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element. + "-Xlint:inaccessible", // Warn about inaccessible types in method signatures. + "-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`. + "-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id. + "-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Xlint:nullary-unit", // Warn when nullary methods return Unit. + "-Xlint:option-implicit", // Option.apply used implicit view. + "-Xlint:package-object-classes", // Class or object defined in package object. + "-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds. + "-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field. + "-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component. + "-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope. + "-Xlint:unsound-match", // Pattern match may not be typesafe. + "-Yno-adapted-args", // Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver. + "-Ypartial-unification", // Enable partial unification in type constructor inference + "-Ywarn-dead-code", // Warn when dead code is identified. + "-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined. + "-Ywarn-inaccessible", // Warn about inaccessible types in method signatures. + "-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`. + "-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. + "-Ywarn-nullary-unit", // Warn when nullary methods return Unit. + "-Ywarn-numeric-widen", // Warn when numerics are widened. + "-Ywarn-unused:implicits", // Warn if an implicit parameter is unused. + "-Ywarn-unused:imports", // Warn if an import selector is not referenced. + "-Ywarn-unused:locals", // Warn if a local definition is unused. + "-Ywarn-unused:params", // Warn if a value parameter is unused. + "-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused. + "-Ywarn-unused:privates", // Warn if a private member is unused. + "-Ywarn-value-discard" // Warn when non-Unit expression results are unused. + ) + override def javacOptions = Seq("-source", "1.8", "-target", "1.8", "-Xlint") + object test extends this.Tests{ + def projectDeps = + if (this == Core.test) Seq(Core) + else Seq(outer, Core.test) + def ivyDeps = Seq(Dep("org.scalatest", "scalatest", "3.0.4")) + def testFramework = "org.scalatest.tools.Framework" + } +} +object Core extends BetterFilesModule{ + def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'core +} +object Akka extends BetterFilesModule{ + def projectDeps = Seq(Core) + def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'akka + def ivyDeps = Seq(Dep("com.typesafe.akka", "akka-actor", "2.5.6")) +} +object ShapelessScanner extends BetterFilesModule{ + def projectDeps = Seq(Core) + def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'shapeless + def ivyDeps = Seq(Dep("com.chuusai", "shapeless", "2.3.2")) +} +object Benchmarks extends BetterFilesModule{ + def projectDeps = Seq(Core) + def basePath = ammonite.ops.pwd / 'target / 'workspace / "better-files" / 'benchmarks + def ivyDeps = Seq( + Dep.Java("commons-io", "commons-io", "2.5") + // "fastjavaio" % "fastjavaio" % "1.0" from "https://github.com/williamfiset/FastJavaIO/releases/download/v1.0/fastjavaio.jar" + ) +} + diff --git a/integration/src/test/resource/jawn/build.sc b/integration/src/test/resource/jawn/build.sc new file mode 100644 index 00000000..9c9b41dc --- /dev/null +++ b/integration/src/test/resource/jawn/build.sc @@ -0,0 +1,58 @@ +import mill.scalalib +import mill.define.Cross +import mill.scalalib.{Dep, TestModule, Module} + +val jawn = Cross("2.10.6", "2.11.11", "2.12.3").map(new Jawn(_)) +class Jawn(crossVersion: String) extends mill.Module{ + trait JawnModule extends scalalib.SbtModule{ outer => + def scalaVersion = crossVersion + def scalacOptions = Seq( + "-deprecation", + "-optimize", + "-unchecked" + ) + def testProjectDeps: Seq[TestModule] = Nil + object test extends this.Tests{ + def projectDeps = super.projectDeps ++ testProjectDeps + def ivyDeps = Seq( + Dep("org.scalatest", "scalatest", "3.0.3"), + Dep("org.scalacheck", "scalacheck", "1.13.5") + ) + def testFramework = "org.scalatest.tools.Framework" + } + } + object Parser extends JawnModule{ + def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'parser + } + object Util extends JawnModule{ + def projectDeps = Seq(Parser) + def testProjectDeps = Seq(Parser.test) + def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'util + } + object Ast extends JawnModule{ + def projectDeps = Seq(Parser, Util) + def testProjectDeps = Seq(Parser.test, Util.test) + def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'acyclic + } + class Support(name: String, ivyDeps0: Dep*) extends JawnModule{ + def projectDeps = Seq[Module](Parser) + def basePath = ammonite.ops.pwd / 'target / 'workspace / 'jawn / 'support / name + def ivyDeps = ivyDeps0 + } + object Argonaut extends Support("argonaut", Dep("io.argonaut", "argonaut", "6.2")) + object Json4s extends Support("json4s", Dep("org.json4s", "json4s-ast", "3.5.2")) + + object Play extends Support("play"){ + def ivyDeps = mill.T{ + scalaBinaryVersion() match{ + case "2.10" => Seq(Dep("com.typesafe.play", "play-json", "2.4.11")) + case "2.11" => Seq(Dep("com.typesafe.play", "play-json", "2.5.15")) + case _ => Seq(Dep("com.typesafe.play", "play-json", "2.6.0")) + } + } + } + + object Rojoma extends Support("rojoma", Dep("com.rojoma", "rojoma-json", "2.4.3")) + object RojomaV3 extends Support("rojoma-v3", Dep("com.rojoma", "rojoma-json-v3", "3.7.2")) + object Spray extends Support("spray", Dep("io.spray", "spray-json", "1.3.3")) +} \ No newline at end of file diff --git a/integration/src/test/scala/mill/integration/AcyclicTests.scala b/integration/src/test/scala/mill/integration/AcyclicTests.scala new file mode 100644 index 00000000..cd7209d5 --- /dev/null +++ b/integration/src/test/scala/mill/integration/AcyclicTests.scala @@ -0,0 +1,34 @@ +package mill.integration + +import ammonite.ops._ +import utest._ + +object AcyclicTests extends IntegrationTestSuite("MILL_ACYCLIC_REPO", "acyclic") { + val tests = Tests{ + initWorkspace() + + def check(scalaVersion: String) = { + val firstCompile = eval(s"acyclic[$scalaVersion].compile") + + assert( + firstCompile, + ls.rec(workspacePath).exists(_.last == "GraphAnalysis.class"), + ls.rec(workspacePath).exists(_.last == "PluginPhase.class") + ) + for(scalaFile <- ls.rec(workspacePath).filter(_.ext == "scala")){ + write.append(scalaFile, "\n}") + } + + val brokenCompile = eval(s"acyclic[$scalaVersion].compile") + + assert(!brokenCompile) + } + + 'scala2118 - check("2.11.8") + 'scala2124 - check("2.12.4") + + } + def main(args: Array[String]): Unit = { + println("Integration Main") + } +} diff --git a/integration/src/test/scala/mill/integration/BetterFilesTests.scala b/integration/src/test/scala/mill/integration/BetterFilesTests.scala new file mode 100644 index 00000000..b14709a4 --- /dev/null +++ b/integration/src/test/scala/mill/integration/BetterFilesTests.scala @@ -0,0 +1,21 @@ +package mill.integration + +import ammonite.ops._ +import utest._ + +object BetterFilesTests extends IntegrationTestSuite("MILL_BETTERFILES_REPO", "better-files") { + val tests = Tests{ + initWorkspace() + 'test - { + + assert(eval("Core.test")) + assert(eval("Akka.test")) + + for(scalaFile <- ls.rec(workspacePath).filter(_.ext == "scala")){ + write.append(scalaFile, "\n}") + } + assert(!eval("Akka.test")) + } + + } +} diff --git a/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala new file mode 100644 index 00000000..e79eebe0 --- /dev/null +++ b/integration/src/test/scala/mill/integration/IntegrationTestSuite.scala @@ -0,0 +1,23 @@ +package mill.integration + +import ammonite.ops._ +import utest._ + +abstract class IntegrationTestSuite(repoKey: String, workspaceSlug: String) extends TestSuite{ + val workspacePath = pwd / 'target / 'workspace / workspaceSlug + val buildFilePath = pwd / 'integration / 'src / 'test / 'resource / workspaceSlug + val runner = new mill.main.MainRunner(ammonite.main.Cli.Config(wd = workspacePath), false) + def eval(s: String*) = runner.runScript(workspacePath / "build.sc", s.toList) + def initWorkspace() = { + rm(workspacePath) + mkdir(workspacePath / up) + // The unzipped git repo snapshots we get from github come with a + // wrapper-folder inside the zip file, so copy the wrapper folder to the + // destination instead of the folder containing the wrapper. + val path = sys.props(repoKey) + val Seq(wrapper) = ls(Path(path)) + cp(wrapper, workspacePath) + cp(buildFilePath / "build.sc", workspacePath / "build.sc") + assert(!ls.rec(workspacePath).exists(_.ext == "class")) + } +} diff --git a/integration/src/test/scala/mill/integration/JawnTests.scala b/integration/src/test/scala/mill/integration/JawnTests.scala new file mode 100644 index 00000000..adf6e688 --- /dev/null +++ b/integration/src/test/scala/mill/integration/JawnTests.scala @@ -0,0 +1,33 @@ +package mill.integration + +import ammonite.ops._ +import utest._ + +object JawnTests extends IntegrationTestSuite("MILL_JAWN_REPO", "jawn") { + val tests = Tests{ + initWorkspace() + + def check(scalaVersion: String) = { + val firstCompile = eval(s"jawn[$scalaVersion].Parser.test") + + assert( + firstCompile, + ls.rec(workspacePath).exists(_.last == "AsyncParser.class"), + ls.rec(workspacePath).exists(_.last == "CharBuilderSpec.class") + ) + + pprint.log(ls.rec(workspacePath).map(_.toString), height=9999) + pprint.log(ls.rec(workspacePath).find(_.ext == "scala")) + for(scalaFile <- ls.rec(workspacePath).filter(_.ext == "scala")){ + write.append(scalaFile, "\n}") + } + + val brokenCompile = eval(s"jawn[$scalaVersion].Parser.test") + + assert(!brokenCompile) + } + + 'scala21111 - check("2.11.11") + 'scala2123 - check("2.12.3") + } +} -- cgit v1.2.3