Merge changes in ExternalSystemTestCase into KotlinGradleTests
This commit is contained in:
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.idea.codeInsight.gradle;
|
||||
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.artifacts.ArtifactManager;
|
||||
import com.intellij.packaging.artifacts.ArtifactType;
|
||||
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
|
||||
import com.intellij.packaging.elements.CompositePackagingElement;
|
||||
import com.intellij.packaging.elements.PackagingElement;
|
||||
import com.intellij.packaging.elements.PackagingElementFactory;
|
||||
import com.intellij.packaging.elements.PackagingElementResolvingContext;
|
||||
import com.intellij.packaging.impl.elements.ArchivePackagingElement;
|
||||
import com.intellij.packaging.impl.elements.DirectoryPackagingElement;
|
||||
import com.intellij.packaging.impl.elements.ManifestFileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
public class ArtifactsTestUtil {
|
||||
public static String printToString(PackagingElement element, int level) {
|
||||
StringBuilder builder = new StringBuilder(StringUtil.repeatSymbol(' ', level));
|
||||
if (element instanceof ArchivePackagingElement) {
|
||||
builder.append(((ArchivePackagingElement)element).getArchiveFileName());
|
||||
}
|
||||
else if (element instanceof DirectoryPackagingElement) {
|
||||
builder.append(((DirectoryPackagingElement)element).getDirectoryName()).append("/");
|
||||
}
|
||||
else {
|
||||
builder.append(element.toString());
|
||||
}
|
||||
builder.append("\n");
|
||||
if (element instanceof CompositePackagingElement) {
|
||||
for (PackagingElement<?> child : ((CompositePackagingElement<?>)element).getChildren()) {
|
||||
builder.append(printToString(child, level + 1));
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static void assertLayout(PackagingElement element, String expected) {
|
||||
assertThat(printToString(element, 0)).isEqualTo(adjustMultiLine(expected));
|
||||
}
|
||||
|
||||
private static String adjustMultiLine(String expected) {
|
||||
final List<String> strings = StringUtil.split(StringUtil.trimStart(expected, "\n"), "\n");
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (String s : strings) {
|
||||
int k = 0;
|
||||
while (k < s.length() && s.charAt(k) == ' ') {
|
||||
k++;
|
||||
}
|
||||
min = Math.min(min, k);
|
||||
}
|
||||
List<String> lines = new ArrayList<>();
|
||||
for (String s : strings) {
|
||||
lines.add(s.substring(min));
|
||||
}
|
||||
return StringUtil.join(lines, "\n") + "\n";
|
||||
}
|
||||
|
||||
public static void assertLayout(Project project, String artifactName, String expected) {
|
||||
assertLayout(findArtifact(project, artifactName).getRootElement(), expected);
|
||||
}
|
||||
|
||||
public static void assertOutputPath(Project project, String artifactName, String expected) {
|
||||
assertThat(findArtifact(project, artifactName).getOutputPath()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
public static void assertOutputFileName(Project project, String artifactName, String expected) {
|
||||
assertThat(findArtifact(project, artifactName).getRootElement().getName()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
public static void setOutput(final Project project, final String artifactName, final String outputPath) {
|
||||
WriteAction.runAndWait(() -> {
|
||||
final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel();
|
||||
model.getOrCreateModifiableArtifact(findArtifact(project, artifactName)).setOutputPath(outputPath);
|
||||
model.commit();
|
||||
});
|
||||
}
|
||||
|
||||
public static void addArtifactToLayout(final Project project, final Artifact parent, final Artifact toAdd) {
|
||||
WriteAction.runAndWait(() -> {
|
||||
final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel();
|
||||
final PackagingElement<?> artifactElement = PackagingElementFactory.getInstance().createArtifactElement(toAdd, project);
|
||||
model.getOrCreateModifiableArtifact(parent).getRootElement().addOrFindChild(artifactElement);
|
||||
model.commit();
|
||||
});
|
||||
}
|
||||
|
||||
public static Artifact findArtifact(Project project, String artifactName) {
|
||||
final ArtifactManager manager = ArtifactManager.getInstance(project);
|
||||
final Artifact artifact = manager.findArtifact(artifactName);
|
||||
assertThat(artifact).describedAs("'" + artifactName + "' artifact not found").isNotNull();
|
||||
return artifact;
|
||||
}
|
||||
|
||||
public static void assertManifest(Artifact artifact, PackagingElementResolvingContext context, @Nullable String mainClass, @Nullable String classpath) {
|
||||
final CompositePackagingElement<?> rootElement = artifact.getRootElement();
|
||||
final ArtifactType type = artifact.getArtifactType();
|
||||
assertManifest(rootElement, context, type, mainClass, classpath);
|
||||
}
|
||||
|
||||
public static void assertManifest(CompositePackagingElement<?> rootElement,
|
||||
PackagingElementResolvingContext context,
|
||||
ArtifactType type,
|
||||
@Nullable String mainClass, @Nullable String classpath) {
|
||||
final VirtualFile file = ManifestFileUtil.findManifestFile(rootElement, context, type);
|
||||
assertThat(file).isNotNull();
|
||||
final Manifest manifest = ManifestFileUtil.readManifest(file);
|
||||
assertThat(manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS)).isEqualTo(mainClass);
|
||||
assertThat(manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH)).isEqualTo(classpath);
|
||||
}
|
||||
}
|
||||
|
||||
+562
-71
@@ -15,27 +15,61 @@
|
||||
*/
|
||||
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
||||
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.findUsages.FindUsagesHandler;
|
||||
import com.intellij.find.findUsages.FindUsagesManager;
|
||||
import com.intellij.find.findUsages.FindUsagesOptions;
|
||||
import com.intellij.find.impl.FindManagerImpl;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpec;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TestDialog;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.artifacts.ArtifactManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ConcurrentWeakKeySoftValueHashMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
@@ -48,7 +82,17 @@ import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
|
||||
|
||||
import static com.intellij.testFramework.EdtTestUtil.runInEdtAndGet;
|
||||
|
||||
// part of com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase
|
||||
public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
|
||||
@@ -58,17 +102,354 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
|
||||
private Logger logger;
|
||||
|
||||
@Override
|
||||
protected Module getModule(String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
|
||||
|
||||
protected abstract ProjectSystemId getExternalSystemId();
|
||||
|
||||
// assertion methods
|
||||
protected void assertModulesContains(@NotNull Project project, String... expectedNames) {
|
||||
Module[] actual = ModuleManager.getInstance(project).getModules();
|
||||
List<String> actualNames = new ArrayList<>();
|
||||
|
||||
for (Module m : actual) {
|
||||
actualNames.add(m.getName());
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
|
||||
assertContain(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModulesContains(String... expectedNames) {
|
||||
assertModulesContains(myProject, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModules(@NotNull Project project, String... expectedNames) {
|
||||
Module[] actual = ModuleManager.getInstance(project).getModules();
|
||||
List<String> actualNames = new ArrayList<>();
|
||||
|
||||
for (Module m : actual) {
|
||||
actualNames.add(m.getName());
|
||||
}
|
||||
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModules(String... expectedNames) {
|
||||
assertModules(myProject, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertContentRoots(String moduleName, String... expectedRoots) {
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
actual.add(e.getUrl());
|
||||
}
|
||||
|
||||
for (int i = 0; i < expectedRoots.length; i++) {
|
||||
expectedRoots[i] = VfsUtilCore.pathToUrl(expectedRoots[i]);
|
||||
}
|
||||
|
||||
assertUnorderedPathsAreEqual(actual, Arrays.asList(expectedRoots));
|
||||
}
|
||||
|
||||
protected void assertSources(String moduleName, String... expectedSources) {
|
||||
doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertGeneratedSources(String moduleName, String... expectedSources) {
|
||||
assertGeneratedSources(moduleName, JavaSourceRootType.SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertGeneratedTestSources(String moduleName, String... expectedSources) {
|
||||
assertGeneratedSources(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
private void assertGeneratedSources(String moduleName, JavaSourceRootType type, String... expectedSources) {
|
||||
final ContentEntry[] contentRoots = getContentRoots(moduleName);
|
||||
String rootUrl = contentRoots.length > 1 ? ExternalSystemApiUtil.getExternalProjectPath(getModule(moduleName)) : null;
|
||||
List<String> actual = new ArrayList<>();
|
||||
|
||||
for (ContentEntry contentRoot : contentRoots) {
|
||||
rootUrl = VirtualFileManager.extractPath(rootUrl == null ? contentRoot.getUrl() : rootUrl);
|
||||
for (SourceFolder f : contentRoot.getSourceFolders(type)) {
|
||||
String folderUrl = VirtualFileManager.extractPath(f.getUrl());
|
||||
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
|
||||
}
|
||||
|
||||
JavaSourceRootProperties properties = f.getJpsElement().getProperties(type);
|
||||
if (properties != null && properties.isForGeneratedSources()) {
|
||||
actual.add(folderUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertOrderedElementsAreEqual(actual, Arrays.asList(expectedSources));
|
||||
}
|
||||
|
||||
protected void assertResources(String moduleName, String... expectedSources) {
|
||||
doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestSources(String moduleName, String... expectedSources) {
|
||||
doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestResources(String moduleName, String... expectedSources) {
|
||||
doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertExcludes(String moduleName, String... expectedExcludes) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
doAssertContentFolders(contentRoot, Arrays.asList(contentRoot.getExcludeFolders()), expectedExcludes);
|
||||
}
|
||||
|
||||
protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
|
||||
ContentEntry root = getContentRoot(moduleName, contentRoot);
|
||||
doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes);
|
||||
}
|
||||
|
||||
private void doAssertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType<?> rootType, String... expected) {
|
||||
final ContentEntry[] contentRoots = getContentRoots(moduleName);
|
||||
final String rootUrl = contentRoots.length > 1 ? ExternalSystemApiUtil.getExternalProjectPath(getModule(moduleName)) : null;
|
||||
doAssertContentFolders(rootUrl, contentRoots, rootType, expected);
|
||||
}
|
||||
|
||||
protected static List<SourceFolder> doAssertContentFolders(@Nullable String rootUrl,
|
||||
ContentEntry[] contentRoots,
|
||||
@NotNull JpsModuleSourceRootType<?> rootType,
|
||||
String... expected) {
|
||||
List<SourceFolder> result = new ArrayList<>();
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (ContentEntry contentRoot : contentRoots) {
|
||||
for (SourceFolder f : contentRoot.getSourceFolders(rootType)) {
|
||||
rootUrl = VirtualFileManager.extractPath(rootUrl == null ? contentRoot.getUrl() : rootUrl);
|
||||
String folderUrl = VirtualFileManager.extractPath(f.getUrl());
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
|
||||
}
|
||||
|
||||
actual.add(folderUrl);
|
||||
result.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void doAssertContentFolders(ContentEntry e, final List<? extends ContentFolder> folders, String... expected) {
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (ContentFolder f : folders) {
|
||||
String rootUrl = e.getUrl();
|
||||
String folderUrl = f.getUrl();
|
||||
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
|
||||
}
|
||||
|
||||
actual.add(folderUrl);
|
||||
}
|
||||
|
||||
assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
protected void assertModuleOutputs(String moduleName, String... outputs) {
|
||||
String[] outputPaths = ContainerUtil.map2Array(CompilerPaths.getOutputPaths(new Module[]{getModule(moduleName)}), String.class,
|
||||
s -> getAbsolutePath(s));
|
||||
assertUnorderedElementsAreEqual(outputPaths, outputs);
|
||||
}
|
||||
|
||||
protected void assertModuleOutput(String moduleName, String output, String testOutput) {
|
||||
CompilerModuleExtension e = getCompilerExtension(moduleName);
|
||||
|
||||
assertFalse(e.isCompilerOutputPathInherited());
|
||||
assertEquals(output, getAbsolutePath(e.getCompilerOutputUrl()));
|
||||
assertEquals(testOutput, getAbsolutePath(e.getCompilerOutputUrlForTests()));
|
||||
}
|
||||
|
||||
protected void assertModuleInheritedOutput(String moduleName) {
|
||||
CompilerModuleExtension e = getCompilerExtension(moduleName);
|
||||
assertTrue(e.isCompilerOutputPathInherited());
|
||||
}
|
||||
|
||||
protected static String getAbsolutePath(String path) {
|
||||
path = VfsUtilCore.urlToPath(path);
|
||||
path = PathUtil.getCanonicalPath(path);
|
||||
return FileUtil.toSystemIndependentName(path);
|
||||
}
|
||||
|
||||
protected void assertProjectOutput(String module) {
|
||||
assertTrue(getCompilerExtension(module).isCompilerOutputPathInherited());
|
||||
}
|
||||
|
||||
protected CompilerModuleExtension getCompilerExtension(String module) {
|
||||
return CompilerModuleExtension.getInstance(getModule(module));
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName) {
|
||||
assertModuleLibDep(moduleName, depName, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath) {
|
||||
assertModuleLibDep(moduleName, depName, classesPath, null, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath, String sourcePath, String javadocPath) {
|
||||
LibraryOrderEntry lib = ContainerUtil.getFirstItem(getModuleLibDeps(moduleName, depName));
|
||||
final String errorMessage = "Failed to find dependency with name [" + depName + "] in module [" + moduleName + "]\n" +
|
||||
"Available dependencies: " + collectModuleDepsNames(moduleName, LibraryOrderEntry.class);
|
||||
assertNotNull(errorMessage, lib);
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPath == null ? null : Collections.singletonList(javadocPath));
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName,
|
||||
String depName,
|
||||
List<String> classesPaths,
|
||||
List<String> sourcePaths,
|
||||
List<String> javadocPaths) {
|
||||
LibraryOrderEntry lib = ContainerUtil.getFirstItem(getModuleLibDeps(moduleName, depName));
|
||||
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePaths);
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPaths);
|
||||
}
|
||||
|
||||
private static void assertModuleLibDepPath(LibraryOrderEntry lib, OrderRootType type, List<String> paths) {
|
||||
assertNotNull(lib);
|
||||
if (paths == null) return;
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(lib.getRootUrls(type)), paths);
|
||||
// also check the library because it may contain slight different set of urls (e.g. with duplicates)
|
||||
final Library library = lib.getLibrary();
|
||||
assertNotNull(library);
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(library.getUrls(type)), paths);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDepScope(String moduleName, String depName, DependencyScope... scopes) {
|
||||
List<LibraryOrderEntry> deps = getModuleLibDeps(moduleName, depName);
|
||||
assertUnorderedElementsAreEqual(ContainerUtil.map2Array(deps, entry -> entry.getScope()), scopes);
|
||||
}
|
||||
|
||||
protected List<LibraryOrderEntry> getModuleLibDeps(String moduleName, String depName) {
|
||||
return getModuleDep(moduleName, depName, LibraryOrderEntry.class);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, LibraryOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDeps(BiPredicate<String, String> predicate, String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(predicate, moduleName, LibraryOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertExportedDeps(String moduleName, String... expectedDeps) {
|
||||
final List<String> actual = new ArrayList<>();
|
||||
|
||||
getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly().process(new RootPolicy<Object>() {
|
||||
@Override
|
||||
public Object visitModuleOrderEntry(@NotNull ModuleOrderEntry e, Object value) {
|
||||
actual.add(e.getModuleName());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLibraryOrderEntry(@NotNull LibraryOrderEntry e, Object value) {
|
||||
actual.add(e.getLibraryName());
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
|
||||
assertOrderedElementsAreEqual(actual, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, ModuleOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
private void assertModuleDeps(String moduleName, Class clazz, String... expectedDeps) {
|
||||
assertModuleDeps(equalsPredicate(), moduleName, clazz, expectedDeps);
|
||||
}
|
||||
|
||||
private void assertModuleDeps(BiPredicate<String, String> predicate, String moduleName, Class clazz, String... expectedDeps) {
|
||||
assertOrderedElementsAreEqual(predicate, collectModuleDepsNames(moduleName, clazz), expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertProductionOnTestDependencies(String moduleName, String... expectedDeps) {
|
||||
assertOrderedElementsAreEqual(collectModuleDepsNames(
|
||||
moduleName, entry -> entry instanceof ModuleOrderEntry && ((ModuleOrderEntry)entry).isProductionOnTestDependency()
|
||||
), expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope... scopes) {
|
||||
List<ModuleOrderEntry> deps = getModuleModuleDeps(moduleName, depName);
|
||||
assertUnorderedElementsAreEqual(ContainerUtil.map2Array(deps, entry -> entry.getScope()), scopes);
|
||||
}
|
||||
|
||||
protected void assertNoModuleDepForModule(String moduleName, String depName) {
|
||||
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class));
|
||||
}
|
||||
|
||||
protected void assertNoLibraryDepForModule(String moduleName, String depName) {
|
||||
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, LibraryOrderEntry.class));
|
||||
}
|
||||
|
||||
public void assertProjectLibraries(String... expectedNames) {
|
||||
List<String> actualNames = new ArrayList<>();
|
||||
for (Library each : LibraryTablesRegistrar.getInstance().getLibraryTable(myProject).getLibraries()) {
|
||||
String name = each.getName();
|
||||
actualNames.add(name == null ? "<unnamed>" : name);
|
||||
}
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModuleGroupPath(String moduleName, String... expected) {
|
||||
String[] path = ModuleManager.getInstance(myProject).getModuleGroupPath(getModule(moduleName));
|
||||
|
||||
if (expected.length == 0) {
|
||||
assertNull(path);
|
||||
}
|
||||
else {
|
||||
assertNotNull(path);
|
||||
assertOrderedElementsAreEqual(Arrays.asList(path), expected);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertArtifacts(String... expectedNames) {
|
||||
final List<String> actualNames = ContainerUtil.map(
|
||||
ArtifactManager.getInstance(myProject).getAllArtifactsIncludingInvalid(),
|
||||
(Function<Artifact, String>)artifact -> artifact.getName());
|
||||
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
//end of assertions
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName) {
|
||||
ContentEntry[] ee = getContentRoots(moduleName);
|
||||
List<String> roots = new ArrayList<>();
|
||||
for (ContentEntry e : ee) {
|
||||
roots.add(e.getUrl());
|
||||
}
|
||||
|
||||
String message = "Several content roots found: [" + StringUtil.join(roots, ", ") + "]";
|
||||
assertEquals(message, 1, ee.length);
|
||||
|
||||
return ee[0];
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName, String path) {
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
if (e.getUrl().equals(VfsUtilCore.pathToUrl(path))) return e;
|
||||
}
|
||||
throw new AssertionError("content root not found");
|
||||
}
|
||||
|
||||
public ContentEntry[] getContentRoots(String moduleName) {
|
||||
return getRootManager(moduleName).getContentEntries();
|
||||
}
|
||||
|
||||
protected void importProject(@NonNls String config) throws IOException {
|
||||
@@ -198,71 +579,161 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
|
||||
private void doImportProject() {
|
||||
AbstractExternalSystemSettings systemSettings = ExternalSystemApiUtil.getSettings(myProject, getExternalSystemId());
|
||||
ExternalProjectSettings projectSettings = getCurrentExternalProjectSettings();
|
||||
final ExternalProjectSettings projectSettings = getCurrentExternalProjectSettings();
|
||||
projectSettings.setExternalProjectPath(getProjectPath());
|
||||
@SuppressWarnings("unchecked") Set<ExternalProjectSettings> projects =
|
||||
ContainerUtilRt.newHashSet(systemSettings.getLinkedProjectsSettings());
|
||||
//noinspection unchecked
|
||||
Set<ExternalProjectSettings> projects = new HashSet<>(systemSettings.getLinkedProjectsSettings());
|
||||
projects.remove(projectSettings);
|
||||
projects.add(projectSettings);
|
||||
//noinspection unchecked
|
||||
systemSettings.setLinkedProjectsSettings(projects);
|
||||
|
||||
final Ref<Couple<String>> error = Ref.create();
|
||||
ExternalSystemUtil.refreshProjects(
|
||||
new TestImportSpecBuilder(myProject, getExternalSystemId())
|
||||
.setCreateEmptyContentRoots(projectSettings.isCreateEmptyContentRootDirectories())
|
||||
.use(ProgressExecutionMode.MODAL_SYNC)
|
||||
.callback(new ExternalProjectRefreshCallback() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable DataNode<ProjectData> externalProject) {
|
||||
if (externalProject == null) {
|
||||
System.err.println("Got null External project after import");
|
||||
return;
|
||||
}
|
||||
inspectForGradleMemoryLeaks(externalProject);
|
||||
ServiceManager.getService(ProjectDataManager.class).importData(externalProject, myProject, true);
|
||||
System.out.println("External project was successfully imported");
|
||||
}
|
||||
ImportSpec importSpec = createImportSpec();
|
||||
ExternalProjectRefreshCallback callback = importSpec.getCallback();
|
||||
if (callback == null || callback instanceof ImportSpecBuilder.DefaultProjectRefreshCallback) {
|
||||
importSpec = new TestImportSpecBuilder(importSpec)
|
||||
.setCreateEmptyContentRoots(projectSettings.isCreateEmptyContentRootDirectories())
|
||||
.callback(new ExternalProjectRefreshCallback() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable final DataNode<ProjectData> externalProject) {
|
||||
if (externalProject == null) {
|
||||
System.err.println("Got null External project after import");
|
||||
return;
|
||||
}
|
||||
ServiceManager.getService(ProjectDataManager.class).importData(externalProject, myProject, true);
|
||||
System.out.println("External project was successfully imported");
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
|
||||
error.set(Couple.of(errorMessage, errorDetails));
|
||||
}
|
||||
})
|
||||
.forceWhenUptodate()
|
||||
);
|
||||
inspectForGradleMemoryLeaks(externalProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
|
||||
error.set(Couple.of(errorMessage, errorDetails));
|
||||
}
|
||||
}).build();
|
||||
}
|
||||
|
||||
ExternalSystemProgressNotificationManager notificationManager =
|
||||
ServiceManager.getService(ExternalSystemProgressNotificationManager.class);
|
||||
ExternalSystemTaskNotificationListenerAdapter listener = new ExternalSystemTaskNotificationListenerAdapter() {
|
||||
@Override
|
||||
public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) {
|
||||
if (StringUtil.isEmptyOrSpaces(text)) return;
|
||||
(stdOut ? System.out : System.err).print(text);
|
||||
}
|
||||
};
|
||||
notificationManager.addNotificationListener(listener);
|
||||
try {
|
||||
ExternalSystemUtil.refreshProjects(importSpec);
|
||||
}
|
||||
finally {
|
||||
notificationManager.removeNotificationListener(listener);
|
||||
}
|
||||
|
||||
if (!error.isNull()) {
|
||||
String failureMsg = "Import failed: " + error.get().first;
|
||||
if (StringUtil.isNotEmpty(error.get().second)) {
|
||||
failureMsg += "\nError details: \n" + error.get().second;
|
||||
handleImportFailure(error.get().first, error.get().second);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleImportFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
|
||||
String failureMsg = "Import failed: " + errorMessage;
|
||||
if (StringUtil.isNotEmpty(errorDetails)) {
|
||||
failureMsg += "\nError details: \n" + errorDetails;
|
||||
}
|
||||
fail(failureMsg);
|
||||
}
|
||||
|
||||
protected ImportSpec createImportSpec() {
|
||||
ImportSpecBuilder importSpecBuilder = new ImportSpecBuilder(myProject, getExternalSystemId())
|
||||
.use(ProgressExecutionMode.MODAL_SYNC)
|
||||
.forceWhenUptodate();
|
||||
return importSpecBuilder.build();
|
||||
}
|
||||
|
||||
protected void setupJdkForModules(String... moduleNames) {
|
||||
for (String each : moduleNames) {
|
||||
setupJdkForModule(each);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk setupJdkForModule(final String moduleName) {
|
||||
final Sdk sdk = true ? JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk() : createJdk("Java 1.5");
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
|
||||
return sdk;
|
||||
}
|
||||
|
||||
protected static Sdk createJdk(String versionName) {
|
||||
return IdeaTestUtil.getMockJdk17(versionName);
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForYesAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(@NotNull String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForNoAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(@NotNull String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected static Collection<UsageInfo> findUsages(@NotNull PsiElement element) throws Exception {
|
||||
return ProgressManager.getInstance().run(new Task.WithResult<Collection<UsageInfo>, Exception>(null, "", false) {
|
||||
@Override
|
||||
protected Collection<UsageInfo> compute(@NotNull ProgressIndicator indicator) {
|
||||
return runInEdtAndGet(() -> {
|
||||
FindUsagesManager findUsagesManager = ((FindManagerImpl) FindManager.getInstance(element.getProject())).getFindUsagesManager();
|
||||
FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false);
|
||||
assertNotNull(handler);
|
||||
final FindUsagesOptions options = handler.getFindUsagesOptions();
|
||||
final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<>();
|
||||
for (PsiElement element : handler.getPrimaryElements()) {
|
||||
handler.processElementUsages(element, processor, options);
|
||||
}
|
||||
for (PsiElement element : handler.getSecondaryElements()) {
|
||||
handler.processElementUsages(element, processor, options);
|
||||
}
|
||||
return processor.getResults();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected SourceFolder findSource(@NotNull String moduleName, @NotNull String sourcePath) {
|
||||
return findSource(getRootManager(moduleName), sourcePath);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected SourceFolder findSource(@NotNull ModuleRootModel moduleRootManager, @NotNull String sourcePath) {
|
||||
ContentEntry[] contentRoots = moduleRootManager.getContentEntries();
|
||||
Module module = moduleRootManager.getModule();
|
||||
String rootUrl = getAbsolutePath(ExternalSystemApiUtil.getExternalProjectPath(module));
|
||||
for (ContentEntry contentRoot : contentRoots) {
|
||||
for (SourceFolder f : contentRoot.getSourceFolders()) {
|
||||
String folderPath = getAbsolutePath(f.getUrl());
|
||||
String rootPath = getAbsolutePath(rootUrl + "/" + sourcePath);
|
||||
if (folderPath.equals(rootPath)) return f;
|
||||
}
|
||||
fail(failureMsg);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
|
||||
|
||||
protected abstract ProjectSystemId getExternalSystemId();
|
||||
|
||||
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope... scopes) {
|
||||
List<ModuleOrderEntry> deps = getModuleModuleDeps(moduleName, depName);
|
||||
Set<DependencyScope> actualScopes = new HashSet<DependencyScope>();
|
||||
for (ModuleOrderEntry dep : deps) {
|
||||
actualScopes.add(dep.getScope());
|
||||
}
|
||||
HashSet<DependencyScope> expectedScopes = new HashSet<DependencyScope>(Arrays.asList(scopes));
|
||||
assertEquals("Dependency '" + depName + "' for module '" + moduleName + "' has unexpected scope",
|
||||
expectedScopes, actualScopes);
|
||||
}
|
||||
|
||||
protected void assertNoModuleDepForModule(String moduleName, String depName) {
|
||||
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class));
|
||||
}
|
||||
|
||||
protected void assertNoLibraryDepForModule(String moduleName, String depName) {
|
||||
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, LibraryOrderEntry.class));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
|
||||
@@ -273,16 +744,31 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
return ModuleRootManager.getInstance(getModule(module));
|
||||
}
|
||||
|
||||
protected void ignoreData(BooleanFunction<DataNode<?>> booleanFunction, final boolean ignored) {
|
||||
final ExternalProjectInfo externalProjectInfo = ProjectDataManagerImpl.getInstance().getExternalProjectData(
|
||||
myProject, getExternalSystemId(), getCurrentExternalProjectSettings().getExternalProjectPath());
|
||||
assertNotNull(externalProjectInfo);
|
||||
|
||||
final DataNode<ProjectData> projectDataNode = externalProjectInfo.getExternalProjectStructure();
|
||||
assertNotNull(projectDataNode);
|
||||
|
||||
final Collection<DataNode<?>> nodes = ExternalSystemApiUtil.findAllRecursively(projectDataNode, booleanFunction);
|
||||
for (DataNode<?> node : nodes) {
|
||||
node.visit(dataNode -> dataNode.setIgnored(ignored));
|
||||
}
|
||||
ServiceManager.getService(ProjectDataManager.class).importData(projectDataNode, myProject, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
|
||||
List<T> deps = collectModuleDeps(moduleName, depName, clazz);
|
||||
assertTrue("Dependency '" +
|
||||
depName +
|
||||
"' for module '" +
|
||||
moduleName +
|
||||
"' not found among: " +
|
||||
collectModuleDepsNames(moduleName, clazz),
|
||||
!deps.isEmpty());
|
||||
List<T> deps = new ArrayList<>();
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
|
||||
deps.add((T)e);
|
||||
}
|
||||
}
|
||||
assertNotNull("Dependency for module \"" + moduleName + "\" not found: " + depName + "\namong: " + collectModuleDepsNames(moduleName, clazz), deps);
|
||||
return deps;
|
||||
}
|
||||
|
||||
@@ -299,14 +785,19 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
return deps;
|
||||
}
|
||||
|
||||
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
private List<String> collectModuleDepsNames(String moduleName, Predicate<OrderEntry> predicate) {
|
||||
List<String> actual = new ArrayList<>();
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e)) {
|
||||
if (predicate.test(e)) {
|
||||
actual.add(e.getPresentableName());
|
||||
}
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
|
||||
return collectModuleDepsNames(moduleName, entry -> clazz.isInstance(entry));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+496
-120
@@ -15,156 +15,199 @@
|
||||
*/
|
||||
package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
||||
|
||||
import com.intellij.compiler.CompilerTestUtil;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.compiler.impl.ModuleCompileScope;
|
||||
import com.intellij.compiler.server.BuildManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.ByteArraySequence;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.testFramework.EdtTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
|
||||
import com.intellij.task.ProjectTaskManager;
|
||||
import com.intellij.testFramework.*;
|
||||
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.io.PathKt;
|
||||
import com.intellij.util.io.TestFileSystemItem;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.SystemIndependent;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import static com.intellij.testFramework.EdtTestUtilKt.runInEdtAndWait;
|
||||
|
||||
// part of com.intellij.openapi.externalSystem.test.ExternalSystemTestCase
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
|
||||
private static final BiPredicate<Object, Object> EQUALS_PREDICATE = (t, u) -> Objects.equals(t, u);
|
||||
|
||||
private File ourTempDir;
|
||||
|
||||
protected IdeaProjectTestFixture myTestFixture;
|
||||
|
||||
protected Project myProject;
|
||||
|
||||
private VirtualFile myProjectRoot;
|
||||
private final List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>();
|
||||
protected File myTestDir;
|
||||
protected VirtualFile myProjectRoot;
|
||||
protected VirtualFile myProjectConfig;
|
||||
protected List<VirtualFile> myAllConfigs = new ArrayList<>();
|
||||
protected boolean useProjectTaskManager;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ensureTempDirCreated();
|
||||
|
||||
myTestDir = ourTempDir;//TODO was new File(ourTempDir, getTestName(false)); but paths appear to be too long
|
||||
FileUtil.ensureExists(myTestDir);
|
||||
|
||||
setUpFixtures();
|
||||
myProject = myTestFixture.getProject();
|
||||
|
||||
invokeTestRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setUpInWriteAction();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
try {
|
||||
tearDown();
|
||||
}
|
||||
catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
EdtTestUtil.runInEdtAndWait(() -> ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
try {
|
||||
setUpInWriteAction();
|
||||
}
|
||||
});
|
||||
catch (Throwable e) {
|
||||
try {
|
||||
tearDown();
|
||||
}
|
||||
catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
|
||||
List<String> allowedRoots = new ArrayList<String>();
|
||||
List<String> allowedRoots = new ArrayList<>();
|
||||
collectAllowedRoots(allowedRoots);
|
||||
if (!allowedRoots.isEmpty()) {
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), ArrayUtil.toStringArray(allowedRoots));
|
||||
VfsRootAccess.allowRootAccess(myTestFixture.getTestRootDisposable(), ArrayUtilRt.toStringArray(allowedRoots));
|
||||
}
|
||||
|
||||
CompilerTestUtil.enableExternalCompiler();
|
||||
}
|
||||
|
||||
protected void collectAllowedRoots(List<String> roots) throws IOException {
|
||||
protected void collectAllowedRoots(List<String> roots) {
|
||||
}
|
||||
|
||||
public static Collection<String> collectRootsInside(String root) {
|
||||
final List<String> roots = ContainerUtil.newSmartList();
|
||||
final List<String> roots = new SmartList<>();
|
||||
roots.add(root);
|
||||
FileUtil.processFilesRecursively(new File(root), new Processor<File>() {
|
||||
@Override
|
||||
public boolean process(File file) {
|
||||
try {
|
||||
String path = file.getCanonicalPath();
|
||||
if (!FileUtil.isAncestor(path, path, false)) {
|
||||
roots.add(path);
|
||||
}
|
||||
FileUtil.processFilesRecursively(new File(root), file -> {
|
||||
try {
|
||||
String path = file.getCanonicalPath();
|
||||
if (!FileUtil.isAncestor(path, path, false)) {
|
||||
roots.add(path);
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
private void ensureTempDirCreated() throws IOException {
|
||||
if (ourTempDir != null) return;
|
||||
|
||||
ourTempDir = new File(FileUtil.getTempDirectory(), getTestsTempDir());
|
||||
FileUtil.delete(ourTempDir);
|
||||
FileUtil.ensureExists(ourTempDir);
|
||||
}
|
||||
|
||||
protected final String getTestsTempDir() {
|
||||
return "";
|
||||
}
|
||||
|
||||
protected void setUpFixtures() throws Exception {
|
||||
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture();
|
||||
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName(), useDirectoryBasedStorageFormat()).getFixture();
|
||||
myTestFixture.setUp();
|
||||
}
|
||||
|
||||
private void setUpInWriteAction() throws Exception {
|
||||
File projectDir = FileUtil.createTempDirectory("project", "", false);
|
||||
protected boolean useDirectoryBasedStorageFormat() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void setUpInWriteAction() throws Exception {
|
||||
File projectDir = new File(myTestDir, "project");
|
||||
FileUtil.ensureExists(projectDir);
|
||||
myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir);
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
try {
|
||||
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
CompilerTestUtil.disableExternalCompiler(myProject);
|
||||
tearDownFixtures();
|
||||
}
|
||||
});
|
||||
myProject = null;
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
resetClassFields(getClass());
|
||||
}
|
||||
new RunAll(
|
||||
() -> {
|
||||
if (myProject != null && !myProject.isDisposed()) {
|
||||
PathKt.delete(ProjectUtil.getExternalConfigurationDir(myProject));
|
||||
}
|
||||
},
|
||||
() -> EdtTestUtil.runInEdtAndWait(() -> tearDownFixtures()),
|
||||
() -> myProject = null,
|
||||
() -> PathKt.delete(myTestDir.toPath()),
|
||||
() -> super.tearDown(),
|
||||
() -> resetClassFields(getClass())
|
||||
).run();
|
||||
}
|
||||
|
||||
protected void tearDownFixtures() throws Exception {
|
||||
myTestFixture.tearDown();
|
||||
protected void tearDownFixtures() {
|
||||
if (myTestFixture != null) {
|
||||
try {
|
||||
myTestFixture.tearDown();
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
myTestFixture = null;
|
||||
}
|
||||
|
||||
private void resetClassFields(Class<?> aClass) {
|
||||
private void resetClassFields(final Class<?> aClass) {
|
||||
if (aClass == null) return;
|
||||
|
||||
Field[] fields = aClass.getDeclaredFields();
|
||||
final Field[] fields = aClass.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
final int modifiers = field.getModifiers();
|
||||
if ((modifiers & Modifier.FINAL) == 0
|
||||
@@ -187,7 +230,17 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
try {
|
||||
super.runTest();
|
||||
if (runInWriteAction()) {
|
||||
try {
|
||||
WriteAction.runAndWait(() -> super.runTest());
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
ExceptionUtil.rethrowAllAsUnchecked(throwable);
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.runTest();
|
||||
}
|
||||
}
|
||||
catch (Exception throwable) {
|
||||
Throwable each = throwable;
|
||||
@@ -203,11 +256,12 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
|
||||
runInEdtAndWait(() -> {
|
||||
runnable.run();
|
||||
return null;
|
||||
});
|
||||
protected void invokeTestRunnable(@NotNull Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
protected boolean runInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static String getRoot() {
|
||||
@@ -215,74 +269,356 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
return "";
|
||||
}
|
||||
|
||||
protected static String getEnvVar() {
|
||||
if (SystemInfo.isWindows) return "TEMP";
|
||||
else if (SystemInfo.isLinux) return "HOME";
|
||||
return "TMPDIR";
|
||||
}
|
||||
|
||||
protected String getProjectPath() {
|
||||
return myProjectRoot.getPath();
|
||||
}
|
||||
|
||||
protected VirtualFile createProjectConfig(@NonNls String config) throws IOException {
|
||||
return createConfigFile(myProjectRoot, config);
|
||||
protected String getParentPath() {
|
||||
return myProjectRoot.getParent().getPath();
|
||||
}
|
||||
|
||||
private VirtualFile createConfigFile(final VirtualFile dir, String config) throws IOException {
|
||||
final String configFileName = getExternalSystemConfigFileName();
|
||||
VirtualFile f = dir.findChild(configFileName);
|
||||
if (f == null) {
|
||||
f = new WriteAction<VirtualFile>() {
|
||||
@Override
|
||||
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
|
||||
VirtualFile res = dir.createChildData(null, configFileName);
|
||||
result.setResult(res);
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
myAllConfigs.add(f);
|
||||
@SystemIndependent
|
||||
protected String path(@NotNull String relativePath) {
|
||||
return PathUtil.toSystemIndependentName(file(relativePath).getPath());
|
||||
}
|
||||
|
||||
protected File file(@NotNull String relativePath) {
|
||||
return new File(getProjectPath(), relativePath);
|
||||
}
|
||||
|
||||
protected Module createModule(String name) {
|
||||
return createModule(name, StdModuleTypes.JAVA);
|
||||
}
|
||||
|
||||
protected Module createModule(final String name, final ModuleType type) {
|
||||
try {
|
||||
return WriteCommandAction.writeCommandAction(myProject).compute(() -> {
|
||||
VirtualFile f = createProjectSubFile(name + "/" + name + ".iml");
|
||||
Module module = ModuleManager.getInstance(myProject).newModule(f.getPath(), type.getId());
|
||||
PsiTestUtil.addContentRoot(module, f.getParent());
|
||||
return module;
|
||||
});
|
||||
}
|
||||
setFileContent(f, config, true);
|
||||
return f;
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected VirtualFile createProjectConfig(@NonNls String config) {
|
||||
return myProjectConfig = createConfigFile(myProjectRoot, config);
|
||||
}
|
||||
|
||||
protected VirtualFile createConfigFile(final VirtualFile dir, String config) {
|
||||
final String configFileName = getExternalSystemConfigFileName();
|
||||
VirtualFile configFile;
|
||||
try {
|
||||
configFile = WriteAction.computeAndWait(() -> {
|
||||
VirtualFile file = dir.findChild(configFileName);
|
||||
return file == null ? dir.createChildData(null, configFileName) : file;
|
||||
});
|
||||
myAllConfigs.add(configFile);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
setFileContent(configFile, config, true);
|
||||
return configFile;
|
||||
}
|
||||
|
||||
protected abstract String getExternalSystemConfigFileName();
|
||||
|
||||
protected void createStdProjectFolders() throws IOException {
|
||||
createProjectSubDirs("src/main/java",
|
||||
"src/main/resources",
|
||||
"src/test/java",
|
||||
"src/test/resources");
|
||||
}
|
||||
|
||||
protected void createProjectSubDirs(String... relativePaths) throws IOException {
|
||||
for (String path : relativePaths) {
|
||||
createProjectSubDir(path);
|
||||
}
|
||||
}
|
||||
|
||||
protected VirtualFile createProjectSubDir(String relativePath) throws IOException {
|
||||
File f = new File(getProjectPath(), relativePath);
|
||||
FileUtil.ensureExists(f);
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
|
||||
}
|
||||
|
||||
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
|
||||
File f = new File(getProjectPath(), relativePath);
|
||||
FileUtil.ensureExists(f.getParentFile());
|
||||
FileUtil.ensureCanCreateFile(f);
|
||||
boolean created = f.createNewFile();
|
||||
if (!created) {
|
||||
final boolean created = f.createNewFile();
|
||||
if (!created && !f.exists()) {
|
||||
throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
|
||||
}
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected VirtualFile createProjectJarSubFile(String relativePath, Pair<ByteArraySequence, String>... contentEntries) throws IOException {
|
||||
assertTrue("Use 'jar' extension for JAR files: '" + relativePath + "'", FileUtilRt.extensionEquals(relativePath, "jar"));
|
||||
File f = new File(getProjectPath(), relativePath);
|
||||
FileUtil.ensureExists(f.getParentFile());
|
||||
FileUtil.ensureCanCreateFile(f);
|
||||
final boolean created = f.createNewFile();
|
||||
if (!created) {
|
||||
throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
|
||||
}
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
JarOutputStream target = new JarOutputStream(new FileOutputStream(f), manifest);
|
||||
for (Pair<ByteArraySequence, String> contentEntry : contentEntries) {
|
||||
addJarEntry(contentEntry.first.getBytes(), contentEntry.second, target);
|
||||
}
|
||||
target.close();
|
||||
|
||||
final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
|
||||
assertNotNull(virtualFile);
|
||||
final VirtualFile jarFile = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile);
|
||||
assertNotNull(jarFile);
|
||||
return jarFile;
|
||||
}
|
||||
|
||||
private static void addJarEntry(byte[] bytes, String path, JarOutputStream target) throws IOException {
|
||||
JarEntry entry = new JarEntry(path.replace("\\", "/"));
|
||||
target.putNextEntry(entry);
|
||||
target.write(bytes);
|
||||
target.close();
|
||||
}
|
||||
|
||||
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
|
||||
VirtualFile file = createProjectSubFile(relativePath);
|
||||
setFileContent(file, content, false);
|
||||
return file;
|
||||
}
|
||||
|
||||
protected Module getModule(String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
|
||||
protected void compileModules(final String... moduleNames) {
|
||||
if (useProjectTaskManager) {
|
||||
Module[] modules = Arrays.stream(moduleNames).map(moduleName -> getModule(moduleName)).toArray(Module[]::new);
|
||||
build(modules);
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
else {
|
||||
compile(createModulesCompileScope(moduleNames));
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
|
||||
new WriteAction<VirtualFile>() {
|
||||
@Override
|
||||
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
|
||||
if (advanceStamps) {
|
||||
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), -1, file.getTimeStamp() + 4000);
|
||||
}
|
||||
else {
|
||||
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), file.getModificationStamp(), file.getTimeStamp());
|
||||
protected void buildArtifacts(String... artifactNames) {
|
||||
if (useProjectTaskManager) {
|
||||
Artifact[] artifacts = Arrays.stream(artifactNames)
|
||||
.map(artifactName -> ArtifactsTestUtil.findArtifact(myProject, artifactName)).toArray(Artifact[]::new);
|
||||
build(artifacts);
|
||||
}
|
||||
else {
|
||||
compile(createArtifactsScope(artifactNames));
|
||||
}
|
||||
}
|
||||
|
||||
private void build(Object[] buildableElements) {
|
||||
Promise<ProjectTaskManager.Result> promise;
|
||||
if (buildableElements instanceof Module[]) {
|
||||
promise = ProjectTaskManager.getInstance(myProject).build((Module[])buildableElements);
|
||||
}
|
||||
else if (buildableElements instanceof Artifact[]) {
|
||||
promise = ProjectTaskManager.getInstance(myProject).build((Artifact[])buildableElements);
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unsupported buildableElements: " + Arrays.toString(buildableElements));
|
||||
}
|
||||
edt(() -> PlatformTestUtil.waitForPromise(promise));
|
||||
}
|
||||
|
||||
private void compile(@NotNull CompileScope scope) {
|
||||
try {
|
||||
CompilerTester tester = new CompilerTester(myProject, Arrays.asList(scope.getAffectedModules()), null);
|
||||
try {
|
||||
List<CompilerMessage> messages = tester.make(scope);
|
||||
for (CompilerMessage message : messages) {
|
||||
switch (message.getCategory()) {
|
||||
case ERROR:
|
||||
fail("Compilation failed with error: " + message.getMessage());
|
||||
break;
|
||||
case WARNING:
|
||||
System.out.println("Compilation warning: " + message.getMessage());
|
||||
break;
|
||||
case INFORMATION:
|
||||
break;
|
||||
case STATISTICS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
finally {
|
||||
tester.tearDown();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExceptionUtil.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private CompileScope createModulesCompileScope(final String[] moduleNames) {
|
||||
final List<Module> modules = new ArrayList<>();
|
||||
for (String name : moduleNames) {
|
||||
modules.add(getModule(name));
|
||||
}
|
||||
return new ModuleCompileScope(myProject, modules.toArray(Module.EMPTY_ARRAY), false);
|
||||
}
|
||||
|
||||
private CompileScope createArtifactsScope(String[] artifactNames) {
|
||||
List<Artifact> artifacts = new ArrayList<>();
|
||||
for (String name : artifactNames) {
|
||||
artifacts.add(ArtifactsTestUtil.findArtifact(myProject, name));
|
||||
}
|
||||
return ArtifactCompileScope.createArtifactsScope(myProject, artifacts);
|
||||
}
|
||||
|
||||
protected Sdk setupJdkForModule(final String moduleName) {
|
||||
final Sdk sdk = true ? JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk() : createJdk();
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
|
||||
return sdk;
|
||||
}
|
||||
|
||||
protected static Sdk createJdk() {
|
||||
return IdeaTestUtil.getMockJdk17();
|
||||
}
|
||||
|
||||
protected Module getModule(final String name) {
|
||||
return getModule(myProject, name);
|
||||
}
|
||||
|
||||
protected Module getModule(Project project, String name) {
|
||||
Module m = ReadAction.compute(() -> ModuleManager.getInstance(project).findModuleByName(name));
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
}
|
||||
|
||||
protected void assertExplodedLayout(String artifactName, String expected) {
|
||||
assertJarLayout(artifactName + " exploded", expected);
|
||||
}
|
||||
|
||||
protected void assertJarLayout(String artifactName, String expected) {
|
||||
ArtifactsTestUtil.assertLayout(myProject, artifactName, expected);
|
||||
}
|
||||
|
||||
protected void assertArtifactOutputPath(final String artifactName, final String expected) {
|
||||
ArtifactsTestUtil.assertOutputPath(myProject, artifactName, expected);
|
||||
}
|
||||
|
||||
protected void assertArtifactOutputFileName(final String artifactName, final String expected) {
|
||||
ArtifactsTestUtil.assertOutputFileName(myProject, artifactName, expected);
|
||||
}
|
||||
|
||||
protected void assertArtifactOutput(String artifactName, TestFileSystemItem fs) {
|
||||
final Artifact artifact = ArtifactsTestUtil.findArtifact(myProject, artifactName);
|
||||
final String outputFile = artifact.getOutputFilePath();
|
||||
assert outputFile != null;
|
||||
final File file = new File(outputFile);
|
||||
assert file.exists();
|
||||
fs.assertFileEqual(file);
|
||||
}
|
||||
|
||||
protected static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) {
|
||||
try {
|
||||
WriteAction.runAndWait(() -> {
|
||||
if (advanceStamps) {
|
||||
file.setBinaryContent(content.getBytes(StandardCharsets.UTF_8), -1, file.getTimeStamp() + 4000);
|
||||
}
|
||||
else {
|
||||
file.setBinaryContent(content.getBytes(StandardCharsets.UTF_8), file.getModificationStamp(), file.getTimeStamp());
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, Collection<T> expected) {
|
||||
assertOrderedElementsAreEqual(actual, expected.toArray());
|
||||
}
|
||||
|
||||
protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) {
|
||||
assertEquals(new HashSet<>(expected), new HashSet<>(actual));
|
||||
}
|
||||
|
||||
protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) {
|
||||
assertEquals(new SetWithToString<>(new THashSet<>(expected, FileUtil.PATH_HASHING_STRATEGY)),
|
||||
new SetWithToString<>(new THashSet<>(actual, FileUtil.PATH_HASHING_STRATEGY)));
|
||||
}
|
||||
|
||||
protected static <T> void assertUnorderedElementsAreEqual(T[] actual, T... expected) {
|
||||
assertUnorderedElementsAreEqual(Arrays.asList(actual), expected);
|
||||
}
|
||||
|
||||
protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, T... expected) {
|
||||
assertUnorderedElementsAreEqual(actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, T... expected) {
|
||||
assertOrderedElementsAreEqual(equalsPredicate(), actual, expected);
|
||||
}
|
||||
|
||||
protected static <T, U> void assertOrderedElementsAreEqual(BiPredicate<U, T> predicate, Collection<U> actual, T... expected) {
|
||||
String s = "\nexpected: " + Arrays.asList(expected) + "\nactual: " + new ArrayList<>(actual);
|
||||
assertEquals(s, expected.length, actual.size());
|
||||
|
||||
java.util.List<U> actualList = new ArrayList<>(actual);
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
T expectedElement = expected[i];
|
||||
U actualElement = actualList.get(i);
|
||||
assertTrue(s, predicate.test(actualElement, expectedElement));
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T> void assertContain(java.util.List<? extends T> actual, T... expected) {
|
||||
java.util.List<T> expectedList = Arrays.asList(expected);
|
||||
assertTrue("expected: " + expectedList + "\n" + "actual: " + actual.toString(), actual.containsAll(expectedList));
|
||||
}
|
||||
|
||||
protected static <T> void assertDoNotContain(java.util.List<T> actual, T... expected) {
|
||||
java.util.List<T> actualCopy = new ArrayList<>(actual);
|
||||
actualCopy.removeAll(Arrays.asList(expected));
|
||||
assertEquals(actual.toString(), actualCopy.size(), actual.size());
|
||||
}
|
||||
|
||||
protected boolean ignore() {
|
||||
printIgnoredMessage(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static <T, U> BiPredicate<T, U> equalsPredicate() {
|
||||
//noinspection unchecked
|
||||
return (BiPredicate<T, U>)EQUALS_PREDICATE;
|
||||
}
|
||||
|
||||
public static void deleteBuildSystemDirectory() {
|
||||
BuildManager buildManager = BuildManager.getInstance();
|
||||
if (buildManager == null) return;
|
||||
Path buildSystemDirectory = buildManager.getBuildSystemDirectory();
|
||||
try {
|
||||
PathKt.delete(buildSystemDirectory);
|
||||
return;
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
try {
|
||||
FileUtil.delete(buildSystemDirectory.toFile());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Unable to remove build system directory.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void printIgnoredMessage(String message) {
|
||||
@@ -293,4 +629,44 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
toPrint += ": " + getClass().getSimpleName() + "." + getName();
|
||||
System.out.println(toPrint);
|
||||
}
|
||||
|
||||
private static class SetWithToString<T> extends AbstractSet<T> {
|
||||
|
||||
private final Set<T> myDelegate;
|
||||
|
||||
SetWithToString(@NotNull Set<T> delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return myDelegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return myDelegate.contains(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return myDelegate.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return myDelegate.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return myDelegate.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myDelegate.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+120
-34
@@ -15,10 +15,11 @@
|
||||
*/
|
||||
package org.jetbrains.kotlin.idea.codeInsight.gradle
|
||||
|
||||
import com.intellij.compiler.server.BuildManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.Result
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpec
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId
|
||||
import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
|
||||
@@ -28,19 +29,28 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.projectRoots.JavaSdk
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.ui.TestDialog
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.testFramework.IdeaTestUtil
|
||||
import com.intellij.testFramework.RunAll
|
||||
import com.intellij.testFramework.VfsTestUtil
|
||||
import com.intellij.util.ArrayUtilRt
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import junit.framework.TestCase
|
||||
import org.gradle.StartParameter
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.gradle.wrapper.GradleWrapperMain
|
||||
import org.gradle.wrapper.PathAssembler
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker
|
||||
@@ -52,7 +62,9 @@ import org.jetbrains.kotlin.test.RunnerFactoryWithMuteInDatabase
|
||||
import org.jetbrains.plugins.gradle.settings.DistributionType
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSettings
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSystemSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Assume.assumeThat
|
||||
@@ -67,6 +79,8 @@ import java.io.IOException
|
||||
import java.io.StringWriter
|
||||
import java.net.URISyntaxException
|
||||
import java.util.*
|
||||
import java.util.zip.ZipException
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
// part of org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
|
||||
@RunWith(value = JUnitParameterizedWithIdeaConfigurationRunner::class)
|
||||
@@ -75,6 +89,8 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
|
||||
protected var sdkCreationChecker : KotlinSdkCreationChecker? = null
|
||||
|
||||
private val removedSdks: MutableList<Sdk> = SmartList()
|
||||
|
||||
@JvmField
|
||||
@Rule
|
||||
var name = TestName()
|
||||
@@ -112,6 +128,7 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
super.setUp()
|
||||
assumeTrue(isApplicableTest())
|
||||
assumeThat(gradleVersion, versionMatcherRule.matcher)
|
||||
removedSdks.clear()
|
||||
runWrite {
|
||||
val jdkTable = getProjectJdkTableSafe()
|
||||
jdkTable.findJdk(GRADLE_JDK_NAME)?.let {
|
||||
@@ -127,47 +144,77 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
myProjectSettings = GradleProjectSettings().apply {
|
||||
this.isUseQualifiedModuleNames = false
|
||||
}
|
||||
System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, GRADLE_DAEMON_TTL_MS.toString())
|
||||
|
||||
val distribution = WriteAction.computeAndWait<PathAssembler.LocalDistribution, Throwable> { configureWrapper() }
|
||||
|
||||
val allowedRoots = ArrayList<String>()
|
||||
collectAllowedRoots(allowedRoots, distribution)
|
||||
if (!allowedRoots.isEmpty()) {
|
||||
VfsRootAccess.allowRootAccess(myTestFixture.testRootDisposable, *ArrayUtilRt.toStringArray(allowedRoots))
|
||||
}
|
||||
|
||||
GradleSettings.getInstance(myProject).gradleVmOptions =
|
||||
"${jvmHeapArgsByGradleVersion(gradleVersion)} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
|
||||
|
||||
System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, GRADLE_DAEMON_TTL_MS.toString())
|
||||
configureWrapper()
|
||||
sdkCreationChecker = KotlinSdkCreationChecker()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
try {
|
||||
runWrite {
|
||||
val old = getProjectJdkTableSafe().findJdk(GRADLE_JDK_NAME)
|
||||
if (old != null) {
|
||||
SdkConfigurationUtil.removeSdk(old)
|
||||
}
|
||||
}
|
||||
|
||||
Messages.setTestDialog(TestDialog.DEFAULT)
|
||||
FileUtil.delete(BuildManager.getInstance().buildSystemDirectory.toFile())
|
||||
sdkCreationChecker?.removeNewKotlinSdk()
|
||||
} finally {
|
||||
super.tearDown()
|
||||
if (myJdkHome == null) {
|
||||
//super.setUp() wasn't called
|
||||
return
|
||||
}
|
||||
RunAll(
|
||||
ThrowableRunnable {
|
||||
runWrite {
|
||||
Arrays.stream(ProjectJdkTable.getInstance().allJdks).forEach { jdk: Sdk ->
|
||||
ProjectJdkTable.getInstance().removeJdk(jdk)
|
||||
}
|
||||
for (sdk in removedSdks) {
|
||||
SdkConfigurationUtil.addSdk(sdk)
|
||||
}
|
||||
removedSdks.clear()
|
||||
}
|
||||
},
|
||||
ThrowableRunnable {
|
||||
Messages.setTestDialog(TestDialog.DEFAULT)
|
||||
deleteBuildSystemDirectory()
|
||||
// was FileUtil.delete(BuildManager.getInstance().buildSystemDirectory.toFile())
|
||||
sdkCreationChecker?.removeNewKotlinSdk()
|
||||
},
|
||||
ThrowableRunnable {
|
||||
super.tearDown()
|
||||
}
|
||||
).run()
|
||||
}
|
||||
|
||||
override fun collectAllowedRoots(roots: MutableList<String>) {
|
||||
super.collectAllowedRoots(roots)
|
||||
roots.add(myJdkHome)
|
||||
roots.addAll(ExternalSystemTestCase.collectRootsInside(myJdkHome))
|
||||
roots.add(PathManager.getConfigPath())
|
||||
}
|
||||
|
||||
protected open fun collectAllowedRoots(
|
||||
roots: MutableList<String>,
|
||||
distribution: PathAssembler.LocalDistribution?
|
||||
) {
|
||||
//Note: could be required to use:
|
||||
//Environment.getEnvVariable("JAVA_HOME")
|
||||
roots.add(myJdkHome)
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return if (name.methodName == null) super.getName() else FileUtil.sanitizeFileName(name.methodName)
|
||||
}
|
||||
|
||||
override fun getExternalSystemConfigFileName(): String = "build.gradle"
|
||||
|
||||
protected fun importProjectUsingSingeModulePerGradleProject() {
|
||||
myProjectSettings.isResolveModulePerSourceSet = false
|
||||
importProject()
|
||||
@Throws(IOException::class)
|
||||
protected open fun importProjectUsingSingeModulePerGradleProject(config: String? = null) {
|
||||
currentExternalProjectSettings.isResolveModulePerSourceSet = false
|
||||
importProject(config)
|
||||
}
|
||||
|
||||
override fun importProject() {
|
||||
@@ -185,28 +232,43 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
super.importProject()
|
||||
}
|
||||
|
||||
override fun importProject(@NonNls @Language("Groovy") config: String) {
|
||||
super.importProject(
|
||||
"""
|
||||
allprojects {
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://maven.labs.intellij.net/repo1'
|
||||
}
|
||||
}
|
||||
}
|
||||
@Throws(IOException::class)
|
||||
override fun importProject(@NonNls @Language("Groovy") config: String?) {
|
||||
var config = config
|
||||
config = injectRepo(config)
|
||||
super.importProject(config)
|
||||
}
|
||||
|
||||
$config
|
||||
""".trimIndent()
|
||||
)
|
||||
protected open fun injectRepo(@NonNls @Language("Groovy") config: String?): String {
|
||||
var config = config ?: ""
|
||||
config = """allprojects {
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://repo.labs.intellij.net/repo1'
|
||||
}
|
||||
}}
|
||||
$config"""
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
override fun createImportSpec(): ImportSpec? {
|
||||
val importSpecBuilder = ImportSpecBuilder(super.createImportSpec())
|
||||
importSpecBuilder.withArguments("--stacktrace")
|
||||
return importSpecBuilder.build()
|
||||
}
|
||||
|
||||
override fun getCurrentExternalProjectSettings(): GradleProjectSettings = myProjectSettings
|
||||
|
||||
override fun getExternalSystemId(): ProjectSystemId = GradleConstants.SYSTEM_ID
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected open fun createSettingsFile(@NonNls @Language("Groovy") content: String?): VirtualFile? {
|
||||
return createProjectSubFile("settings.gradle", content)
|
||||
}
|
||||
|
||||
@Throws(IOException::class, URISyntaxException::class)
|
||||
private fun configureWrapper() {
|
||||
private fun configureWrapper(): PathAssembler.LocalDistribution {
|
||||
val distributionUri = AbstractModelBuilderTest.DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion))
|
||||
|
||||
myProjectSettings.distributionType = DistributionType.DEFAULT_WRAPPED
|
||||
@@ -228,6 +290,27 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
properties.store(writer, null)
|
||||
|
||||
createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString())
|
||||
|
||||
val wrapperConfiguration =
|
||||
GradleUtil.getWrapperConfiguration(projectPath)
|
||||
val localDistribution = PathAssembler(
|
||||
StartParameter.DEFAULT_GRADLE_USER_HOME
|
||||
).getDistribution(wrapperConfiguration)
|
||||
|
||||
val zip = localDistribution.zipFile
|
||||
try {
|
||||
if (zip.exists()) {
|
||||
val zipFile = ZipFile(zip)
|
||||
zipFile.close()
|
||||
}
|
||||
} catch (e: ZipException) {
|
||||
e.printStackTrace()
|
||||
println("Corrupted file will be removed: " + zip.path)
|
||||
FileUtil.delete(zip)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return localDistribution
|
||||
}
|
||||
|
||||
protected open fun testDataDirName(): String = ""
|
||||
@@ -290,7 +373,6 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun runWrite(f: () -> Unit) {
|
||||
object : WriteAction<Any>() {
|
||||
override fun run(result: Result<Any>) {
|
||||
@@ -299,6 +381,10 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
|
||||
}.execute()
|
||||
}
|
||||
|
||||
protected open fun enableGradleDebugWithSuspend() {
|
||||
GradleSystemSettings.getInstance().gradleVmOptions = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val GRADLE_JDK_NAME = "Gradle JDK"
|
||||
private const val GRADLE_DAEMON_TTL_MS = 10000
|
||||
|
||||
+2
-3
@@ -13,10 +13,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TestImportSpecBuilder extends ImportSpecBuilder {
|
||||
public TestImportSpecBuilder(
|
||||
@NotNull Project project,
|
||||
@NotNull ProjectSystemId id
|
||||
@NotNull ImportSpec importSpec
|
||||
) {
|
||||
super(project, id);
|
||||
super(importSpec);
|
||||
}
|
||||
|
||||
public ImportSpecBuilder setCreateEmptyContentRoots(boolean value) {
|
||||
|
||||
Reference in New Issue
Block a user