mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-07 02:36:56 +07:00
404 lines
15 KiB
Java
404 lines
15 KiB
Java
package com.jetbrains.python.fixture;
|
|
|
|
import com.intellij.application.options.CodeStyle;
|
|
import com.intellij.openapi.application.WriteAction;
|
|
import com.intellij.openapi.projectRoots.Sdk;
|
|
import com.intellij.openapi.projectRoots.SdkModificator;
|
|
import com.intellij.openapi.roots.OrderRootType;
|
|
import com.intellij.openapi.util.text.StringUtil;
|
|
import com.intellij.openapi.vfs.StandardFileSystems;
|
|
import com.intellij.openapi.vfs.VfsUtil;
|
|
import com.intellij.openapi.vfs.VirtualFile;
|
|
import com.intellij.psi.PsiFile;
|
|
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
|
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
|
import com.jetbrains.python.PythonLanguage;
|
|
import com.jetbrains.python.PythonTestUtil;
|
|
import com.jetbrains.python.documentation.PyDocumentationSettings;
|
|
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
|
|
import com.jetbrains.python.psi.LanguageLevel;
|
|
import com.jetbrains.python.psi.PyFile;
|
|
import com.jetbrains.python.psi.PyUtil;
|
|
import com.jetbrains.python.psi.impl.PyFileImpl;
|
|
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
|
|
import com.jetbrains.python.psi.types.TypeEvalContext;
|
|
import com.jetbrains.python.sdk.PythonSdkUtil;
|
|
import junit.framework.TestCase;
|
|
import org.jetbrains.annotations.Contract;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.junit.Assert;
|
|
|
|
import java.util.*;
|
|
import java.util.function.BiPredicate;
|
|
import java.util.function.Consumer;
|
|
|
|
public abstract class PythonCommonTestCase extends TestCase {
|
|
protected PythonCommonCodeInsightTestFixture myFixture;
|
|
|
|
protected abstract PythonCommonCodeInsightTestFixture getFixture();
|
|
|
|
@Override
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
myFixture = getFixture();
|
|
myFixture.setUp();
|
|
}
|
|
|
|
@Override
|
|
protected void runTest() throws Throwable {
|
|
myFixture.runTest(() -> {
|
|
super.runTest();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
protected void tearDown() throws Exception {
|
|
try {
|
|
myFixture.tearDown();
|
|
}
|
|
catch (Throwable e) {
|
|
myFixture.addSuppressedException(e);
|
|
}
|
|
finally {
|
|
super.tearDown();
|
|
}
|
|
}
|
|
|
|
@NotNull
|
|
protected String getTestName(boolean lowercaseFirstLetter) {
|
|
return getTestName(getName(), lowercaseFirstLetter);
|
|
}
|
|
|
|
protected void setLanguageLevel(@Nullable LanguageLevel languageLevel) {
|
|
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), languageLevel);
|
|
}
|
|
|
|
protected void runWithLanguageLevel(@NotNull LanguageLevel languageLevel, @NotNull Runnable runnable) {
|
|
setLanguageLevel(languageLevel);
|
|
try {
|
|
runnable.run();
|
|
}
|
|
finally {
|
|
setLanguageLevel(null);
|
|
}
|
|
}
|
|
|
|
protected void runWithDocStringFormat(@NotNull DocStringFormat format, @NotNull Runnable runnable) {
|
|
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(myFixture.getModule());
|
|
final DocStringFormat oldFormat = settings.getFormat();
|
|
settings.setFormat(format);
|
|
try {
|
|
runnable.run();
|
|
}
|
|
finally {
|
|
settings.setFormat(oldFormat);
|
|
}
|
|
}
|
|
|
|
@NotNull
|
|
protected CommonCodeStyleSettings getCommonCodeStyleSettings() {
|
|
return getCodeStyleSettings().getCommonSettings(PythonLanguage.getInstance());
|
|
}
|
|
|
|
@NotNull
|
|
protected CodeStyleSettings getCodeStyleSettings() {
|
|
return CodeStyle.getSettings(myFixture.getProject());
|
|
}
|
|
|
|
@NotNull
|
|
protected CommonCodeStyleSettings.IndentOptions getIndentOptions() {
|
|
return getCommonCodeStyleSettings().getIndentOptions();
|
|
}
|
|
|
|
protected void assertProjectFilesNotParsed(@NotNull PsiFile currentFile) {
|
|
assertRootNotParsed(currentFile, myFixture.getTempDirRoot(), null);
|
|
}
|
|
|
|
protected void assertProjectFilesNotParsed(@NotNull TypeEvalContext context) {
|
|
assertRootNotParsed(context.getOrigin(), myFixture.getTempDirRoot(), null);
|
|
}
|
|
|
|
protected void assertSdkRootsNotParsed(@NotNull PsiFile currentFile) {
|
|
final Sdk testSdk = PythonSdkUtil.findPythonSdk(currentFile);
|
|
for (VirtualFile root : testSdk.getRootProvider().getFiles(OrderRootType.CLASSES)) {
|
|
assertRootNotParsed(currentFile, root, null);
|
|
}
|
|
}
|
|
|
|
private void assertRootNotParsed(@NotNull PsiFile currentFile, @NotNull VirtualFile root, @Nullable TypeEvalContext context) {
|
|
for (VirtualFile file : VfsUtil.collectChildrenRecursively(root)) {
|
|
final PyFile pyFile = PyUtil.as(myFixture.getPsiManager().findFile(file), PyFile.class);
|
|
if (pyFile != null && !pyFile.equals(currentFile) && (context == null || !context.maySwitchToAST(pyFile))) {
|
|
assertNotParsed(pyFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Contract("null, _ -> fail")
|
|
@NotNull
|
|
public static <T> T assertInstanceOf(Object o, @NotNull Class<T> aClass) {
|
|
Assert.assertNotNull("Expected instance of: " + aClass.getName() + " actual: " + null, o);
|
|
Assert.assertTrue("Expected instance of: " + aClass.getName() + " actual: " + o.getClass().getName(), aClass.isInstance(o));
|
|
@SuppressWarnings("unchecked") T t = (T)o;
|
|
return t;
|
|
}
|
|
|
|
@NotNull
|
|
public static String getTestName(@NotNull String name, boolean lowercaseFirstLetter) {
|
|
name = StringUtil.trimStart(name, "test");
|
|
return StringUtil.isEmpty(name) ? "" : lowercaseFirstLetter(name, lowercaseFirstLetter);
|
|
}
|
|
|
|
@NotNull
|
|
public static String lowercaseFirstLetter(@NotNull String name, boolean lowercaseFirstLetter) {
|
|
if (lowercaseFirstLetter && !isAllUppercaseName(name)) {
|
|
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
public static boolean isAllUppercaseName(@NotNull String name) {
|
|
int uppercaseChars = 0;
|
|
for (int i = 0; i < name.length(); i++) {
|
|
if (Character.isLowerCase(name.charAt(i))) {
|
|
return false;
|
|
}
|
|
if (Character.isUpperCase(name.charAt(i))) {
|
|
uppercaseChars++;
|
|
}
|
|
}
|
|
return uppercaseChars >= 3;
|
|
}
|
|
|
|
public static <T> void assertEmpty(@NotNull String errorMsg, @NotNull Collection<? extends T> collection) {
|
|
assertOrderedEquals(errorMsg, collection, Collections.emptyList());
|
|
}
|
|
|
|
public static void assertEmpty(@NotNull Collection<?> collection) {
|
|
assertEmpty(collection.toString(), collection);
|
|
}
|
|
|
|
public static void assertEmpty(Object @NotNull [] array) {
|
|
assertOrderedEquals(array);
|
|
}
|
|
|
|
@NotNull
|
|
public static String toString(@NotNull Iterable<?> collection) {
|
|
if (!collection.iterator().hasNext()) {
|
|
return "<empty>";
|
|
}
|
|
|
|
final StringBuilder builder = new StringBuilder();
|
|
for (final Object o : collection) {
|
|
if (o instanceof Set) {
|
|
builder.append(new TreeSet<>((Set<?>)o));
|
|
}
|
|
else {
|
|
builder.append(o);
|
|
}
|
|
builder.append('\n');
|
|
}
|
|
return builder.toString();
|
|
}
|
|
|
|
private static <T> boolean equals(@NotNull Iterable<? extends T> a1,
|
|
@NotNull Iterable<? extends T> a2,
|
|
@NotNull BiPredicate<? super T, ? super T> comparator) {
|
|
Iterator<? extends T> it1 = a1.iterator();
|
|
Iterator<? extends T> it2 = a2.iterator();
|
|
while (it1.hasNext() || it2.hasNext()) {
|
|
if (!it1.hasNext() || !it2.hasNext() || !comparator.test(it1.next(), it2.next())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static <T> void assertOrderedEquals(T @NotNull [] actual, T @NotNull ... expected) {
|
|
assertOrderedEquals(Arrays.asList(actual), expected);
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static <T> void assertOrderedEquals(@NotNull Iterable<? extends T> actual, T @NotNull ... expected) {
|
|
assertOrderedEquals("", actual, expected);
|
|
}
|
|
|
|
public static void assertOrderedEquals(byte @NotNull [] actual, byte @NotNull [] expected) {
|
|
assertEquals(expected.length, actual.length);
|
|
for (int i = 0; i < actual.length; i++) {
|
|
byte a = actual[i];
|
|
byte e = expected[i];
|
|
assertEquals("not equals at index: " + i, e, a);
|
|
}
|
|
}
|
|
|
|
public static void assertOrderedEquals(int @NotNull [] actual, int @NotNull [] expected) {
|
|
if (actual.length != expected.length) {
|
|
fail("Expected size: " +
|
|
expected.length +
|
|
"; actual: " +
|
|
actual.length +
|
|
"\nexpected: " +
|
|
Arrays.toString(expected) +
|
|
"\nactual : " +
|
|
Arrays.toString(actual));
|
|
}
|
|
for (int i = 0; i < actual.length; i++) {
|
|
int a = actual[i];
|
|
int e = expected[i];
|
|
assertEquals("not equals at index: " + i, e, a);
|
|
}
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static <T> void assertOrderedEquals(@NotNull String errorMsg, @NotNull Iterable<? extends T> actual, T @NotNull ... expected) {
|
|
assertOrderedEquals(errorMsg, actual, Arrays.asList(expected));
|
|
}
|
|
|
|
public static <T> void assertOrderedEquals(@NotNull Iterable<? extends T> actual, @NotNull Iterable<? extends T> expected) {
|
|
assertOrderedEquals("", actual, expected);
|
|
}
|
|
|
|
public static <T> void assertOrderedEquals(@NotNull String errorMsg,
|
|
@NotNull Iterable<? extends T> actual,
|
|
@NotNull Iterable<? extends T> expected) {
|
|
assertOrderedEquals(errorMsg, actual, expected, (t, t2) -> Objects.equals(t, t2));
|
|
}
|
|
|
|
public static <T> void assertOrderedEquals(@NotNull String errorMsg,
|
|
@NotNull Iterable<? extends T> actual,
|
|
@NotNull Iterable<? extends T> expected,
|
|
@NotNull BiPredicate<? super T, ? super T> comparator) {
|
|
if (!equals(actual, expected, comparator)) {
|
|
String expectedString = toString(expected);
|
|
String actualString = toString(actual);
|
|
Assert.assertEquals(errorMsg, expectedString, actualString);
|
|
Assert.fail("Warning! 'toString' does not reflect the difference.\nExpected: " + expectedString + "\nActual: " + actualString);
|
|
}
|
|
}
|
|
|
|
protected static void assertNotParsed(PsiFile file) {
|
|
assertInstanceOf(file, PyFileImpl.class);
|
|
assertNull("Operations should have been performed on stubs but caused file to be parsed: " + file.getVirtualFile().getPath(),
|
|
((PyFileImpl)file).getTreeElement());
|
|
}
|
|
|
|
/**
|
|
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
|
*/
|
|
@SafeVarargs
|
|
public static <T> void assertSameElements(T @NotNull [] actual, T @NotNull ... expected) {
|
|
assertSameElements(Arrays.asList(actual), expected);
|
|
}
|
|
|
|
/**
|
|
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
|
*/
|
|
@SafeVarargs
|
|
public static <T> void assertSameElements(@NotNull Collection<? extends T> actual, T @NotNull ... expected) {
|
|
assertSameElements(actual, Arrays.asList(expected));
|
|
}
|
|
|
|
/**
|
|
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
|
*/
|
|
public static <T> void assertSameElements(@NotNull Collection<? extends T> actual, @NotNull Collection<? extends T> expected) {
|
|
assertSameElements("", actual, expected);
|
|
}
|
|
|
|
/**
|
|
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
|
*/
|
|
public static <T> void assertSameElements(@NotNull String message, @NotNull Collection<? extends T> actual, @NotNull Collection<? extends T> expected) {
|
|
if (actual.size() != expected.size() || !new HashSet<>(expected).equals(new HashSet<T>(actual))) {
|
|
Assert.assertEquals(message, new HashSet<>(expected), new HashSet<T>(actual));
|
|
}
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static <T> void assertContainsElements(@NotNull Collection<? extends T> collection, T @NotNull ... expected) {
|
|
assertContainsElements(collection, Arrays.asList(expected));
|
|
}
|
|
|
|
public static <T> void assertContainsElements(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
|
|
ArrayList<T> copy = new ArrayList<>(collection);
|
|
copy.retainAll(expected);
|
|
assertSameElements(toString(collection), copy, expected);
|
|
}
|
|
|
|
@SafeVarargs
|
|
public static <T> void assertDoesntContain(@NotNull Collection<? extends T> collection, T @NotNull ... notExpected) {
|
|
assertDoesntContain(collection, Arrays.asList(notExpected));
|
|
}
|
|
|
|
public static <T> void assertDoesntContain(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> notExpected) {
|
|
ArrayList<T> expected = new ArrayList<>(collection);
|
|
expected.removeAll(notExpected);
|
|
assertSameElements(collection, expected);
|
|
}
|
|
|
|
public static void assertNullOrEmpty(@Nullable Collection<?> collection) {
|
|
if (collection == null) return;
|
|
assertEmpty("", collection);
|
|
}
|
|
|
|
public static void assertNotEmpty(@Nullable Collection<?> collection) {
|
|
assertNotNull(collection);
|
|
assertFalse(collection.isEmpty());
|
|
}
|
|
|
|
public static void assertSize(int expectedSize, Object @NotNull [] array) {
|
|
if (array.length != expectedSize) {
|
|
assertEquals(toString(Arrays.asList(array)), expectedSize, array.length);
|
|
}
|
|
}
|
|
|
|
public static void assertSize(int expectedSize, @NotNull Collection<?> c) {
|
|
if (c.size() != expectedSize) {
|
|
assertEquals(toString(c), expectedSize, c.size());
|
|
}
|
|
}
|
|
|
|
protected void runWithAdditionalClassEntryInSdkRoots(@NotNull VirtualFile directory, @NotNull Runnable runnable) {
|
|
final Sdk sdk = PythonSdkUtil.findPythonSdk(myFixture.getModule());
|
|
assertNotNull(sdk);
|
|
runWithAdditionalRoot(sdk, directory, OrderRootType.CLASSES, (__) -> runnable.run());
|
|
}
|
|
|
|
protected void runWithAdditionalClassEntryInSdkRoots(@NotNull String relativeTestDataPath, @NotNull Runnable runnable) {
|
|
final String absPath = getTestDataPath() + "/" + relativeTestDataPath;
|
|
final VirtualFile testDataDir = StandardFileSystems.local().findFileByPath(absPath);
|
|
assertNotNull("Additional class entry directory '" + absPath + "' not found", testDataDir);
|
|
runWithAdditionalClassEntryInSdkRoots(testDataDir, runnable);
|
|
}
|
|
|
|
private static void runWithAdditionalRoot(@NotNull Sdk sdk,
|
|
@NotNull VirtualFile root,
|
|
@NotNull OrderRootType rootType,
|
|
@NotNull Consumer<VirtualFile> rootConsumer) {
|
|
WriteAction.run(() -> {
|
|
final SdkModificator modificator = sdk.getSdkModificator();
|
|
assertNotNull(modificator);
|
|
modificator.addRoot(root, rootType);
|
|
modificator.commitChanges();
|
|
});
|
|
try {
|
|
rootConsumer.accept(root);
|
|
}
|
|
finally {
|
|
WriteAction.run(() -> {
|
|
final SdkModificator modificator = sdk.getSdkModificator();
|
|
assertNotNull(modificator);
|
|
modificator.removeRoot(root, rootType);
|
|
modificator.commitChanges();
|
|
});
|
|
}
|
|
}
|
|
|
|
protected @NotNull String getTestDataPath() {
|
|
return PythonTestUtil.getTestDataPath();
|
|
}
|
|
}
|