aboutsummaryrefslogtreecommitdiff
path: root/sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala
diff options
context:
space:
mode:
Diffstat (limited to 'sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala')
-rw-r--r--sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala151
1 files changed, 151 insertions, 0 deletions
diff --git a/sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala b/sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala
new file mode 100644
index 000000000..60545091b
--- /dev/null
+++ b/sbt-bridge/src/test/scala/xsbt/DependencySpecification.scala
@@ -0,0 +1,151 @@
+/** 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
+ }
+ */
+}