Skip to content

Commit 6f82c22

Browse files
committed
Merge pull request #1122 from dotty-staging/neg-lines-2
Neg tests: remove xerror parameter from neg tests (#1110)
2 parents af8fc52 + 2b8cd5a commit 6f82c22

15 files changed

+101
-139
lines changed

test/dotc/tests.scala

Lines changed: 14 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -108,87 +108,22 @@ class tests extends CompilerTest {
108108

109109
@Test def new_all = compileFiles(newDir, twice)
110110

111-
@Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2)
112-
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1)
113-
@Test def neg_bounds() = compileFile(negDir, "bounds", xerrors = 2)
114-
@Test def neg_functionArity() = compileFile(negDir, "function-arity", xerrors = 7)
115-
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 3)
116-
@Test def neg_typedIdents() = compileDir(negDir, "typedIdents", xerrors = 2)
117-
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)
118-
@Test def neg_typers() = compileFile(negDir, "typers", xerrors = 14)(allowDoubleBindings)
119-
@Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2)
120-
@Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2)
121-
@Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3)
122-
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil, xerrors = 3)
123-
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
124-
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
125-
@Test def namedParams = compileFile(negDir, "named-params", xerrors = 14)
126-
@Test def neg_over = compileFile(negDir, "over", xerrors = 3)
127-
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 14)
128-
@Test def neg_overrideClass = compileFile(negDir, "overrideClass", List("-language:Scala2"), xerrors = 1)
129-
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 2)
130-
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 3)
131-
@Test def neg_zoo = compileFile(negDir, "zoo", xerrors = 12)
111+
@Test def neg_all = compileFiles(negDir, verbose = true, compileSubDirs = false)
112+
@Test def neg_typedIdents() = compileDir(negDir, "typedIdents")
113+
114+
val negCustomArgs = negDir + "customArgs/"
115+
@Test def neg_typers() = compileFile(negCustomArgs, "typers")(allowDoubleBindings)
116+
@Test def neg_overrideClass = compileFile(negCustomArgs, "overrideClass", List("-language:Scala2"))
117+
@Test def neg_autoTupling = compileFile(negCustomArgs, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil)
118+
@Test def neg_i1050 = compileFile(negCustomArgs, "i1050", List("-strict"))
132119

133120
val negTailcallDir = negDir + "tailcall/"
134-
@Test def neg_tailcall_t1672b = compileFile(negTailcallDir, "t1672b", xerrors = 5)
135-
@Test def neg_tailcall_t3275 = compileFile(negTailcallDir, "t3275", xerrors = 1)
136-
@Test def neg_tailcall_t6574 = compileFile(negTailcallDir, "t6574", xerrors = 2)
137-
@Test def neg_tailcall = compileFile(negTailcallDir, "tailrec", xerrors = 7)
138-
@Test def neg_tailcall2 = compileFile(negTailcallDir, "tailrec-2", xerrors = 2)
139-
@Test def neg_tailcall3 = compileFile(negTailcallDir, "tailrec-3", xerrors = 2)
140-
141-
@Test def neg_t1843_variances = compileFile(negDir, "t1843-variances", xerrors = 1)
142-
@Test def neg_t2660_ambi = compileFile(negDir, "t2660", xerrors = 2)
143-
@Test def neg_t2994 = compileFile(negDir, "t2994", xerrors = 2)
144-
@Test def neg_subtyping = compileFile(negDir, "subtyping", xerrors = 5)
145-
@Test def neg_variances = compileFile(negDir, "variances", xerrors = 2)
146-
@Test def neg_variancesConstr = compileFile(negDir, "variances-constr", xerrors = 2)
147-
@Test def neg_i871_missingReturnType = compileFile(negDir, "i871", xerrors = 2)
148-
@Test def neg_badAuxConstr = compileFile(negDir, "badAuxConstr", xerrors = 2)
149-
@Test def neg_typetest = compileFile(negDir, "typetest", xerrors = 1)
150-
@Test def neg_t1569_failedAvoid = compileFile(negDir, "t1569-failedAvoid", xerrors = 1)
151-
@Test def neg_clashes = compileFile(negDir, "clashes", xerrors = 2)
152-
@Test def neg_cycles = compileFile(negDir, "cycles", xerrors = 7)
153-
@Test def neg_boundspropagation = compileFile(negDir, "boundspropagation", xerrors = 5)
154-
@Test def neg_refinedSubtyping = compileFile(negDir, "refinedSubtyping", xerrors = 2)
155-
@Test def neg_hklower = compileFile(negDir, "hklower", xerrors = 4)
156-
@Test def neg_Iter2 = compileFile(negDir, "Iter2", xerrors = 2)
157-
@Test def neg_i0091_infpaths = compileFile(negDir, "i0091-infpaths", xerrors = 3)
158-
@Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 4)
159-
@Test def neg_i0281 = compileFile(negDir, "i0281-null-primitive-conforms", xerrors = 3)
160-
@Test def neg_i324 = compileFile(negDir, "i324", xerrors = 2)
161-
@Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2)
162-
@Test def neg_i941 = compileFile(negDir, "i941", xerrors = 3)
163-
@Test def neg_finalSealed = compileFile(negDir, "final-sealed", xerrors = 2)
164-
@Test def neg_i645 = compileFile(negDir, "amp", xerrors = 4)
165-
@Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 7)
166-
@Test def neg_i803 = compileFile(negDir, "i803", xerrors = 2)
167-
@Test def neg_i866 = compileFile(negDir, "i866", xerrors = 2)
168-
@Test def neg_i974 = compileFile(negDir, "i974", xerrors = 2)
169-
@Test def neg_i997 = compileFile(negDir, "i997", xerrors = 15)
170-
@Test def neg_i997a = compileFile(negDir, "i997a", xerrors = 2)
171-
@Test def neg_i1050 = compileFile(negDir, "i1050", List("-strict"), xerrors = 11)
172-
@Test def neg_i1050a = compileFile(negDir, "i1050a", xerrors = 2)
173-
@Test def neg_i1050c = compileFile(negDir, "i1050c", xerrors = 8)
174-
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
175-
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
176-
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
177-
@Test def neg_partialApplications = compileFile(negDir, "partialApplications", xerrors = 3)
178-
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 6)
179-
@Test def neg_selfreq = compileFile(negDir, "selfreq", xerrors = 2)
180-
@Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 8)
181-
@Test def neg_ski = compileFile(negDir, "ski", xerrors = 12)
182-
@Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5)
183-
@Test def neg_traitParamsMixin = compileFile(negDir, "traitParamsMixin", xerrors = 2)
184-
@Test def neg_firstError = compileFile(negDir, "firstError", xerrors = 3)
185-
@Test def neg_implicitLowerBound = compileFile(negDir, "implicit-lower-bound", xerrors = 1)
186-
@Test def neg_validate = compileFile(negDir, "validate", xerrors = 18)
187-
@Test def neg_validateParsing = compileFile(negDir, "validate-parsing", xerrors = 7)
188-
@Test def neg_validateRefchecks = compileFile(negDir, "validate-refchecks", xerrors = 2)
189-
@Test def neg_skolemize = compileFile(negDir, "skolemize", xerrors = 2)
190-
@Test def neg_nested_bounds = compileFile(negDir, "nested_bounds", xerrors = 1)
191-
@Test def neg_valueClasses = compileFile(negDir, "valueClasses", xerrors = 2)
121+
@Test def neg_tailcall_t1672b = compileFile(negTailcallDir, "t1672b")
122+
@Test def neg_tailcall_t3275 = compileFile(negTailcallDir, "t3275")
123+
@Test def neg_tailcall_t6574 = compileFile(negTailcallDir, "t6574")
124+
@Test def neg_tailcall = compileFile(negTailcallDir, "tailrec")
125+
@Test def neg_tailcall2 = compileFile(negTailcallDir, "tailrec-2")
126+
@Test def neg_tailcall3 = compileFile(negTailcallDir, "tailrec-3")
192127

193128
@Test def run_all = runFiles(runDir)
194129

test/test/CompilerTest.scala

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ abstract class CompilerTest {
4343
val defaultOutputDir: String
4444

4545
/** Override to filter out tests that should not be run by partest. */
46-
def partestableFile(prefix: String, fileName: String, extension: String, args: List[String], xerrors: Int) = true
47-
def partestableDir(prefix: String, dirName: String, args: List[String], xerrors: Int) = true
48-
def partestableList(testName: String, files: List[String], args: List[String], xerrors: Int) = true
46+
def partestableFile(prefix: String, fileName: String, extension: String, args: List[String]) = true
47+
def partestableDir(prefix: String, dirName: String, args: List[String]) = true
48+
def partestableList(testName: String, files: List[String], args: List[String]) = true
4949

5050
val generatePartestFiles = {
5151
/* Because we fork in test, the JVM in which this JUnit test runs has a
@@ -68,70 +68,80 @@ abstract class CompilerTest {
6868
val logFile = if (!generatePartestFiles) None else Some(CompilerTest.init)
6969

7070
/** Always run with JUnit. */
71-
def compileLine(cmdLine: String, xerrors: Int = 0)(implicit defaultOptions: List[String]): Unit = {
71+
def compileLine(cmdLine: String)(implicit defaultOptions: List[String]): Unit = {
7272
if (generatePartestFiles)
7373
log("WARNING: compileLine will always run with JUnit, no partest files generated.")
74-
compileArgs(cmdLine.split("\n"), xerrors)
74+
compileArgs(cmdLine.split("\n"), Nil)
7575
}
7676

7777
/** Compiles the given code file.
7878
*
7979
* @param prefix the parent directory (including separator at the end)
8080
* @param fileName the filename, by default without extension
8181
* @param args arguments to the compiler
82-
* @param xerrors if > 0, this test is a neg test with the expected number
83-
* of compiler errors. Otherwise, this is a pos test.
8482
* @param extension the file extension, .scala by default
8583
* @param defaultOptions more arguments to the compiler
8684
*/
87-
def compileFile(prefix: String, fileName: String, args: List[String] = Nil, xerrors: Int = 0,
88-
extension: String = ".scala", runTest: Boolean = false)
85+
def compileFile(prefix: String, fileName: String, args: List[String] = Nil, extension: String = ".scala", runTest: Boolean = false)
8986
(implicit defaultOptions: List[String]): Unit = {
90-
if (!generatePartestFiles || !partestableFile(prefix, fileName, extension, args ++ defaultOptions, xerrors)) {
87+
val filePath = s"$prefix$fileName$extension"
88+
val expErrors = expectedErrors(filePath)
89+
if (!generatePartestFiles || !partestableFile(prefix, fileName, extension, args ++ defaultOptions)) {
9190
if (runTest)
9291
log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$fileName$extension")
93-
compileArgs((s"$prefix$fileName$extension" :: args).toArray, xerrors)
92+
compileArgs((s"$filePath" :: args).toArray, expErrors)
9493
} else {
95-
val kind = testKind(prefix, xerrors, runTest)
94+
val kind = testKind(prefix, runTest)
9695
log(s"generating partest files for test file: $prefix$fileName$extension of kind $kind")
9796

9897
val sourceFile = new JFile(prefix + fileName + extension)
9998
if (sourceFile.exists) {
10099
val firstDest = SFile(DPConfig.testRoot + JFile.separator + kind + JFile.separator + fileName + extension)
100+
val xerrors = expErrors.map(_.totalErrors).sum
101101
computeDestAndCopyFiles(sourceFile, firstDest, kind, args ++ defaultOptions, xerrors.toString)
102102
} else {
103103
throw new java.io.FileNotFoundException(s"Unable to locate test file $prefix$fileName")
104104
}
105105
}
106106
}
107-
def runFile(prefix: String, fileName: String, args: List[String] = Nil, xerrors: Int = 0,
108-
extension: String = ".scala")(implicit defaultOptions: List[String]): Unit =
109-
compileFile(prefix, fileName, args, xerrors, extension, true)
107+
def runFile(prefix: String, fileName: String, args: List[String] = Nil, extension: String = ".scala")
108+
(implicit defaultOptions: List[String]): Unit = {
109+
compileFile(prefix, fileName, args, extension, true)
110+
}
110111

111112
/** Compiles the code files in the given directory together. If args starts
112113
* with "-deep", all files in subdirectories (and so on) are included. */
113-
def compileDir(prefix: String, dirName: String, args: List[String] = Nil, xerrors: Int = 0, runTest: Boolean = false)
114+
def compileDir(prefix: String, dirName: String, args: List[String] = Nil, runTest: Boolean = false)
114115
(implicit defaultOptions: List[String]): Unit = {
115-
if (!generatePartestFiles || !partestableDir(prefix, dirName, args ++ defaultOptions, xerrors)) {
116-
if (runTest)
117-
log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$dirName")
116+
def computeFilePathsAndExpErrors = {
118117
val dir = Directory(prefix + dirName)
119118
val (files, normArgs) = args match {
120119
case "-deep" :: args1 => (dir.deepFiles, args1)
121120
case _ => (dir.files, args)
122121
}
123-
val fileNames = files.toArray.map(_.toString).filter(name => (name endsWith ".scala") || (name endsWith ".java"))
124-
compileArgs(fileNames ++ normArgs, xerrors)
122+
val filePaths = files.toArray.map(_.toString).filter(name => (name endsWith ".scala") || (name endsWith ".java"))
123+
val expErrors = expectedErrors(filePaths.toList)
124+
(filePaths, normArgs, expErrors)
125+
}
126+
if (!generatePartestFiles || !partestableDir(prefix, dirName, args ++ defaultOptions)) {
127+
if (runTest)
128+
log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$dirName")
129+
val (filePaths, normArgs, expErrors) = computeFilePathsAndExpErrors
130+
compileArgs(filePaths ++ normArgs, expErrors)
125131
} else {
126132
val (sourceDir, flags, deep) = args match {
127133
case "-deep" :: args1 => (flattenDir(prefix, dirName), args1 ++ defaultOptions, "deep")
128134
case _ => (new JFile(prefix + dirName), args ++ defaultOptions, "shallow")
129135
}
130-
val kind = testKind(prefix, xerrors, runTest)
136+
val kind = testKind(prefix, runTest)
131137
log(s"generating partest files for test directory ($deep): $prefix$dirName of kind $kind")
132138

133139
if (sourceDir.exists) {
134140
val firstDest = Directory(DPConfig.testRoot + JFile.separator + kind + JFile.separator + dirName)
141+
val xerrors = if (isNegTest(prefix)) {
142+
val (_, _, expErrors) = computeFilePathsAndExpErrors
143+
expErrors.map(_.totalErrors).sum
144+
} else 0
135145
computeDestAndCopyFiles(sourceDir, firstDest, kind, flags, xerrors.toString)
136146
if (deep == "deep")
137147
Directory(sourceDir).deleteRecursively
@@ -140,67 +150,73 @@ abstract class CompilerTest {
140150
}
141151
}
142152
}
143-
def runDir(prefix: String, dirName: String, args: List[String] = Nil, xerrors: Int = 0)
153+
def runDir(prefix: String, dirName: String, args: List[String] = Nil)
144154
(implicit defaultOptions: List[String]): Unit =
145-
compileDir(prefix, dirName, args, xerrors, true)
155+
compileDir(prefix, dirName, args, true)
146156

147157
/** Compiles each source in the directory path separately by calling
148158
* compileFile resp. compileDir. */
149-
def compileFiles(path: String, args: List[String] = Nil, verbose: Boolean = true, runTest: Boolean = false)
150-
(implicit defaultOptions: List[String]): Unit = {
159+
def compileFiles(path: String, args: List[String] = Nil, verbose: Boolean = true, runTest: Boolean = false,
160+
compileSubDirs: Boolean = true)(implicit defaultOptions: List[String]): Unit = {
151161
val dir = Directory(path)
152162
val fileNames = dir.files.toArray.map(_.jfile.getName).filter(name => (name endsWith ".scala") || (name endsWith ".java"))
153163
for (name <- fileNames) {
154164
if (verbose) log(s"testing $path$name")
155-
compileFile(path, name, args, 0, "", runTest)
156-
}
157-
for (subdir <- dir.dirs) {
158-
if (verbose) log(s"testing $subdir")
159-
compileDir(path, subdir.jfile.getName, args, 0, runTest)
165+
compileFile(path, name, args, "", runTest)
160166
}
167+
if (compileSubDirs)
168+
for (subdir <- dir.dirs) {
169+
if (verbose) log(s"testing $subdir")
170+
compileDir(path, subdir.jfile.getName, args, runTest)
171+
}
161172
}
162173
def runFiles(path: String, args: List[String] = Nil, verbose: Boolean = true)
163174
(implicit defaultOptions: List[String]): Unit =
164175
compileFiles(path, args, verbose, true)
165176

166177
/** Compiles the given list of code files. */
167-
def compileList(testName: String, files: List[String], args: List[String] = Nil, xerrors: Int = 0)
178+
def compileList(testName: String, files: List[String], args: List[String] = Nil)
168179
(implicit defaultOptions: List[String]): Unit = {
169-
if (!generatePartestFiles || !partestableList(testName, files, args ++ defaultOptions, xerrors)) {
170-
compileArgs((files ++ args).toArray, xerrors)
180+
if (!generatePartestFiles || !partestableList(testName, files, args ++ defaultOptions)) {
181+
val expErrors = expectedErrors(files)
182+
compileArgs((files ++ args).toArray, expErrors)
171183
} else {
172184
val destDir = Directory(DPConfig.testRoot + JFile.separator + testName)
173185
files.foreach({ file =>
174186
val jfile = new JFile(file)
175187
recCopyFiles(jfile, destDir / jfile.getName)
176188
})
177-
compileDir(DPConfig.testRoot + JFile.separator, testName, args, xerrors)
189+
compileDir(DPConfig.testRoot + JFile.separator, testName, args)
178190
destDir.deleteRecursively
179191
}
180192
}
181193

182194
// ========== HELPERS =============
183195

184-
private def compileArgs(args: Array[String], xerrors: Int = 0)
196+
private def expectedErrors(filePaths: List[String]): List[ErrorsInFile] = if (filePaths.exists(isNegTest(_))) filePaths.map(getErrors(_)) else Nil
197+
198+
private def expectedErrors(filePath: String): List[ErrorsInFile] = expectedErrors(List(filePath))
199+
200+
private def isNegTest(testPath: String) = testPath.contains(JFile.separator + "neg" + JFile.separator)
201+
202+
private def compileArgs(args: Array[String], expectedErrorsPerFile: List[ErrorsInFile])
185203
(implicit defaultOptions: List[String]): Unit = {
186204
val allArgs = args ++ defaultOptions
187205
val processor = if (allArgs.exists(_.startsWith("#"))) Bench else Main
188206
val reporter = processor.process(allArgs)
189207

190208
val nerrors = reporter.errorCount
191-
assert(nerrors == xerrors, s"Wrong # of errors. Expected: $xerrors, found: $nerrors")
192-
209+
val xerrors = (expectedErrorsPerFile map {_.totalErrors}).sum
210+
assert(nerrors == xerrors,
211+
s"""Wrong # of errors. Expected: $xerrors, found: $nerrors
212+
|Files with expected errors: ${expectedErrorsPerFile.collect{ case er if er.totalErrors > 0 => er.fileName} }
213+
""".stripMargin)
193214
// NEG TEST
194215
if (xerrors > 0) {
195216
val errorLines = reporter.allErrors.map(_.pos)
196217
// reporter didn't record as many errors as its errorCount says
197218
assert(errorLines.length == nerrors, s"Not enough errors recorded.")
198219

199-
val allFiles = (allArgs filter {
200-
arg => !arg.startsWith("-") && (arg.endsWith(".scala") || arg.endsWith(".java"))
201-
}).toList
202-
val expectedErrorsPerFile = allFiles.map(getErrors(_))
203-
204220
// Some compiler errors have an associated source position. Each error
205221
// needs to correspond to a "// error" marker on that line in the source
206222
// file and vice versa.
@@ -233,7 +249,9 @@ abstract class CompilerTest {
233249
/** Captures the number of nopos-errors in the given file and the number of
234250
* errors with a position, represented as a tuple of source line and number
235251
* of errors on that line. */
236-
case class ErrorsInFile(fileName: String, noposErrorNr: Int, posErrorLinesToNr: List[(Int, Int)])
252+
case class ErrorsInFile(fileName: String, noposErrorNr: Int, posErrorLinesToNr: List[(Int, Int)]) {
253+
def totalErrors = noposErrorNr + posErrorLinesToNr.map(_._2).sum
254+
}
237255

238256
/** Extracts the errors expected for the given neg test file. */
239257
def getErrors(fileName: String): ErrorsInFile = {
@@ -319,9 +337,9 @@ abstract class CompilerTest {
319337
private val extensionsToCopy = scala.collection.immutable.HashSet("scala", "java")
320338

321339
/** Determines what kind of test to run. */
322-
private def testKind(prefixDir: String, xerrors: Int, runTest: Boolean) = {
340+
private def testKind(prefixDir: String, runTest: Boolean) = {
323341
if (runTest) "run"
324-
else if (xerrors > 0) "neg"
342+
else if (isNegTest(prefixDir)) "neg"
325343
else if (prefixDir.endsWith("run" + JFile.separator)) {
326344
log("WARNING: test is being run as pos test despite being in a run directory. " +
327345
"Use runFile/runDir instead of compileFile/compileDir to do a run test")

0 commit comments

Comments
 (0)