Skip to content

Commit d544c1c

Browse files
committed
Add link tests
1 parent af85ec4 commit d544c1c

31 files changed

+215
-8
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class ScalaSettings extends Settings.SettingGroup {
102102
val YcheckAllPatmat = BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm)")
103103
val YretainTrees = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
104104
val YshowTreeIds = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
105+
val YRunClasspath = PathSetting("-YRunClasspath", "Specify where to find user class files while executing run tests.", defaultClasspath)
105106

106107
/** Area-specific debug output */
107108
val Yexplainlowlevel = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tools
33
package dotc
44

55
import org.junit.{ Test, BeforeClass, AfterClass }
6+
import org.junit.Assert._
67

78
import java.nio.file._
89
import java.util.stream.{ Stream => JStream }
@@ -11,6 +12,7 @@ import scala.util.matching.Regex
1112
import scala.concurrent.duration._
1213

1314
import vulpix.{ ParallelTesting, SummaryReport, SummaryReporting, TestConfiguration }
15+
import dotty.tools.io.JFile
1416

1517

1618
class CompilationTests extends ParallelTesting {
@@ -29,7 +31,6 @@ class CompilationTests extends ParallelTesting {
2931

3032
@Test def compilePos: Unit = {
3133
compileList("compileStdLib", StdLibSources.whitelisted, scala2Mode.and("-migration", "-Yno-inline")) +
32-
compileDir("../collection-strawman/src/main", defaultOptions) +
3334
compileDir("../compiler/src/dotty/tools/dotc/ast", defaultOptions) +
3435
compileDir("../compiler/src/dotty/tools/dotc/config", defaultOptions) +
3536
compileDir("../compiler/src/dotty/tools/dotc/core", allowDeepSubtypes) +
@@ -293,6 +294,60 @@ class CompilationTests extends ParallelTesting {
293294
tests.foreach(_.delete())
294295
}
295296

297+
@Test def linkAll: Unit = {
298+
299+
// Setup and compile libraries
300+
def strawmanLibrary =
301+
compileDir("../collection-strawman/src/main", defaultOptions)
302+
def linkCustomLib =
303+
compileDir("../tests/link/custom-lib", defaultOptions)
304+
305+
val libraries = {
306+
strawmanLibrary +
307+
linkCustomLib
308+
}.keepOutput.checkCompile()
309+
310+
311+
def mkLinkClassPath(libPath: String) =
312+
mkClassPath(libPath :: Jars.dottyTestDeps) ++ mkClassPath(Jars.dottyTestDeps, "-YRunClasspath")
313+
314+
val strawmanClassPath = mkLinkClassPath(defaultOutputDir + "strawmanLibrary/main/")
315+
val customLibClassPath = mkLinkClassPath(defaultOutputDir + "linkCustomLib/custom-lib")
316+
317+
// Link tests
318+
val linkDir = "../tests/link"
319+
val linkStramanDir = linkDir + "/strawman"
320+
val linkCustomLibDir = linkDir + "/on-custom-lib"
321+
def linkStrawmanTest = compileFilesInDir(linkStramanDir, basicLinkOptimise ++ strawmanClassPath)
322+
def linkCustomLibTest = compileFilesInDir(linkCustomLibDir, basicLinkOptimise ++ customLibClassPath)
323+
324+
def classFileChecks(sourceDir: String, testName: String) = {
325+
val checkExt = ".classcheck"
326+
for (check <- new JFile(sourceDir).listFiles().filter(_.toString.endsWith(checkExt))) {
327+
val outDir = {
328+
def path(str: String) = str.substring(linkDir.length, str.length - checkExt.length)
329+
defaultOutputDir + testName + path(check.toString) + "/"
330+
}
331+
val expectedClasses = scala.io.Source.fromFile(check).getLines().toSet
332+
val actualClasses = Files.walk(Paths.get(outDir)).iterator().asScala.collect {
333+
case f if f.toString.endsWith(".class") => f.toString.substring(outDir.length, f.toString.length - ".class".length)
334+
}.toSet
335+
assertEquals(check.toString, expectedClasses, actualClasses)
336+
}
337+
}
338+
339+
// Run all tests
340+
val tests = {
341+
linkStrawmanTest +
342+
linkCustomLibTest
343+
}.keepOutput.checkRuns()
344+
345+
classFileChecks(linkStramanDir, "linkStrawmanTest")
346+
classFileChecks(linkCustomLibDir, "linkCustomLibTest")
347+
348+
(libraries + tests).delete()
349+
}
350+
296351
/** Add a `z` so that they run last. TODO: Only run them selectively? */
297352
@Test def zBytecodeIdempotency: Unit = {
298353
val opt = defaultOptions.and("-YemitTasty")

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ trait ParallelTesting extends RunnerOrchestration { self =>
6161
.map(":" + _)
6262
.getOrElse("")
6363

64+
def runClassPath = {
65+
flags
66+
.dropWhile(_ != "-YRunClasspath")
67+
.drop(1)
68+
.headOption
69+
.map(outDir.getAbsolutePath + ":" + _)
70+
.getOrElse(classPath)
71+
}
6472

6573
def title: String = self match {
6674
case self: JointCompilationSource =>
@@ -481,7 +489,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
481489

482490
private def verifyOutput(checkFile: Option[JFile], dir: JFile, testSource: TestSource, warnings: Int) = {
483491
if (Properties.testsNoRun) addNoRunWarning()
484-
else runMain(testSource.classPath) match {
492+
else runMain(testSource.runClassPath) match {
485493
case Success(_) if !checkFile.isDefined || !checkFile.get.exists => // success!
486494
case Success(output) => {
487495
val outputLines = output.lines.toArray
@@ -1079,8 +1087,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10791087
* `testName` since files can be in separate directories and or be otherwise
10801088
* dissociated
10811089
*/
1082-
def compileList(testName: String, files: List[String], flags: Array[String])(implicit outDirectory: String): CompilationTest = {
1083-
val callingMethod = getCallingMethod()
1090+
def compileList(testName: String, files: List[String], flags: Array[String], callingMethod: String = getCallingMethod())(implicit outDirectory: String): CompilationTest = {
10841091
val outDir = outDirectory + callingMethod + "/" + testName + "/"
10851092

10861093
// Directories in which to compile all containing files with `flags`:

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ object TestConfiguration {
2323
"-Yforce-sbt-phases"
2424
)
2525

26-
val classPath = {
27-
val paths = Jars.dottyTestDeps map { p =>
26+
val classPath = mkClassPath(Jars.dottyTestDeps)
27+
28+
def mkClassPath(classPaths: List[String], classPathFlag: String = "-classpath"): Array[String] = {
29+
val paths = classPaths map { p =>
2830
val file = new java.io.File(p)
2931
assert(
3032
file.exists,
@@ -47,12 +49,13 @@ object TestConfiguration {
4749
file.getAbsolutePath
4850
} mkString (":")
4951

50-
Array("-classpath", paths)
52+
Array(classPathFlag, paths)
5153
}
5254

5355
private val yCheckOptions = Array("-Ycheck:tailrec,resolveSuper,mixin,arrayConstructors,labelDef")
5456

55-
val defaultUnoptimised = noCheckOptions ++ checkOptions ++ yCheckOptions ++ classPath
57+
val basicDefaultOptions = noCheckOptions ++ checkOptions ++ yCheckOptions
58+
val defaultUnoptimised = basicDefaultOptions ++ classPath
5659
val defaultOptimised = defaultUnoptimised :+ "-optimise"
5760
val defaultOptions = defaultUnoptimised
5861
val allowDeepSubtypes = defaultOptions diff Array("-Yno-deep-subtypes")
@@ -65,4 +68,5 @@ object TestConfiguration {
6568
val scala2Mode = defaultOptions ++ Array("-language:Scala2")
6669
val explicitUTF8 = defaultOptions ++ Array("-encoding", "UTF8")
6770
val explicitUTF16 = defaultOptions ++ Array("-encoding", "UTF16")
71+
val basicLinkOptimise = basicDefaultOptions ++ Array("-Xlink-optimise")
6872
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class EmptyClass
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
object EmptyObject
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
trait EmptyTrait

tests/link/custom-lib/Map2.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Map2[K] {
2+
def get(k: K): K = k
3+
def foo: K = {
4+
this match {
5+
case that: Map2[b] => that.get(3.asInstanceOf[b])
6+
case _ => get(5.asInstanceOf[K])
7+
}
8+
}
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package object foo {
2+
def bar = 42
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
EmptyClass
2+
Test
3+
Test$
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
new EmptyClass
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
EmptyObject
2+
EmptyObject$
3+
Test
4+
Test$
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
EmptyObject
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
EmptyClass
2+
MyClass
3+
Test
4+
Test$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
new MyClass
4+
}
5+
}
6+
7+
class MyClass extends EmptyClass
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
EmptyTrait
2+
MyClass
3+
Test
4+
Test$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
new MyClass
4+
}
5+
}
6+
7+
class MyClass extends EmptyTrait
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
foo/package
2+
foo/package$
3+
Test
4+
Test$
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
println(foo.bar)
4+
}
5+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Test
2+
Test$

tests/link/on-custom-lib/map2.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
// FIMXE
4+
// val map2 = new Map2[Int] {}
5+
// println(map2.foo)
6+
}
7+
}

tests/link/strawman/hashing.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-106205
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
strawman/collection/Hash
2+
strawman/collection/Hash$
3+
strawman/collection/Hashing
4+
strawman/collection/Hashing$
5+
Test
6+
Test$

tests/link/strawman/hashing.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
println(strawman.collection.Hash.hash(42))
4+
}
5+
}
6+
7+
package strawman {
8+
package collection {
9+
object Hash {
10+
def hash(n: Int) = Hashing.computeHash(n)
11+
}
12+
}
13+
}

tests/link/strawman/iterator-1.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
true
2+
3
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Test
2+
Test$

tests/link/strawman/iterator-1.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import strawman.collection.Iterator
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
// FIXME: issue loading package object
6+
// val it = new MyIterator
7+
// println(it.hasNext)
8+
// println(it.next())
9+
println(true)
10+
println(3)
11+
}
12+
}
13+
14+
//class MyIterator extends Iterator[Int] {
15+
// override def hasNext: Boolean = true
16+
// override def next(): Int = 3
17+
//}

tests/link/strawman/nil.classcheck

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Test
2+
Test$

tests/link/strawman/nil.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
// FIXME
4+
// strawman.collection.immutable.Nil
5+
}
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
strawman/collection/immutable/RedBlack
2+
strawman/collection/immutable/RedBlack$
3+
Test
4+
Test$

tests/link/strawman/red-black.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
strawman.collection.immutable.RedBlack
4+
}
5+
}
6+
7+
package strawman {
8+
package collection {
9+
package immutable {
10+
object RedBlack {
11+
// RedBlackTree
12+
}
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)