Skip to content

Commit c734eb3

Browse files
authored
Add test for scalac dependencies (#998)
* Add test for scalac dependencies * comment
1 parent 216874c commit c734eb3

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

third_party/dependency_analyzer/src/test/BUILD

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ scala_test(
3838
],
3939
)
4040

41+
scala_test(
42+
name = "scalac_dependency_test",
43+
size = "small",
44+
srcs = [
45+
"io/bazel/rulesscala/dependencyanalyzer/ScalacDependencyTest.scala",
46+
],
47+
jvm_flags = common_jvm_flags,
48+
unused_dependency_checker_mode = "off",
49+
deps = [
50+
"//external:io_bazel_rules_scala/dependency/scala/scala_compiler",
51+
"//external:io_bazel_rules_scala/dependency/scala/scala_library",
52+
"//external:io_bazel_rules_scala/dependency/scala/scala_reflect",
53+
"//third_party/dependency_analyzer/src/main:dependency_analyzer",
54+
"//third_party/utils/src/test:test_util",
55+
"@scalac_rules_commons_io//jar",
56+
],
57+
)
58+
4159
scala_test(
4260
name = "strict_deps_test",
4361
size = "small",
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package third_party.dependency_analyzer.src.test.io.bazel.rulesscala.dependencyanalyzer
2+
3+
import java.nio.file.Files
4+
import java.nio.file.Path
5+
import java.util.UUID
6+
import org.apache.commons.io.FileUtils
7+
import org.scalatest._
8+
import third_party.utils.src.test.io.bazel.rulesscala.utils.JavaCompileUtil
9+
import third_party.utils.src.test.io.bazel.rulesscala.utils.TestUtil
10+
11+
/**
12+
* Test that the scalac compiler behaves how we expect it to around
13+
* dependencies. That is, for given scenarios, we want to make sure
14+
* that scalac requires the given set of dependencies; no more and
15+
* no less.
16+
*
17+
* To clarify: these tests do not reflect the end result of strict/unused
18+
* deps as we are considering alternatives of how to mitigate scalac's
19+
* limitations.
20+
*/
21+
class ScalacDependencyTest extends FunSuite {
22+
private def withSandbox(action: Sandbox => Unit): Unit = {
23+
val tmpDir = Files.createTempDirectory("dependency_analyzer_test_temp")
24+
val file = tmpDir.toFile
25+
try {
26+
action(new Sandbox(tmpDir))
27+
} finally {
28+
FileUtils.deleteDirectory(file)
29+
}
30+
}
31+
32+
private class Sandbox(tmpDir: Path) {
33+
def compile(
34+
code: String
35+
): Unit = {
36+
val errors =
37+
TestUtil.runCompiler(
38+
code = code,
39+
extraClasspath = List(tmpDir.toString),
40+
outputPathOpt = Some(tmpDir)
41+
)
42+
assert(errors.isEmpty)
43+
}
44+
45+
def compileJava(
46+
className: String,
47+
code: String
48+
): Unit = {
49+
JavaCompileUtil.compile(
50+
tmpDir = tmpDir.toString,
51+
className = className,
52+
code = code
53+
)
54+
}
55+
56+
def checkExactDepsNeeded(
57+
code: String,
58+
deps: List[String]
59+
): Unit = {
60+
def doesCompileSucceed(usedDeps: List[String]): Boolean = {
61+
val subdir = tmpDir.resolve(UUID.randomUUID().toString)
62+
Files.createDirectory(subdir)
63+
usedDeps.foreach { dep =>
64+
val name = s"$dep.class"
65+
Files.copy(tmpDir.resolve(name), subdir.resolve(name))
66+
}
67+
val errors =
68+
TestUtil.runCompiler(
69+
code = code,
70+
extraClasspath = List(subdir.toString)
71+
)
72+
errors.isEmpty
73+
}
74+
75+
assert(doesCompileSucceed(deps), s"Failed to compile with all deps")
76+
77+
deps.foreach { toSkip =>
78+
val remaining = deps.filter(_ != toSkip)
79+
// sanity check we removed exactly one item
80+
assert(remaining.size + 1 == deps.size)
81+
assert(
82+
!doesCompileSucceed(remaining),
83+
s"Compile succeeded even though $toSkip was missing")
84+
}
85+
}
86+
}
87+
88+
test("static annotation of superclass not needed") {
89+
withSandbox { sandbox =>
90+
sandbox.compile("class A extends scala.annotation.StaticAnnotation")
91+
sandbox.compile("@A class B")
92+
sandbox.checkExactDepsNeeded(
93+
code = "class C extends B",
94+
deps = List("B")
95+
)
96+
}
97+
}
98+
99+
test("superclass of superclass needed") {
100+
withSandbox { sandbox =>
101+
sandbox.compile("class A")
102+
sandbox.compile("class B extends A")
103+
sandbox.checkExactDepsNeeded(
104+
code = "class C extends B",
105+
deps = List("A", "B")
106+
)
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)