Refactoring: extract tests files utilities to separate class
This commit is contained in:
+2
-6
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.checkers;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import kotlin.io.FilesKt;
|
||||
import kotlin.text.Charsets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -16,10 +15,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||
import org.jetbrains.kotlin.test.*;
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase;
|
||||
|
||||
import java.io.File;
|
||||
@@ -160,7 +156,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
|
||||
protected abstract void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<F> files) throws Exception;
|
||||
|
||||
protected List<F> createTestFiles(File file, String expectedText, Map<String, ModuleAndDependencies> modules) {
|
||||
return KotlinTestUtils.createTestFiles(file.getName(), expectedText, new KotlinTestUtils.TestFileFactory<M, F>() {
|
||||
return TestFiles.createTestFiles(file.getName(), expectedText, new TestFiles.TestFileFactory<M, F>() {
|
||||
@Override
|
||||
public F createFile(
|
||||
@Nullable M module,
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.intellij.testFramework.TestDataFile;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.io.FilesKt;
|
||||
import kotlin.script.experimental.api.ErrorHandlingKt;
|
||||
import kotlin.text.Charsets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -68,7 +67,6 @@ import java.util.regex.Pattern;
|
||||
|
||||
import static org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings;
|
||||
import static org.jetbrains.kotlin.cli.common.output.OutputUtilsKt.writeAllTo;
|
||||
import static org.jetbrains.kotlin.cli.js.K2JsIrCompilerKt.loadPluginsForTests;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.TestUtilsKt.extractUrls;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar;
|
||||
@@ -794,7 +792,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
|
||||
@NotNull
|
||||
private static List<TestFile> createTestFiles(File file, String expectedText, String coroutinesPackage) {
|
||||
return KotlinTestUtils.createTestFiles(file.getName(), expectedText, new KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
|
||||
return TestFiles.createTestFiles(file.getName(), expectedText, new TestFiles.TestFileFactoryNoModules<TestFile>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public TestFile create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
|
||||
+2
-2
@@ -279,9 +279,9 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
assertTrue(srcDir.mkdir());
|
||||
assertTrue(compiledDir.mkdir());
|
||||
|
||||
List<File> srcFiles = KotlinTestUtils.createTestFiles(
|
||||
List<File> srcFiles = TestFiles.createTestFiles(
|
||||
new File(javaFileName).getName(), FileUtil.loadFile(new File(javaFileName), true),
|
||||
new TestFileFactoryNoModules<File>() {
|
||||
new TestFiles.TestFileFactoryNoModules<File>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public File create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment;
|
||||
import org.jetbrains.kotlin.test.TestFiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -42,7 +43,7 @@ public abstract class ExtensibleResolveTestCase extends KotlinTestWithEnvironmen
|
||||
protected void doTest(@NonNls String filePath) throws Exception {
|
||||
File file = new File(filePath);
|
||||
String text = KotlinTestUtils.doLoadFile(file);
|
||||
List<KtFile> files = KotlinTestUtils.createTestFiles("file.kt", text, new KotlinTestUtils.TestFileFactoryNoModules<KtFile>() {
|
||||
List<KtFile> files = TestFiles.createTestFiles("file.kt", text, new TestFiles.TestFileFactoryNoModules<KtFile>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public KtFile create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
|
||||
@@ -31,11 +31,9 @@ import kotlin.Unit;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.collections.SetsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.CoroutineTestUtilKt;
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -98,22 +96,7 @@ public class KotlinTestUtils {
|
||||
|
||||
private static final List<File> filesToDelete = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Syntax:
|
||||
*
|
||||
* // MODULE: name(dependency1, dependency2, ...)
|
||||
*
|
||||
* // FILE: name
|
||||
*
|
||||
* Several files may follow one module
|
||||
*/
|
||||
private static final String MODULE_DELIMITER = ",\\s*";
|
||||
|
||||
private static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile(
|
||||
"(?://\\s*MODULE:\\s*([^()\\n]+)(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*)?" +
|
||||
"//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE);
|
||||
private static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!([\\w_]+)(:\\s*(.*)$)?", Pattern.MULTILINE);
|
||||
private static final Pattern LINE_SEPARATOR_PATTERN = Pattern.compile("\\r\\n|\\r|\\n");
|
||||
static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!([\\w_]+)(:\\s*(.*)$)?", Pattern.MULTILINE);
|
||||
|
||||
private KotlinTestUtils() {
|
||||
}
|
||||
@@ -539,141 +522,6 @@ public class KotlinTestUtils {
|
||||
), javaErrorFile);
|
||||
}
|
||||
|
||||
public interface TestFileFactory<M, F> {
|
||||
F createFile(@Nullable M module, @NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
M createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends);
|
||||
}
|
||||
|
||||
public static abstract class TestFileFactoryNoModules<F> implements TestFileFactory<Void, F> {
|
||||
@Override
|
||||
public final F createFile(
|
||||
@Nullable Void module,
|
||||
@NotNull String fileName,
|
||||
@NotNull String text,
|
||||
@NotNull Map<String, String> directives
|
||||
) {
|
||||
return create(fileName, text, directives);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract F create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
|
||||
@Override
|
||||
public Void createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(@Nullable String testFileName, String expectedText, TestFileFactory<M, F> factory) {
|
||||
return createTestFiles(testFileName, expectedText, factory, false, "");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(@Nullable String testFileName, String expectedText, TestFileFactory<M, F> factory, String coroutinesPackage) {
|
||||
return createTestFiles(testFileName, expectedText, factory, false, coroutinesPackage);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(String testFileName, String expectedText, TestFileFactory<M, F> factory,
|
||||
boolean preserveLocations, String coroutinesPackage) {
|
||||
Map<String, String> directives = parseDirectives(expectedText);
|
||||
|
||||
List<F> testFiles = Lists.newArrayList();
|
||||
Matcher matcher = FILE_OR_MODULE_PATTERN.matcher(expectedText);
|
||||
boolean hasModules = false;
|
||||
if (!matcher.find()) {
|
||||
assert testFileName != null : "testFileName should not be null if no FILE directive defined";
|
||||
// One file
|
||||
testFiles.add(factory.createFile(null, testFileName, expectedText, directives));
|
||||
}
|
||||
else {
|
||||
int processedChars = 0;
|
||||
M module = null;
|
||||
// Many files
|
||||
while (true) {
|
||||
String moduleName = matcher.group(1);
|
||||
String moduleDependencies = matcher.group(2);
|
||||
String moduleFriends = matcher.group(3);
|
||||
if (moduleName != null) {
|
||||
moduleName = moduleName.trim();
|
||||
hasModules = true;
|
||||
module = factory.createModule(moduleName, parseModuleList(moduleDependencies), parseModuleList(moduleFriends));
|
||||
}
|
||||
|
||||
String fileName = matcher.group(4);
|
||||
int start = processedChars;
|
||||
|
||||
boolean nextFileExists = matcher.find();
|
||||
int end;
|
||||
if (nextFileExists) {
|
||||
end = matcher.start();
|
||||
}
|
||||
else {
|
||||
end = expectedText.length();
|
||||
}
|
||||
String fileText = preserveLocations ?
|
||||
substringKeepingLocations(expectedText, start, end) :
|
||||
expectedText.substring(start,end);
|
||||
processedChars = end;
|
||||
|
||||
testFiles.add(factory.createFile(module, fileName, fileText, directives));
|
||||
|
||||
if (!nextFileExists) break;
|
||||
}
|
||||
assert processedChars == expectedText.length() : "Characters skipped from " +
|
||||
processedChars +
|
||||
" to " +
|
||||
(expectedText.length() - 1);
|
||||
}
|
||||
|
||||
if (isDirectiveDefined(expectedText, "WITH_COROUTINES")) {
|
||||
M supportModule = hasModules ? factory.createModule("support", Collections.emptyList(), Collections.emptyList()) : null;
|
||||
|
||||
boolean isReleaseCoroutines =
|
||||
!coroutinesPackage.contains("experimental") &&
|
||||
!isDirectiveDefined(expectedText, "!LANGUAGE: -ReleaseCoroutines");
|
||||
|
||||
boolean checkStateMachine = isDirectiveDefined(expectedText, "CHECK_STATE_MACHINE");
|
||||
boolean checkTailCallOptimization = isDirectiveDefined(expectedText, "CHECK_TAIL_CALL_OPTIMIZATION");
|
||||
|
||||
testFiles.add(
|
||||
factory.createFile(
|
||||
supportModule,
|
||||
"CoroutineUtil.kt",
|
||||
CoroutineTestUtilKt.createTextForHelpers(isReleaseCoroutines, checkStateMachine, checkTailCallOptimization),
|
||||
directives
|
||||
));
|
||||
}
|
||||
|
||||
return testFiles;
|
||||
}
|
||||
|
||||
private static String substringKeepingLocations(String string, int start, int end) {
|
||||
Matcher matcher = LINE_SEPARATOR_PATTERN.matcher(string);
|
||||
StringBuilder prefix = new StringBuilder();
|
||||
int lastLineOffset = 0;
|
||||
while (matcher.find()) {
|
||||
if (matcher.end() > start) {
|
||||
break;
|
||||
}
|
||||
|
||||
lastLineOffset = matcher.end();
|
||||
prefix.append('\n');
|
||||
}
|
||||
|
||||
while (lastLineOffset++ < start) {
|
||||
prefix.append(' ');
|
||||
}
|
||||
|
||||
return prefix + string.substring(start, end);
|
||||
}
|
||||
|
||||
private static List<String> parseModuleList(@Nullable String dependencies) {
|
||||
if (dependencies == null) return Collections.emptyList();
|
||||
return StringsKt.split(dependencies, Pattern.compile(MODULE_DELIMITER), 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, String> parseDirectives(String expectedText) {
|
||||
Map<String, String> directives = new HashMap<>();
|
||||
@@ -697,7 +545,7 @@ public class KotlinTestUtils {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
List<String> files = createTestFiles("", content, new TestFileFactoryNoModules<String>() {
|
||||
List<String> files = TestFiles.createTestFiles("", content, new TestFiles.TestFileFactoryNoModules<String>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.CoroutineTestUtilKt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
|
||||
|
||||
public class TestFiles {
|
||||
/**
|
||||
* Syntax:
|
||||
*
|
||||
* // MODULE: name(dependency1, dependency2, ...)
|
||||
*
|
||||
* // FILE: name
|
||||
*
|
||||
* Several files may follow one module
|
||||
*/
|
||||
private static final String MODULE_DELIMITER = ",\\s*";
|
||||
|
||||
private static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile(
|
||||
"(?://\\s*MODULE:\\s*([^()\\n]+)(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*)?" +
|
||||
"//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE);
|
||||
|
||||
private static final Pattern LINE_SEPARATOR_PATTERN = Pattern.compile("\\r\\n|\\r|\\n");
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(@Nullable String testFileName, String expectedText, TestFileFactory<M, F> factory) {
|
||||
return createTestFiles(testFileName, expectedText, factory, false, "");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(@Nullable String testFileName, String expectedText, TestFileFactory<M, F> factory, String coroutinesPackage) {
|
||||
return createTestFiles(testFileName, expectedText, factory, false, coroutinesPackage);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M, F> List<F> createTestFiles(String testFileName, String expectedText, TestFileFactory<M, F> factory,
|
||||
boolean preserveLocations, String coroutinesPackage) {
|
||||
Map<String, String> directives = KotlinTestUtils.parseDirectives(expectedText);
|
||||
|
||||
List<F> testFiles = Lists.newArrayList();
|
||||
Matcher matcher = FILE_OR_MODULE_PATTERN.matcher(expectedText);
|
||||
boolean hasModules = false;
|
||||
if (!matcher.find()) {
|
||||
assert testFileName != null : "testFileName should not be null if no FILE directive defined";
|
||||
// One file
|
||||
testFiles.add(factory.createFile(null, testFileName, expectedText, directives));
|
||||
}
|
||||
else {
|
||||
int processedChars = 0;
|
||||
M module = null;
|
||||
// Many files
|
||||
while (true) {
|
||||
String moduleName = matcher.group(1);
|
||||
String moduleDependencies = matcher.group(2);
|
||||
String moduleFriends = matcher.group(3);
|
||||
if (moduleName != null) {
|
||||
moduleName = moduleName.trim();
|
||||
hasModules = true;
|
||||
module = factory.createModule(moduleName, parseModuleList(moduleDependencies), parseModuleList(moduleFriends));
|
||||
}
|
||||
|
||||
String fileName = matcher.group(4);
|
||||
int start = processedChars;
|
||||
|
||||
boolean nextFileExists = matcher.find();
|
||||
int end;
|
||||
if (nextFileExists) {
|
||||
end = matcher.start();
|
||||
}
|
||||
else {
|
||||
end = expectedText.length();
|
||||
}
|
||||
String fileText = preserveLocations ?
|
||||
substringKeepingLocations(expectedText, start, end) :
|
||||
expectedText.substring(start,end);
|
||||
processedChars = end;
|
||||
|
||||
testFiles.add(factory.createFile(module, fileName, fileText, directives));
|
||||
|
||||
if (!nextFileExists) break;
|
||||
}
|
||||
assert processedChars == expectedText.length() : "Characters skipped from " +
|
||||
processedChars +
|
||||
" to " +
|
||||
(expectedText.length() - 1);
|
||||
}
|
||||
|
||||
if (isDirectiveDefined(expectedText, "WITH_COROUTINES")) {
|
||||
M supportModule = hasModules ? factory.createModule("support", Collections.emptyList(), Collections.emptyList()) : null;
|
||||
|
||||
boolean isReleaseCoroutines =
|
||||
!coroutinesPackage.contains("experimental") &&
|
||||
!isDirectiveDefined(expectedText, "!LANGUAGE: -ReleaseCoroutines");
|
||||
|
||||
boolean checkStateMachine = isDirectiveDefined(expectedText, "CHECK_STATE_MACHINE");
|
||||
boolean checkTailCallOptimization = isDirectiveDefined(expectedText, "CHECK_TAIL_CALL_OPTIMIZATION");
|
||||
|
||||
testFiles.add(
|
||||
factory.createFile(
|
||||
supportModule,
|
||||
"CoroutineUtil.kt",
|
||||
CoroutineTestUtilKt.createTextForHelpers(isReleaseCoroutines, checkStateMachine, checkTailCallOptimization),
|
||||
directives
|
||||
));
|
||||
}
|
||||
|
||||
return testFiles;
|
||||
}
|
||||
|
||||
private static String substringKeepingLocations(String string, int start, int end) {
|
||||
Matcher matcher = LINE_SEPARATOR_PATTERN.matcher(string);
|
||||
StringBuilder prefix = new StringBuilder();
|
||||
int lastLineOffset = 0;
|
||||
while (matcher.find()) {
|
||||
if (matcher.end() > start) {
|
||||
break;
|
||||
}
|
||||
|
||||
lastLineOffset = matcher.end();
|
||||
prefix.append('\n');
|
||||
}
|
||||
|
||||
while (lastLineOffset++ < start) {
|
||||
prefix.append(' ');
|
||||
}
|
||||
|
||||
return prefix + string.substring(start, end);
|
||||
}
|
||||
|
||||
private static List<String> parseModuleList(@Nullable String dependencies) {
|
||||
if (dependencies == null) return Collections.emptyList();
|
||||
return kotlin.text.StringsKt.split(dependencies, Pattern.compile(MODULE_DELIMITER), 0);
|
||||
}
|
||||
|
||||
public interface TestFileFactory<M, F> {
|
||||
F createFile(@Nullable M module, @NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
M createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends);
|
||||
}
|
||||
|
||||
public static abstract class TestFileFactoryNoModules<F> implements TestFileFactory<Void, F> {
|
||||
@Override
|
||||
public final F createFile(
|
||||
@Nullable Void module,
|
||||
@NotNull String fileName,
|
||||
@NotNull String text,
|
||||
@NotNull Map<String, String> directives
|
||||
) {
|
||||
return create(fileName, text, directives);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract F create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
|
||||
@Override
|
||||
public Void createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user