mirror of https://github.com/sbt/sbt.git
Add support for unit testing of extracted source dependencies.
Add `extractDependenciesFromSrcs` method to ScalaCompilerForUnitTest class which allows us to unit test dependency extraction logic. See the comment attached to the method that explain the details of how it should be used.
This commit is contained in:
parent
89914975e1
commit
de1c5a4aed
|
|
@ -13,11 +13,13 @@ import xsbti.api.Def
|
|||
import xsbt.api.SameAPI
|
||||
import sbt.ConsoleLogger
|
||||
|
||||
import ScalaCompilerForUnitTesting.ExtractedSourceDependencies
|
||||
|
||||
/**
|
||||
* Provides common functionality needed for unit tests that require compiling
|
||||
* source code using Scala compiler.
|
||||
*/
|
||||
class ScalaCompilerForUnitTesting {
|
||||
class ScalaCompilerForUnitTesting(memberRefAndInheritanceDeps: Boolean = false) {
|
||||
|
||||
/**
|
||||
* Compiles given source code using Scala compiler and returns API representation
|
||||
|
|
@ -28,6 +30,43 @@ class ScalaCompilerForUnitTesting {
|
|||
analysisCallback.apis(tempSrcFile)
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles given source code snippets (passed as Strings) using Scala compiler and returns extracted
|
||||
* dependencies between snippets. Source code snippets are identified by symbols. Each symbol should
|
||||
* be associated with one snippet only.
|
||||
*
|
||||
* Symbols are used to express extracted dependencies between source code snippets. This way we have
|
||||
* file system-independent way of testing dependencies between source code "files".
|
||||
*/
|
||||
def extractDependenciesFromSrcs(srcs: (Symbol, String)*): ExtractedSourceDependencies = {
|
||||
val (symbolsForSrcs, rawSrcs) = srcs.unzip
|
||||
assert(symbolsForSrcs.distinct.size == symbolsForSrcs.size,
|
||||
s"Duplicate symbols for srcs detected: $symbolsForSrcs")
|
||||
val (tempSrcFiles, testCallback) = compileSrcs(rawSrcs: _*)
|
||||
val fileToSymbol = (tempSrcFiles zip symbolsForSrcs).toMap
|
||||
val memberRefFileDeps = testCallback.sourceDependencies collect {
|
||||
// false indicates that those dependencies are not introduced by inheritance
|
||||
case (target, src, false) => (src, target)
|
||||
}
|
||||
val inheritanceFileDeps = testCallback.sourceDependencies collect {
|
||||
// true indicates that those dependencies are introduced by inheritance
|
||||
case (target, src, true) => (src, target)
|
||||
}
|
||||
def toSymbols(src: File, target: File): (Symbol, Symbol) = (fileToSymbol(src), fileToSymbol(target))
|
||||
val memberRefDeps = memberRefFileDeps map { case (src, target) => toSymbols(src, target) }
|
||||
val inheritanceDeps = inheritanceFileDeps map { case (src, target) => toSymbols(src, target) }
|
||||
def pairsToMultiMap[A, B](pairs: Seq[(A, B)]): Map[A, Set[B]] = {
|
||||
import scala.collection.mutable.{HashMap, MultiMap}
|
||||
val emptyMultiMap = new HashMap[A, scala.collection.mutable.Set[B]] with MultiMap[A, B]
|
||||
val multiMap = pairs.foldLeft(emptyMultiMap) { case (acc, (key, value)) =>
|
||||
acc.addBinding(key, value)
|
||||
}
|
||||
// convert all collections to immutable variants
|
||||
multiMap.toMap.mapValues(_.toSet).withDefaultValue(Set.empty)
|
||||
}
|
||||
ExtractedSourceDependencies(pairsToMultiMap(memberRefDeps), pairsToMultiMap(inheritanceDeps))
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles given source code snippets written to a temporary files. Each snippet is
|
||||
* written to a separate temporary file.
|
||||
|
|
@ -37,7 +76,7 @@ class ScalaCompilerForUnitTesting {
|
|||
*/
|
||||
private def compileSrcs(srcs: String*): (Seq[File], TestCallback) = {
|
||||
withTemporaryDirectory { temp =>
|
||||
val analysisCallback = new TestCallback
|
||||
val analysisCallback = new TestCallback(memberRefAndInheritanceDeps)
|
||||
val classesDir = new File(temp, "classes")
|
||||
classesDir.mkdir()
|
||||
val compiler = prepareCompiler(classesDir, analysisCallback)
|
||||
|
|
@ -53,12 +92,8 @@ class ScalaCompilerForUnitTesting {
|
|||
}
|
||||
|
||||
private def prepareSrcFile(baseDir: File, fileName: String, src: String): File = {
|
||||
import java.io.FileWriter
|
||||
val srcFile = new File(baseDir, fileName)
|
||||
srcFile.createNewFile()
|
||||
val fw = new FileWriter(srcFile)
|
||||
fw.write(src)
|
||||
fw.close()
|
||||
sbt.IO.write(srcFile, src)
|
||||
srcFile
|
||||
}
|
||||
|
||||
|
|
@ -90,3 +125,7 @@ class ScalaCompilerForUnitTesting {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
object ScalaCompilerForUnitTesting {
|
||||
case class ExtractedSourceDependencies(memberRef: Map[Symbol, Set[Symbol]], inheritance: Map[Symbol, Set[Symbol]])
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue