summaryrefslogblamecommitdiff
path: root/scalaplugin/src/test/scala/mill/scalaplugin/HelloWorldTests.scala
blob: 4ec10472a2838eabbbb5f242f76c979be88be69c (plain) (tree)
1
2
3
4
5
6
7
8
9




                                
                                  
                               
                                    
                                 








                                              






                                                            
 
                                                    
                              

 
                                                      
                                             


                                                         
                                                                 

 


















                                                                          


                                                         



                                                                             

                                                                       
 






















                                                      




                            
                                                                                     






                             
                                                                                                          








                              
                                                                                      






                         
                                                                                                        








                                                             
                                                                                
 

                                              
                                         
                                
                                                                
               
                                                         
                               





                                                          
                                                                                    


                                       
                                                                            



                                      
                                                                                 
                                                                 



                                           
                                                                                 


                                               



                                                                            




                                                 



                                                                                


                                                               
                                                                                                   



                                               
                
                        
                                                                                   








                                                             





















                                                               
                                  
                                                                                            







                                                        
                                                                                         





                                         
            
                                 
                                                                                         









                                                             
                                                                               





                                            

                   
                                                                            





                              
                                              




                                                    
                                                








                                                                         
                 
                                                                                            













                                                             
                        
                                               
 
                                                   

                               

















                                               
package mill.scalaplugin

import ammonite.ops._
import ammonite.ops.ImplicitWd._
import mill._
import mill.define.{Cross, Target}
import mill.discover.Discovered
import mill.eval.{Evaluator, Result}
import mill.scalaplugin.publish._
import sbt.internal.inc.CompileFailed
import utest._

trait HelloWorldModule extends ScalaModule {
  def scalaVersion = "2.12.4"
  def basePath = HelloWorldTests.workspacePath
}

object HelloWorld extends HelloWorldModule
object CrossHelloWorld extends Module{
  val cross =
    for(v <- Cross("2.10.6", "2.11.11", "2.12.3", "2.12.4"))
    yield new HelloWorldModule {
      def scalaVersion = v
    }
}

object HelloWorldWithMain extends HelloWorldModule {
  def mainClass = Some("Main")
}

object HelloWorldWarnUnused extends HelloWorldModule {
  def scalacOptions = T(Seq("-Ywarn-unused"))
}

object HelloWorldFatalWarnings extends HelloWorldModule {
  def scalacOptions = T(Seq("-Ywarn-unused", "-Xfatal-warnings"))
}

object HelloWorldWithPublish extends HelloWorldModule with PublishModule {
  def publishName = "hello-world"
  def publishVersion = "0.0.1"

  def pomSettings = PomSettings(
    organization = "com.lihaoyi",
    description = "hello world ready for real world publishing",
    url = "https://github.com/lihaoyi/hello-world-publish",
    licenses = Seq(
      License("Apache License, Version 2.0",
              "http://www.apache.org/licenses/LICENSE-2.0")),
    scm = SCM(
      "https://github.com/lihaoyi/hello-world-publish",
      "scm:git:https://github.com/lihaoyi/hello-world-publish"
    ),
    developers =
      Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
  )
}
object HelloWorldScalaOverride extends HelloWorldModule {
  override def scalaVersion: Target[String] = "2.11.11"
}
object HelloWorldTests extends TestSuite {

  val srcPath = pwd / 'scalaplugin / 'src / 'test / 'resource / "hello-world"
  val workspacePath = pwd / 'target / 'workspace / "hello-world"
  val mainObject = workspacePath / 'src / 'main / 'scala / "Main.scala"




  val helloWorldEvaluator = new TestEvaluator(
    Discovered.mapping(HelloWorld),
    workspacePath
  )
  val helloWorldWithMainEvaluator = new TestEvaluator(
    Discovered.mapping(HelloWorldWithMain),
    workspacePath
  )
  val helloWorldFatalEvaluator = new TestEvaluator(
    Discovered.mapping(HelloWorldFatalWarnings),
    workspacePath
  )
  val helloWorldOverrideEvaluator = new TestEvaluator(
    Discovered.mapping(HelloWorldScalaOverride),
    workspacePath
  )
  val helloWorldCrossEvaluator = new TestEvaluator(
    Discovered.mapping(CrossHelloWorld),
    workspacePath
  )


  def tests: Tests = Tests {
    prepareWorkspace()
    'scalaVersion - {
      'fromBuild - {
        val Right((result, evalCount)) = helloWorldEvaluator(HelloWorld.scalaVersion)

        assert(
          result == "2.12.4",
          evalCount > 0
        )
      }
      'override - {
        val Right((result, evalCount)) = helloWorldOverrideEvaluator(HelloWorldScalaOverride.scalaVersion)

        assert(
          result == "2.11.11",
          evalCount > 0
        )
      }
    }
    'scalacOptions - {
      'emptyByDefault - {
        val Right((result, evalCount)) = helloWorldEvaluator(HelloWorld.scalacOptions)

        assert(
          result.isEmpty,
          evalCount > 0
        )
      }
      'override - {
        val Right((result, evalCount)) = helloWorldFatalEvaluator(HelloWorldFatalWarnings.scalacOptions)

        assert(
          result == Seq("-Ywarn-unused", "-Xfatal-warnings"),
          evalCount > 0
        )
      }
    }
    'compile - {
      'fromScratch - {
        val Right((result, evalCount)) = helloWorldEvaluator(HelloWorld.compile)

        val outPath = result.classes.path
        val analysisFile = result.analysisFile
        val outputFiles = ls.rec(outPath)
        val expectedClassfiles =
          compileClassfiles(workspacePath / 'compile / 'classes)
        assert(
          outPath == workspacePath / 'compile / 'classes,
          exists(analysisFile),
          outputFiles.nonEmpty,
          outputFiles.forall(expectedClassfiles.contains),
          evalCount > 0
        )

        // don't recompile if nothing changed
        val Right((_, unchangedEvalCount)) = helloWorldEvaluator(HelloWorld.compile)
        assert(unchangedEvalCount == 0)
      }
      'recompileOnChange - {
        val Right((_, freshCount)) = helloWorldEvaluator(HelloWorld.compile)
        assert(freshCount > 0)

        write.append(mainObject, "\n")

        val Right((_, incCompileCount)) = helloWorldEvaluator(HelloWorld.compile)
        assert(incCompileCount > 0, incCompileCount < freshCount)
      }
      'failOnError - {
        write.append(mainObject, "val x: ")

        val Left(Result.Exception(err)) = helloWorldEvaluator(HelloWorld.compile)

        assert(err.isInstanceOf[CompileFailed])

        val (compilePath, compileMetadataPath) = Evaluator.resolveDestPaths(
          workspacePath,
          helloWorldEvaluator.evaluator.mapping.value(HelloWorld.compile)
        )

        assert(
          ls.rec(compilePath / 'classes).isEmpty,
          !exists(compileMetadataPath)
        )
        // Works when fixed
        write.over(mainObject, read(mainObject).dropRight("val x: ".length))

        val Right((result, evalCount)) = helloWorldEvaluator(HelloWorld.compile)
      }
      'passScalacOptions - {
        // compilation fails because of "-Xfatal-warnings" flag
        val Left(Result.Exception(err)) = helloWorldFatalEvaluator(HelloWorldFatalWarnings.compile)

        assert(err.isInstanceOf[CompileFailed])
      }
    }
    'runMain - {
      'runMainObject - {
        val Right((_, evalCount)) = helloWorldEvaluator(HelloWorld.runMain("Main"))

        assert(evalCount > 0)

        val runResult = workspacePath / "hello-mill"
        assert(
          exists(runResult),
          read(runResult) == "hello rockjam, your age is: 25"
        )
      }
      'runCross{
        def cross(v: String) {

          val Right((_, evalCount)) = helloWorldCrossEvaluator(
            CrossHelloWorld.cross(v).runMain("Main")
          )

          assert(evalCount > 0)

          val runResult = workspacePath / "hello-mill"
          assert(
            exists(runResult),
            read(runResult) == "hello rockjam, your age is: 25"
          )
        }
        'v210 - cross("2.10.6")
        'v211 - cross("2.11.11")
        'v2123 - cross("2.12.3")
        'v2124 - cross("2.12.4")
      }


      'notRunInvalidMainObject - {
        val Left(Result.Exception(err)) = helloWorldEvaluator(HelloWorld.runMain("Invalid"))

        assert(
          err.isInstanceOf[InteractiveShelloutException]
        )
      }
      'notRunWhenComplileFailed - {
        write.append(mainObject, "val x: ")

        val Left(Result.Exception(err)) = helloWorldEvaluator(HelloWorld.runMain("Main"))

        assert(
          err.isInstanceOf[CompileFailed]
        )
      }
    }
    'run - {
      'runIfMainClassProvided - {
        val Right((_, evalCount)) = helloWorldWithMainEvaluator(HelloWorldWithMain.run())

        assert(evalCount > 0)

        val runResult = workspacePath / "hello-mill"
        assert(
          exists(runResult),
          read(runResult) == "hello rockjam, your age is: 25"
        )
      }
      'notRunWithoutMainClass - {
        val Left(Result.Exception(err)) = helloWorldEvaluator(HelloWorld.run())

        assert(
          err.isInstanceOf[RuntimeException]
        )
      }
    }
    'jar - {
      'nonEmpty - {
        val Right((result, evalCount)) = helloWorldEvaluator(HelloWorld.jar)

        assert(
          exists(result.path),
          evalCount > 0
        )

        val unJarPath = workspacePath / 'unjar
        mkdir(unJarPath)
        %("tar", "xf", result.path, "-C", unJarPath)

        val manifestFiles = Seq(
          unJarPath / "META-INF",
          unJarPath / "META-INF" / "MANIFEST.MF"
        )
        val expectedFiles = compileClassfiles(unJarPath) ++ manifestFiles

        val jarFiles = ls.rec(unJarPath)
        assert(
          jarFiles.nonEmpty,
          jarFiles.forall(expectedFiles.contains)
        )
      }
      'runJar - {
        val Right((result, evalCount)) = helloWorldWithMainEvaluator(HelloWorldWithMain.jar)

        assert(
          exists(result.path),
          evalCount > 0
        )

        %("scala", result.path)

        val runResult = workspacePath / "hello-mill"
        assert(
          exists(runResult),
          read(runResult) == "hello rockjam, your age is: 25"
        )
      }
      'logOutputToFile {
        helloWorldEvaluator(HelloWorld.compile)

        val logFile = workspacePath / "compile.log"
        assert(exists(logFile))
      }
    }
  }

  def compileClassfiles(parentDir: Path) = Seq(
    parentDir / "Main.class",
    parentDir / "Main$.class",
    parentDir / "Main$delayedInit$body.class",
    parentDir / "Person.class",
    parentDir / "Person$.class"
  )

  def prepareWorkspace(): Unit = {
    rm(workspacePath)
    mkdir(workspacePath / up)
    cp(srcPath, workspacePath)
  }

}