J2K: AbstractBytecodeTextTest.java convert

(cherry picked from commit 93fce11)
This commit is contained in:
Nikolay Krasko
2016-10-03 17:37:03 +03:00
committed by Nikolay Krasko
parent 5a873432d9
commit 32dff799ff
2 changed files with 113 additions and 123 deletions
@@ -14,165 +14,155 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen
import org.jetbrains.annotations.NotNull import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.annotations.Nullable import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.utils.rethrow
import java.io.File import java.io.File
import java.util.* import java.util.*
import java.util.List
import java.util.Map
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
public abstract class AbstractBytecodeTextTest extends CodegenTestCase { abstract class AbstractBytecodeTextTest : CodegenTestCase() {
private static final Pattern AT_OUTPUT_FILE_PATTERN = Pattern.compile("^\\s*//\\s*@(.*):$");
private static final Pattern EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$");
@Override @Throws(Exception::class)
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception { override fun doMultiFileTest(wholeFile: File, files: List<CodegenTestCase.TestFile>, javaFilesDir: File?) {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, files, javaFilesDir); createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, files, javaFilesDir)
loadMultiFiles(files); loadMultiFiles(files)
if (isMultiFileTest(files)) { if (isMultiFileTest(files)) {
doTestMultiFile(files); doTestMultiFile(files)
} }
else { else {
List<OccurrenceInfo> expected = readExpectedOccurrences(wholeFile.getPath()); val expected = readExpectedOccurrences(wholeFile.path)
String actual = generateToText(); val actual = generateToText()
checkGeneratedTextAgainstExpectedOccurrences(actual, expected); checkGeneratedTextAgainstExpectedOccurrences(actual, expected)
} }
} }
private static boolean isMultiFileTest(@NotNull List<TestFile> files) { @Throws(Exception::class)
int kotlinFiles = 0; private fun doTestMultiFile(files: List<CodegenTestCase.TestFile>) {
for (TestFile file : files) { val expectedOccurrencesByOutputFile = LinkedHashMap<String, List<OccurrenceInfo>>()
if (file.name.endsWith(".kt")) { for (file in files) {
kotlinFiles++; readExpectedOccurrencesForMultiFileTest(file, expectedOccurrencesByOutputFile)
}
}
return kotlinFiles > 1;
}
protected static void checkGeneratedTextAgainstExpectedOccurrences(
@NotNull String text,
@NotNull List<OccurrenceInfo> expectedOccurrences
) {
StringBuilder expected = new StringBuilder();
StringBuilder actual = new StringBuilder();
for (OccurrenceInfo info : expectedOccurrences) {
expected.append(info).append("\n");
actual.append(info.getActualOccurrence(text)).append("\n");
} }
try { val generated = generateEachFileToText()
assertEquals(text, expected.toString(), actual.toString()); for (expectedOutputFile in expectedOccurrencesByOutputFile.keys) {
} assertTextWasGenerated(expectedOutputFile, generated)
catch (Throwable e) { val generatedText = generated[expectedOutputFile]
System.out.println(text); val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]
throw ExceptionUtilsKt.rethrow(e); checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences)
} }
} }
private void doTestMultiFile(@NotNull List<TestFile> files) throws Exception { @Throws(Exception::class)
Map<String, List<OccurrenceInfo>> expectedOccurrencesByOutputFile = new LinkedHashMap<String, List<OccurrenceInfo>>(); protected fun readExpectedOccurrences(filename: String): List<OccurrenceInfo> {
for (TestFile file : files) { val result = ArrayList<OccurrenceInfo>()
readExpectedOccurrencesForMultiFileTest(file, expectedOccurrencesByOutputFile); val lines = FileUtil.loadFile(File(filename), Charsets.UTF_8.name(), true).split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
}
Map<String, String> generated = generateEachFileToText(); for (line in lines) {
for (String expectedOutputFile : expectedOccurrencesByOutputFile.keySet()) { val matcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
assertTextWasGenerated(expectedOutputFile, generated);
String generatedText = generated.get(expectedOutputFile);
List<OccurrenceInfo> expectedOccurrences = expectedOccurrencesByOutputFile.get(expectedOutputFile);
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences);
}
}
private static void assertTextWasGenerated(String expectedOutputFile, Map<String, String> generated) {
if (!generated.containsKey(expectedOutputFile)) {
StringBuilder failMessage = new StringBuilder();
failMessage.append("Missing output file ").append(expectedOutputFile).append(", got ").append(generated.size()).append(": ");
for (String generatedFile : generated.keySet()) {
failMessage.append(generatedFile).append(" ");
}
fail(failMessage.toString());
}
}
@NotNull
protected List<OccurrenceInfo> readExpectedOccurrences(@NotNull String filename) throws Exception {
List<OccurrenceInfo> result = new ArrayList<OccurrenceInfo>();
String[] lines = FileUtil.loadFile(new File(filename), Charsets.UTF_8.name(), true).split("\n");
for (String line : lines) {
Matcher matcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line);
if (matcher.matches()) { if (matcher.matches()) {
result.add(parseOccurrenceInfo(matcher)); result.add(parseOccurrenceInfo(matcher))
} }
} }
return result; return result
} }
private static void readExpectedOccurrencesForMultiFileTest( protected class OccurrenceInfo private constructor(private val numberOfOccurrences: Int, private val needle: String) {
@NotNull TestFile file,
@NotNull Map<String, List<OccurrenceInfo>> occurrenceMap fun getActualOccurrence(text: String): String? {
) { val actualCount = StringUtil.findMatches(text, Pattern.compile("($needle)")).size
List<OccurrenceInfo> currentOccurrenceInfos = null; return actualCount + " " + needle
for (String line : file.content.split("\n")) { }
Matcher atOutputFileMatcher = AT_OUTPUT_FILE_PATTERN.matcher(line);
if (atOutputFileMatcher.matches()) { override fun toString(): String {
String outputFileName = atOutputFileMatcher.group(1); return numberOfOccurrences + " " + needle
if (occurrenceMap.containsKey(outputFileName)) { }
throw new AssertionError( }
file.name + ": Expected occurrences for output file " + outputFileName + " were already provided"
); companion object {
private val AT_OUTPUT_FILE_PATTERN = Pattern.compile("^\\s*//\\s*@(.*):$")
private val EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$")
private fun isMultiFileTest(files: List<CodegenTestCase.TestFile>): Boolean {
var kotlinFiles = 0
for (file in files) {
if (file.name.endsWith(".kt")) {
kotlinFiles++
} }
currentOccurrenceInfos = new ArrayList<OccurrenceInfo>(); }
occurrenceMap.put(outputFileName, currentOccurrenceInfos); return kotlinFiles > 1
}
protected fun checkGeneratedTextAgainstExpectedOccurrences(
text: String,
expectedOccurrences: List<OccurrenceInfo>) {
val expected = StringBuilder()
val actual = StringBuilder()
for (info in expectedOccurrences) {
expected.append(info).append("\n")
actual.append(info.getActualOccurrence(text)).append("\n")
} }
Matcher expectedOccurrencesMatcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line); try {
if (expectedOccurrencesMatcher.matches()) { TestCase.assertEquals(text, expected.toString(), actual.toString())
if (currentOccurrenceInfos == null) { }
throw new AssertionError( catch (e: Throwable) {
file.name + ": Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations" println(text)
); throw rethrow(e)
}
}
private fun assertTextWasGenerated(expectedOutputFile: String, generated: Map<String, String>) {
if (!generated.containsKey(expectedOutputFile)) {
val failMessage = StringBuilder()
failMessage.append("Missing output file ").append(expectedOutputFile).append(", got ").append(generated.size).append(": ")
for (generatedFile in generated.keys) {
failMessage.append(generatedFile).append(" ")
} }
OccurrenceInfo occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher); TestCase.fail(failMessage.toString())
currentOccurrenceInfos.add(occurrenceInfo);
} }
} }
}
@NotNull private fun readExpectedOccurrencesForMultiFileTest(
private static OccurrenceInfo parseOccurrenceInfo(Matcher matcher) { file: CodegenTestCase.TestFile,
int numberOfOccurrences = Integer.parseInt(matcher.group(1)); occurrenceMap: MutableMap<String, List<OccurrenceInfo>>) {
String needle = matcher.group(2); var currentOccurrenceInfos: MutableList<OccurrenceInfo>? = null
return new OccurrenceInfo(numberOfOccurrences, needle); for (line in file.content.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
} val atOutputFileMatcher = AT_OUTPUT_FILE_PATTERN.matcher(line)
if (atOutputFileMatcher.matches()) {
val outputFileName = atOutputFileMatcher.group(1)
if (occurrenceMap.containsKey(outputFileName)) {
throw AssertionError(
file.name + ": Expected occurrences for output file " + outputFileName + " were already provided")
}
currentOccurrenceInfos = ArrayList<OccurrenceInfo>()
occurrenceMap.put(outputFileName, currentOccurrenceInfos)
}
protected static class OccurrenceInfo { val expectedOccurrencesMatcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
private final int numberOfOccurrences; if (expectedOccurrencesMatcher.matches()) {
private final String needle; if (currentOccurrenceInfos == null) {
throw AssertionError(
private OccurrenceInfo(int numberOfOccurrences, @NotNull String needle) { file.name + ": Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
this.numberOfOccurrences = numberOfOccurrences; }
this.needle = needle; val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher)
currentOccurrenceInfos.add(occurrenceInfo)
}
}
} }
@Nullable private fun parseOccurrenceInfo(matcher: Matcher): OccurrenceInfo {
public String getActualOccurrence(String text) { val numberOfOccurrences = Integer.parseInt(matcher.group(1))
int actualCount = StringUtil.findMatches(text, Pattern.compile("(" + needle + ")")).size(); val needle = matcher.group(2)
return actualCount + " " + needle; return OccurrenceInfo(numberOfOccurrences, needle)
}
@Override
public String toString() {
return numberOfOccurrences + " " + needle;
} }
} }
} }
@@ -78,6 +78,6 @@ public abstract class AbstractTopLevelMembersInvocationTest extends AbstractByte
List<OccurrenceInfo> expected = readExpectedOccurrences(KotlinTestUtils.getTestDataPathBase() + "/codegen/" + sourceFiles.get(0)); List<OccurrenceInfo> expected = readExpectedOccurrences(KotlinTestUtils.getTestDataPathBase() + "/codegen/" + sourceFiles.get(0));
String actual = generateToText(); String actual = generateToText();
checkGeneratedTextAgainstExpectedOccurrences(actual, expected); Companion.checkGeneratedTextAgainstExpectedOccurrences(actual, expected);
} }
} }