Skip to content

Commit 3962d3c

Browse files
Merge pull request #6647 from dotty-staging/add-test-6642
Add test for #620
2 parents 8212f60 + 6465524 commit 3962d3c

File tree

7 files changed

+206
-59
lines changed

7 files changed

+206
-59
lines changed

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
783783
params ::: rest
784784
} else impl.body
785785

786-
val bodyText = " {" ~~ selfText ~~ toTextGlobal(primaryConstrs ::: body, "\n") ~ "}"
786+
val bodyText = " {" ~~ selfText ~ toTextGlobal(primaryConstrs ::: body, "\n") ~ "}"
787787

788788
prefix ~
789789
keywordText(" extends").provided(!ofNew && impl.parents.nonEmpty) ~~ parentsText ~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package dotty
2+
package tools
3+
package dotc
4+
5+
import vulpix.FileDiff
6+
import vulpix.TestConfiguration
7+
import vulpix.TestConfiguration
8+
import reporting.TestReporter
9+
10+
import java.io._
11+
import java.nio.file.{Path => JPath}
12+
import java.lang.System.{lineSeparator => EOL}
13+
14+
import interfaces.Diagnostic.INFO
15+
import dotty.tools.io.Directory
16+
17+
import scala.io.Source
18+
import org.junit.Test
19+
20+
class PrintingTest {
21+
val testsDir = "tests/printing"
22+
val options = List("-Xprint:frontend", "-color:never", "-classpath", TestConfiguration.basicClasspath)
23+
24+
private def fileContent(filePath: String): List[String] =
25+
if (new File(filePath).exists)
26+
Source.fromFile(filePath, "UTF-8").getLines().toList
27+
else Nil
28+
29+
30+
private def compileFile(path: JPath): Boolean = {
31+
val baseFilePath = path.toString.stripSuffix(".scala")
32+
val checkFilePath = baseFilePath + ".check"
33+
val byteStream = new ByteArrayOutputStream()
34+
val reporter = TestReporter.reporter(new PrintStream(byteStream), INFO)
35+
36+
try {
37+
Main.process((path.toString::options).toArray, reporter, null)
38+
} catch {
39+
case e: Throwable =>
40+
println(s"Compile $path exception:")
41+
e.printStackTrace()
42+
}
43+
44+
val actualLines = byteStream.toString("UTF-8").split("\\r?\\n")
45+
46+
FileDiff.checkAndDump(path.toString, actualLines, checkFilePath)
47+
}
48+
49+
@Test
50+
def printing: Unit = {
51+
val res = Directory(testsDir).list.toList
52+
.filter(f => f.extension == "scala")
53+
.map { f => compileFile(f.jpath) }
54+
55+
val failed = res.filter(!_)
56+
57+
val msg = s"Pass: ${res.length - failed.length}, Failed: ${failed.length}"
58+
59+
assert(failed.length == 0, msg)
60+
61+
println(msg)
62+
}
63+
}

compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala

+20-25
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,24 @@ package tools
33
package dotc
44
package transform
55

6+
import vulpix.FileDiff
67
import vulpix.TestConfiguration
8+
import reporting.TestReporter
9+
10+
import dotty.tools.io.Directory
711

812
import java.io._
913
import java.nio.file.{Path => JPath}
1014

1115
import scala.io.Source._
12-
import dotty.tools.io.Directory
1316
import org.junit.Test
14-
import reporting.TestReporter
15-
import vulpix.TestConfiguration
1617

1718
class PatmatExhaustivityTest {
1819
val testsDir = "tests/patmat"
1920
// stop-after: patmatexhaust-huge.scala crash compiler
2021
val options = List("-color:never", "-Ystop-after:crossCast", "-Ycheck-all-patmat", "-classpath", TestConfiguration.basicClasspath)
2122

22-
private def compileFile(path: JPath) = {
23+
private def compileFile(path: JPath): Boolean = {
2324
val stringBuffer = new StringWriter()
2425
val reporter = TestReporter.simplifiedReporter(new PrintWriter(stringBuffer))
2526

@@ -31,18 +32,18 @@ class PatmatExhaustivityTest {
3132
e.printStackTrace()
3233
}
3334

34-
val actual = stringBuffer.toString.trim.replaceAll("\\s+\n", "\n")
35-
val checkFilePath = path.toAbsolutePath.toString.stripSuffix(".scala") + ".check"
36-
val checkContent =
37-
if (new File(checkFilePath).exists)
38-
fromFile(checkFilePath).getLines().map(_.replaceAll("\\s+$", "")).mkString("\n").trim
39-
else ""
35+
val actualLines: Seq[String] = stringBuffer.toString.trim.replaceAll("\\s+\n", "\n") match {
36+
case "" => Nil
37+
case s => s.split("\\r?\\n")
38+
}
39+
val baseFilePath = path.toString.stripSuffix(".scala")
40+
val checkFilePath = baseFilePath + ".check"
4041

41-
(path, checkContent, actual)
42+
FileDiff.checkAndDump(path.toString, actualLines, checkFilePath)
4243
}
4344

4445
/** A single test with multiple files grouped in a folder */
45-
private def compileDir(path: JPath) = {
46+
private def compileDir(path: JPath): Boolean = {
4647
val stringBuffer = new StringWriter()
4748
val reporter = TestReporter.simplifiedReporter(new PrintWriter(stringBuffer))
4849

@@ -58,14 +59,14 @@ class PatmatExhaustivityTest {
5859
e.printStackTrace()
5960
}
6061

61-
val actual = stringBuffer.toString.trim.replaceAll("\\s+\n", "\n")
62+
val actualLines: Seq[String] = stringBuffer.toString.trim.replaceAll("\\s+\n", "\n") match {
63+
case "" => Nil
64+
case s => s.split("\\r?\\n")
65+
}
66+
6267
val checkFilePath = path + File.separator + "expected.check"
63-
val checkContent =
64-
if (new File(checkFilePath).exists)
65-
fromFile(checkFilePath).getLines().map(_.replaceAll("\\s+$", "")).mkString("\n").trim
66-
else ""
6768

68-
(path, checkContent, actual)
69+
FileDiff.checkAndDump(path.toString, actualLines, checkFilePath)
6970
}
7071

7172
@Test
@@ -79,15 +80,9 @@ class PatmatExhaustivityTest {
7980
compileFile(f.jpath)
8081
}
8182

82-
val failed = res.filter { case (_, expected, actual) => expected != actual }
83+
val failed = res.filter(!_)
8384
val ignored = Directory(testsDir).list.toList.filter(_.extension == "ignore")
8485

85-
failed.foreach { case (file, expected, actual) =>
86-
println(s"\n----------------- incorrect output for $file --------------\n" +
87-
s"Expected:\n---------\n$expected\n\nActual:\n-------\n$actual\n"
88-
)
89-
}
90-
9186
val msg = s"Total: ${res.length + ignored.length}, Failed: ${failed.length}, Ignored: ${ignored.length}"
9287

9388
assert(failed.length == 0, msg)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dotty.tools.vulpix
2+
3+
import scala.io.Source
4+
import java.io.File
5+
import java.lang.System.{lineSeparator => EOL}
6+
7+
object FileDiff {
8+
def diffMessage(expectFile: String, actualFile: String): String =
9+
s"""Test output dumped in: $actualFile
10+
| See diff of the checkfile (`brew install icdiff` for colored diff)
11+
| > diff $expectFile $actualFile
12+
| Replace checkfile with current output output
13+
| > mv $actualFile $expectFile
14+
""".stripMargin
15+
16+
def check(sourceTitle: String, outputLines: Seq[String], checkFile: String): Option[String] = {
17+
val checkLines =
18+
if (!(new File(checkFile)).exists) Nil
19+
else Source.fromFile(checkFile, "UTF-8").getLines().toList
20+
21+
def linesMatch =
22+
outputLines.length == checkLines.length &&
23+
(outputLines, checkLines).zipped.forall(_ == _)
24+
25+
if (!linesMatch) Some(
26+
s"""|Output from '$sourceTitle' did not match check file. Actual output:
27+
|${outputLines.mkString(EOL)}
28+
|""".stripMargin + "\n")
29+
else None
30+
}
31+
32+
def dump(path: String, content: Seq[String]): Unit = {
33+
val outFile = dotty.tools.io.File(path)
34+
outFile.writeAll(content.mkString("", EOL, EOL))
35+
}
36+
37+
def checkAndDump(sourceTitle: String, actualLines: Seq[String], checkFilePath: String): Boolean =
38+
FileDiff.check(sourceTitle, actualLines, checkFilePath) match {
39+
case Some(msg) =>
40+
val outFilePath = checkFilePath + ".out"
41+
FileDiff.dump(outFilePath, actualLines)
42+
println(msg)
43+
println(FileDiff.diffMessage(checkFilePath, outFilePath))
44+
false
45+
case _ =>
46+
true
47+
}
48+
}

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

+12-33
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,17 @@ trait ParallelTesting extends RunnerOrchestration { self =>
228228
* If not, fails the test.
229229
*/
230230
final def diffTest(testSource: TestSource, checkFile: JFile, actual: List[String], reporters: Seq[TestReporter], logger: LoggedRunnable) = {
231-
val expected = Source.fromFile(checkFile, "UTF-8").getLines().toList
232-
for (msg <- diffMessage(testSource.title, actual, expected)) {
231+
for (msg <- FileDiff.check(testSource.title, actual, checkFile.getPath)) {
233232
onFailure(testSource, reporters, logger, Some(msg))
234-
dumpOutputToFile(checkFile, actual)
233+
234+
if (updateCheckFiles) {
235+
FileDiff.dump(checkFile.toPath.toString, actual)
236+
echo("Updated checkfile: " + checkFile.getPath)
237+
} else {
238+
val outFile = checkFile.toPath.resolveSibling(checkFile.toPath.getFileName + ".out").toString
239+
FileDiff.dump(outFile, actual)
240+
echo(FileDiff.diffMessage(checkFile.getPath, outFile))
241+
}
235242
}
236243
}
237244

@@ -568,24 +575,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
568575
this
569576
}
570577

571-
protected def dumpOutputToFile(checkFile: JFile, lines: Seq[String]): Unit = {
572-
if (updateCheckFiles) {
573-
val outFile = dotty.tools.io.File(checkFile.toPath)
574-
outFile.writeAll(lines.mkString("", EOL, EOL))
575-
echo("Updated checkfile: " + checkFile.getPath)
576-
} else {
577-
val outFile = dotty.tools.io.File(checkFile.toPath.resolveSibling(checkFile.toPath.getFileName + ".out"))
578-
outFile.writeAll(lines.mkString("", EOL, EOL))
579-
echo(
580-
s"""Test output dumped in: ${outFile.path}
581-
| See diff of the checkfile
582-
| > diff $checkFile $outFile
583-
| Replace checkfile with current output output
584-
| > mv $outFile $checkFile
585-
""".stripMargin)
586-
}
587-
}
588-
589578
/** Returns all files in directory or the file if not a directory */
590579
private def flattenFiles(f: JFile): Array[JFile] =
591580
if (f.isDirectory) f.listFiles.flatMap(flattenFiles)
@@ -611,12 +600,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
611600

612601
private def verifyOutput(checkFile: Option[JFile], dir: JFile, testSource: TestSource, warnings: Int, reporters: Seq[TestReporter], logger: LoggedRunnable) = {
613602
if (Properties.testsNoRun) addNoRunWarning()
614-
else runMain(testSource.runClassPath) match {
603+
else runMain(testSource.runClassPath) match {
615604
case Success(output) => checkFile match {
616605
case Some(file) if file.exists => diffTest(testSource, file, output.linesIterator.toList, reporters, logger)
617606
case _ =>
618607
}
619-
case Failure(output) =>
608+
case Failure(output) =>
620609
echo(s"Test '${testSource.title}' failed with output:")
621610
echo(output)
622611
failTestSource(testSource)
@@ -712,16 +701,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
712701
override def maybeFailureMessage(testSource: TestSource, reporters: Seq[TestReporter]): Option[String] = None
713702
}
714703

715-
def diffMessage(sourceTitle: String, outputLines: Seq[String], checkLines: Seq[String]): Option[String] = {
716-
def linesMatch =
717-
(outputLines, checkLines).zipped.forall(_ == _)
718-
719-
if (outputLines.length != checkLines.length || !linesMatch) Some(
720-
s"""|Output from '$sourceTitle' did not match check file. Actual output:
721-
|${outputLines.mkString(EOL)}
722-
|""".stripMargin + "\n")
723-
else None
724-
}
725704

726705
/** The `CompilationTest` is the main interface to `ParallelTesting`, it
727706
* can be instantiated via one of the following methods:

tests/printing/i620.check

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
result of tests/printing/i620.scala after frontend:
2+
package O {
3+
package O.A {
4+
class D() extends Object() {
5+
class C() extends Object() {
6+
protected[D] def a: Int = 0
7+
private[D] def b: Int = 0
8+
private def c: Int = 0
9+
protected def d: Int = 0
10+
private[A] def e: Int = 0
11+
protected[A] def f: Int = 0
12+
def g: Int = 0
13+
}
14+
private[D] class E() extends Object() {}
15+
private class F() extends Object() {}
16+
private[A] class G() extends Object() {}
17+
protected[D] class H() extends Object() {}
18+
protected class I() extends Object() {}
19+
protected[A] class J() extends Object() {}
20+
class K() extends Object() {}
21+
protected[D] val a: Int = 0
22+
private[D] val b: Int = 0
23+
private val c: Int = 0
24+
protected val d: Int = 0
25+
private[A] val e: Int = 0
26+
protected[A] val f: Int = 0
27+
val g: Int = 0
28+
}
29+
}
30+
}

tests/printing/i620.scala

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// test printing of private[D] and protected[D]
2+
3+
package O
4+
package A
5+
6+
class D {
7+
class C {
8+
protected[D] def a: Int = 0
9+
private[D] def b: Int = 0
10+
private def c: Int = 0
11+
protected def d: Int = 0
12+
private[A] def e: Int = 0
13+
protected[A] def f: Int = 0
14+
def g: Int = 0
15+
}
16+
17+
private[D] class E
18+
private class F
19+
private[A] class G
20+
protected[D] class H
21+
protected class I
22+
protected[A] class J
23+
class K
24+
25+
protected[D] val a: Int = 0
26+
private[D] val b: Int = 0
27+
private val c: Int = 0
28+
protected val d: Int = 0
29+
private[A] val e: Int = 0
30+
protected[A] val f: Int = 0
31+
val g: Int = 0
32+
}

0 commit comments

Comments
 (0)