/** Adapted from https://github.com/sbt/sbt/blob/0.13/compile/interface/src/test/scala/xsbt/DependencySpecification.scala */
package xsbt
import org.junit.runner.RunWith
import xsbti.api.ClassLike
import xsbti.api.Def
import xsbt.api.SameAPI
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner
import ScalaCompilerForUnitTesting.ExtractedSourceDependencies
@RunWith(classOf[JUnitRunner])
class DependencySpecification extends Specification {
"Extracted source dependencies from public members" in {
val sourceDependencies = extractSourceDependenciesPublic
val memberRef = sourceDependencies.memberRef
val inheritance = sourceDependencies.inheritance
memberRef('A) === Set.empty
inheritance('A) === Set.empty
memberRef('B) === Set('A, 'D)
inheritance('B) === Set('D)
memberRef('C) === Set('A)
inheritance('C) === Set.empty
memberRef('D) === Set.empty
inheritance('D) === Set.empty
memberRef('E) === Set.empty
inheritance('E) === Set.empty
memberRef('F) === Set('A, 'B, 'C, 'D, 'E, 'G)
inheritance('F) === Set('A, 'E)
memberRef('H) === Set('B, 'E, 'G)
// aliases and applied type constructors are expanded so we have inheritance dependency on B
inheritance('H) === Set('B, 'E)
}
"Extracted source dependencies from private members" in {
val sourceDependencies = extractSourceDependenciesPrivate
val memberRef = sourceDependencies.memberRef
val inheritance = sourceDependencies.inheritance
memberRef('A) === Set.empty
inheritance('A) === Set.empty
memberRef('B) === Set.empty
inheritance('B) === Set.empty
memberRef('C) === Set('A)
inheritance('C) === Set('A)
memberRef('D) === Set('B)
inheritance('D) === Set('B)
}
"Extracted source dependencies with trait as first parent" in {
val sourceDependencies = extractSourceDependenciesTraitAsFirstPatent
val memberRef = sourceDependencies.memberRef
val inheritance = sourceDependencies.inheritance
memberRef('A) === Set.empty
inheritance('A) === Set.empty
memberRef('B) === Set('A)
inheritance('B) === Set('A)
// verify that memberRef captures the oddity described in documentation of `Relations.inheritance`
// we are mainly interested whether dependency on A is captured in `memberRef` relation so
// the invariant that says that memberRef is superset of inheritance relation is preserved
memberRef('C) === Set('A, 'B)
inheritance('C) === Set('A, 'B)
// same as above but indirect (C -> B -> A), note that only A is visible here
memberRef('D) === Set('A, 'C)
inheritance('D) === Set('A, 'C)
}
/*
"Extracted source dependencies from macro arguments" in {
val sourceDependencies = extractSourceDependenciesFromMacroArgument
val memberRef = sourceDependencies.memberRef
val inheritance = sourceDependencies.inheritance
memberRef('A) === Set('B, 'C)
inheritance('A) === Set.empty
memberRef('B) === Set.empty
inheritance('B) === Set.empty
memberRef('C) === Set.empty
inheritance('C) === Set.empty
}
*/
private def extractSourceDependenciesPublic: ExtractedSourceDependencies = {
val srcA = "class A"
val srcB = "class B extends D[A]"
val srcC = """|class C {
| def a: A = null
|}""".stripMargin
val srcD = "class D[T]"
val srcE = "trait E[T]"
val srcF = "trait F extends A with E[D[B]] { self: G.MyC => }"
val srcG = "object G { type T[x] = B ; type MyC = C }"
// T is a type constructor [x]B
// B extends D
// E verifies the core type gets pulled out
val srcH = "trait H extends G.T[Int] with (E[Int] @unchecked)"
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val sourceDependencies = compilerForTesting.extractDependenciesFromSrcs('A -> srcA, 'B -> srcB, 'C -> srcC,
'D -> srcD, 'E -> srcE, 'F -> srcF, 'G -> srcG, 'H -> srcH)
sourceDependencies
}
private def extractSourceDependenciesPrivate: ExtractedSourceDependencies = {
val srcA = "class A"
val srcB = "class B"
val srcC = "class C { private class Inner1 extends A }"
val srcD = "class D { def foo: Unit = { class Inner2 extends B } }"
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val sourceDependencies =
compilerForTesting.extractDependenciesFromSrcs('A -> srcA, 'B -> srcB, 'C -> srcC, 'D -> srcD)
sourceDependencies
}
private def extractSourceDependenciesTraitAsFirstPatent: ExtractedSourceDependencies = {
val srcA = "class A"
val srcB = "trait B extends A"
val srcC = "trait C extends B"
val srcD = "class D extends C"
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val sourceDependencies =
compilerForTesting.extractDependenciesFromSrcs('A -> srcA, 'B -> srcB, 'C -> srcC, 'D -> srcD)
sourceDependencies
}
/*
private def extractSourceDependenciesFromMacroArgument: ExtractedSourceDependencies = {
val srcA = "class A { println(B.printTree(C.foo)) }"
val srcB = """
|import scala.language.experimental.macros
|import scala.reflect.macros._
|object B {
| def printTree(arg: Any) = macro printTreeImpl
| def printTreeImpl(c: Context)(arg: c.Expr[Any]): c.Expr[String] = {
| val argStr = arg.tree.toString
| val literalStr = c.universe.Literal(c.universe.Constant(argStr))
| c.Expr[String](literalStr)
| }
|}""".stripMargin
val srcC = "object C { val foo = 1 }"
val compilerForTesting = new ScalaCompilerForUnitTesting(nameHashing = true)
val sourceDependencies =
compilerForTesting.extractDependenciesFromSrcs(List(Map('B -> srcB, 'C -> srcC), Map('A -> srcA)))
sourceDependencies
}
*/
}