J2K: AbstractBytecodeTextTest.java convert
(cherry picked from commit 93fce11)
This commit is contained in:
committed by
Nikolay Krasko
parent
5a873432d9
commit
32dff799ff
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user