mirror of https://github.com/sbt/sbt.git
Fixed tests
This commit is contained in:
parent
39546077ee
commit
72ce84933d
|
|
@ -5,11 +5,9 @@ package xsbt
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
|
|
||||||
/** Interface to the Scala compiler that uses the dependency analysis plugin. This class uses the Scala library and compiler
|
/** Interface to the Scala compiler that uses the dependency analysis plugin. This class uses the Scala library and compiler
|
||||||
* obtained through the 'scalaLoader' class loader. This class requires a ComponentManager in order to obtain the
|
* provided by scalaInstance. This class requires a ComponentManager in order to obtain the interface code to scalac and
|
||||||
* interface code to scalac and the analysis plugin. Because these call Scala code for a different Scala version, they must
|
* the analysis plugin. Because these call Scala code for a different Scala version than the one used for this class, they must
|
||||||
* be compiled for the version of Scala being used. It is essential that the provided 'scalaVersion' be a 1:1 mapping to the
|
* be compiled for the version of Scala being used.*/
|
||||||
* actual version of Scala being used for compilation (-SNAPSHOT is not acceptable). Otherwise, binary compatibility
|
|
||||||
* issues will ensue!*/
|
|
||||||
class AnalyzingCompiler(scalaInstance: ScalaInstance, manager: ComponentManager) extends NotNull
|
class AnalyzingCompiler(scalaInstance: ScalaInstance, manager: ComponentManager) extends NotNull
|
||||||
{
|
{
|
||||||
def apply(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], callback: AnalysisCallback, maximumErrors: Int, log: CompileLogger): Unit =
|
def apply(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], callback: AnalysisCallback, maximumErrors: Int, log: CompileLogger): Unit =
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package xsbt
|
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import org.specs.Specification
|
|
||||||
|
|
||||||
object CheckBasic extends Specification
|
|
||||||
{
|
|
||||||
val basicName = new File("Basic.scala")
|
|
||||||
val basicSource = "package org.example { object Basic }"
|
|
||||||
|
|
||||||
"Compiling basic file should succeed" in {
|
|
||||||
WithFiles(basicName -> basicSource){ files =>
|
|
||||||
TestCompile(files){ loader => Class.forName("org.example.Basic", false, loader) }
|
|
||||||
true must beTrue // don't know how to just check that previous line completes without exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"Analyzer plugin should send source begin and end" in {
|
|
||||||
WithFiles(basicName -> basicSource) { files =>
|
|
||||||
CallbackTest(files) { callback =>
|
|
||||||
(callback.beganSources) must haveTheSameElementsAs(files)
|
|
||||||
(callback.endedSources) must haveTheSameElementsAs(files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package xsbt
|
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import java.net.URLClassLoader
|
|
||||||
import xsbti.TestCallback
|
|
||||||
import FileUtilities.withTemporaryDirectory
|
|
||||||
|
|
||||||
object TestCompile
|
|
||||||
{
|
|
||||||
/** Tests running the compiler interface with the analyzer plugin with a test callback. The test callback saves all information
|
|
||||||
* that the plugin sends it for post-compile analysis by the provided function.*/
|
|
||||||
def apply[T](arguments: Seq[String], superclassNames: Seq[String])(f: (TestCallback, Logger) => T): T =
|
|
||||||
{
|
|
||||||
val testCallback = new TestCallback(superclassNames.toArray)
|
|
||||||
val i = new CompilerInterface
|
|
||||||
val log = new BufferedLogger(new ConsoleLogger)
|
|
||||||
log.bufferQuietly {
|
|
||||||
i.run(arguments.toArray, testCallback, 5, log)
|
|
||||||
f(testCallback, log)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** Tests running the compiler interface with the analyzer plugin. The provided function is given a ClassLoader that can
|
|
||||||
* load the compiled classes..*/
|
|
||||||
def apply[T](sources: Seq[File])(f: ClassLoader => T): T =
|
|
||||||
CallbackTest.apply(sources, Nil){ case (callback, outputDir, log) => f(new URLClassLoader(Array(outputDir.toURI.toURL))) }
|
|
||||||
}
|
|
||||||
object CallbackTest
|
|
||||||
{
|
|
||||||
def apply[T](sources: Iterable[File])(f: TestCallback => T): T =
|
|
||||||
apply(sources.toSeq, Nil){ case (callback, outputDir, log) => f(callback) }
|
|
||||||
def apply[T](sources: Seq[File], superclassNames: Seq[String])(f: (TestCallback, File, Logger) => T): T =
|
|
||||||
{
|
|
||||||
withTemporaryDirectory { outputDir =>
|
|
||||||
val newArgs = "-d" :: outputDir.getAbsolutePath :: sources.map(_.getAbsolutePath).toList
|
|
||||||
TestCompile(newArgs, superclassNames) { case (callback, log) => f(callback, outputDir, log) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -98,13 +98,14 @@ object ApplicationsTest extends Specification
|
||||||
|
|
||||||
"Analysis plugin should detect applications" in {
|
"Analysis plugin should detect applications" in {
|
||||||
WithFiles(sources : _*) { case files @ Seq(main, main2, main3, main4, main5, main6, main7, main8, main9, mainA, mainB, mainC, mainD, mainE) =>
|
WithFiles(sources : _*) { case files @ Seq(main, main2, main3, main4, main5, main6, main7, main8, main9, mainA, mainB, mainC, mainD, mainE) =>
|
||||||
CallbackTest(files, Nil) { (callback, file, log) =>
|
for(scalaVersion <- TestCompile.allVersions)
|
||||||
val expected = Seq( main -> "Main", main4 -> "Main4", main8 -> "Main8", main9 -> "Main9", mainB -> "MainB",
|
CallbackTest(scalaVersion, files, Nil) { (callback, file, log) =>
|
||||||
mainE -> "MainE1", mainE -> "MainE2", mainE -> "MainE3", mainE -> "MainE4", mainE -> "MainE5" )
|
val expected = Seq( main -> "Main", main4 -> "Main4", main8 -> "Main8", main9 -> "Main9", mainB -> "MainB",
|
||||||
(callback.applications) must haveTheSameElementsAs(expected)
|
mainE -> "MainE1", mainE -> "MainE2", mainE -> "MainE3", mainE -> "MainE4", mainE -> "MainE5" )
|
||||||
val loader = new URLClassLoader(Array(file.toURI.toURL), getClass.getClassLoader)
|
(callback.applications) must haveTheSameElementsAs(expected)
|
||||||
for( (_, className) <- expected) testRun(loader, className)
|
val loader = new URLClassLoader(Array(file.toURI.toURL), getClass.getClassLoader)
|
||||||
}
|
for( (_, className) <- expected) testRun(loader, className)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private def testRun(loader: ClassLoader, className: String)
|
private def testRun(loader: ClassLoader, className: String)
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import org.specs.Specification
|
||||||
|
|
||||||
|
object CheckBasic extends Specification
|
||||||
|
{
|
||||||
|
val basicName = new File("Basic.scala")
|
||||||
|
val basicSource = "package org.example { object Basic }"
|
||||||
|
|
||||||
|
"Compiling basic file should succeed" in {
|
||||||
|
WithFiles(basicName -> basicSource){ files =>
|
||||||
|
for(scalaVersion <- TestCompile.allVersions)
|
||||||
|
{
|
||||||
|
TestCompile(scalaVersion, files){ loader => Class.forName("org.example.Basic", false, loader) }
|
||||||
|
true must beTrue // don't know how to just check that previous line completes without exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"Analyzer plugin should send source begin and end" in {
|
||||||
|
WithFiles(basicName -> basicSource) { files =>
|
||||||
|
for(scalaVersion <- TestCompile.allVersions)
|
||||||
|
CallbackTest(scalaVersion, files) { callback =>
|
||||||
|
(callback.beganSources) must haveTheSameElementsAs(files)
|
||||||
|
(callback.endedSources) must haveTheSameElementsAs(files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,13 +4,15 @@ import java.io.File
|
||||||
import FileUtilities.withTemporaryDirectory
|
import FileUtilities.withTemporaryDirectory
|
||||||
import org.specs._
|
import org.specs._
|
||||||
|
|
||||||
// compile w/ analysis a bit hard to test properly right now:
|
|
||||||
// requires compile project to depend on +publish-local, which is not possible in sbt (addressed in xsbt, but that doesn't help here!)
|
|
||||||
object CompileTest extends Specification
|
object CompileTest extends Specification
|
||||||
{
|
{
|
||||||
"Analysis compiler" should {
|
"Analysis compiler" should {
|
||||||
"compile basic sources" in {
|
"compile basic sources" in {
|
||||||
WithCompiler( "2.7.2" )(testCompileAnalysis)
|
WithCompiler( "2.7.2" )(testCompileAnalysis)
|
||||||
|
WithCompiler( "2.7.3" )(testCompileAnalysis)
|
||||||
|
WithCompiler( "2.7.4" )(testCompileAnalysis)
|
||||||
|
WithCompiler( "2.7.5" )(testCompileAnalysis)
|
||||||
|
WithCompiler( "2.8.0-SNAPSHOT" )(testCompileAnalysis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private def testCompileAnalysis(compiler: AnalyzingCompiler, log: CompileLogger)
|
private def testCompileAnalysis(compiler: AnalyzingCompiler, log: CompileLogger)
|
||||||
|
|
@ -38,7 +40,12 @@ object WithCompiler
|
||||||
val manager = new ComponentManager(launch.getSbtHome(sbtVersion, scalaVersion), log)
|
val manager = new ComponentManager(launch.getSbtHome(sbtVersion, scalaVersion), log)
|
||||||
prepare(manager, ComponentCompiler.compilerInterfaceSrcID, "CompilerInterface.scala")
|
prepare(manager, ComponentCompiler.compilerInterfaceSrcID, "CompilerInterface.scala")
|
||||||
prepare(manager, ComponentCompiler.xsbtiID, classOf[xsbti.AnalysisCallback])
|
prepare(manager, ComponentCompiler.xsbtiID, classOf[xsbti.AnalysisCallback])
|
||||||
f(AnalyzingCompiler(scalaVersion, launch, manager), log)
|
val result = f(AnalyzingCompiler(scalaVersion, launch, manager), log)
|
||||||
|
launch.clearScalaLoaderCache
|
||||||
|
System.gc()
|
||||||
|
System.gc()
|
||||||
|
System.gc()
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,17 @@ object DetectSubclasses extends Specification
|
||||||
WithFiles(sources.map{case (file, content) => (new File(file), content)} : _*)
|
WithFiles(sources.map{case (file, content) => (new File(file), content)} : _*)
|
||||||
{
|
{
|
||||||
case files @ Seq(supFile, sup2File, midFile, sub1File, sub2File, sub3File) =>
|
case files @ Seq(supFile, sup2File, midFile, sub1File, sub2File, sub3File) =>
|
||||||
CallbackTest(files, Seq( "a.Super", "Super2", "x.Super3", "Super4") ) { (callback, x, xx) =>
|
for(scalaVersion <- TestCompile.allVersions)
|
||||||
val expected =
|
CallbackTest(scalaVersion, files, Seq( "a.Super", "Super2", "x.Super3", "Super4") ) { (callback, x, xx) =>
|
||||||
(sub1File, "a.Sub1", "a.Super", false) ::
|
val expected =
|
||||||
(sub2File, "Sub2", "a.Super", false) ::
|
(sub1File, "a.Sub1", "a.Super", false) ::
|
||||||
(sup2File, "Super2", "Super2", false) ::
|
(sub2File, "Sub2", "a.Super", false) ::
|
||||||
(sub3File, "c.Sub3", "Super2", true) ::
|
(sup2File, "Super2", "Super2", false) ::
|
||||||
Nil
|
(sub3File, "c.Sub3", "Super2", true) ::
|
||||||
(callback.foundSubclasses) must haveTheSameElementsAs(expected)
|
Nil
|
||||||
(callback.invalidSuperclasses) must haveTheSameElementsAs(Seq("x.Super3", "Super4"))
|
(callback.foundSubclasses) must haveTheSameElementsAs(expected)
|
||||||
}
|
(callback.invalidSuperclasses) must haveTheSameElementsAs(Seq("x.Super3", "Super4"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package xsbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
import xsbti.TestCallback
|
||||||
|
import FileUtilities.withTemporaryDirectory
|
||||||
|
|
||||||
|
object TestCompile
|
||||||
|
{
|
||||||
|
// skip 2.7.3 and 2.7.4 for speed
|
||||||
|
def allVersions = List("2.7.2", "2.7.5", "2.8.0-SNAPSHOT")//List("2.7.2", "2.7.3", "2.7.4", "2.7.5", "2.8.0-SNAPSHOT")
|
||||||
|
/** Tests running the compiler interface with the analyzer plugin with a test callback. The test callback saves all information
|
||||||
|
* that the plugin sends it for post-compile analysis by the provided function.*/
|
||||||
|
def apply[T](scalaVersion: String, sources: Set[File], outputDirectory: File, options: Seq[String], superclassNames: Seq[String])(f: (TestCallback, CompileLogger) => T): T =
|
||||||
|
{
|
||||||
|
val testCallback = new TestCallback(superclassNames.toArray)
|
||||||
|
val result = WithCompiler(scalaVersion) { (compiler, log) =>
|
||||||
|
compiler(sources, Set.empty, outputDirectory, options, testCallback, 5, log)
|
||||||
|
f(testCallback, log)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
/** Tests running the compiler interface with the analyzer plugin. The provided function is given a ClassLoader that can
|
||||||
|
* load the compiled classes..*/
|
||||||
|
def apply[T](scalaVersion: String, sources: Seq[File])(f: ClassLoader => T): T =
|
||||||
|
CallbackTest.apply(scalaVersion, sources, Nil){ case (callback, outputDir, log) => f(new URLClassLoader(Array(outputDir.toURI.toURL))) }
|
||||||
|
}
|
||||||
|
object CallbackTest
|
||||||
|
{
|
||||||
|
def apply[T](scalaVersion: String, sources: Iterable[File])(f: TestCallback => T): T =
|
||||||
|
apply(scalaVersion, sources.toSeq, Nil){ case (callback, outputDir, log) => f(callback) }
|
||||||
|
def apply[T](scalaVersion: String, sources: Seq[File], superclassNames: Seq[String])(f: (TestCallback, File, CompileLogger) => T): T =
|
||||||
|
withTemporaryDirectory { outputDir =>
|
||||||
|
TestCompile(scalaVersion, Set() ++ sources, outputDir, Nil, superclassNames) { case (callback, log) => f(callback, outputDir, log) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -109,7 +109,8 @@ class Launch(projectRootDirectory: File, mainClassName: String) extends Launcher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val scalaLoaderCache = new scala.collection.jcl.WeakHashMap[String, ClassLoader]
|
private val scalaLoaderCache = new scala.collection.mutable.HashMap[String, ClassLoader]
|
||||||
|
def clearScalaLoaderCache { scalaLoaderCache.clear() }
|
||||||
def launcher(directory: File, mainClassName: String): Launcher = new Launch(directory, mainClassName)
|
def launcher(directory: File, mainClassName: String): Launcher = new Launch(directory, mainClassName)
|
||||||
def getScalaLoader(scalaVersion: String) = scalaLoaderCache.getOrElseUpdate(scalaVersion, createScalaLoader(scalaVersion))
|
def getScalaLoader(scalaVersion: String) = scalaLoaderCache.getOrElseUpdate(scalaVersion, createScalaLoader(scalaVersion))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue