mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
create test: automatically create a test root directory if it is specified in module settings but doesn't exist, never suggest generated source roots
This commit is contained in:
@@ -54,18 +54,22 @@ public class JavaProjectRootsUtil {
|
||||
public static List<VirtualFile> getSuitableDestinationSourceRoots(@NotNull Project project) {
|
||||
List<VirtualFile> roots = new ArrayList<VirtualFile>();
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
for (ContentEntry entry : ModuleRootManager.getInstance(module).getContentEntries()) {
|
||||
for (SourceFolder sourceFolder : entry.getSourceFolders(JavaModuleSourceRootTypes.SOURCES)) {
|
||||
if (!isForGeneratedSources(sourceFolder)) {
|
||||
ContainerUtil.addIfNotNull(roots, sourceFolder.getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
collectSuitableDestinationSourceRoots(module, roots);
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
private static boolean isForGeneratedSources(SourceFolder sourceFolder) {
|
||||
public static void collectSuitableDestinationSourceRoots(@NotNull Module module, @NotNull List<VirtualFile> result) {
|
||||
for (ContentEntry entry : ModuleRootManager.getInstance(module).getContentEntries()) {
|
||||
for (SourceFolder sourceFolder : entry.getSourceFolders(JavaModuleSourceRootTypes.SOURCES)) {
|
||||
if (!isForGeneratedSources(sourceFolder)) {
|
||||
ContainerUtil.addIfNotNull(result, sourceFolder.getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isForGeneratedSources(SourceFolder sourceFolder) {
|
||||
JavaSourceRootProperties properties = sourceFolder.getJpsElement().getProperties(JavaModuleSourceRootTypes.SOURCES);
|
||||
JavaResourceRootProperties resourceProperties = sourceFolder.getJpsElement().getProperties(JavaModuleSourceRootTypes.RESOURCES);
|
||||
return properties != null && properties.isForGeneratedSources() || resourceProperties != null && resourceProperties.isForGeneratedSources();
|
||||
|
||||
@@ -22,12 +22,13 @@ import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.SourceFolder;
|
||||
import com.intellij.openapi.roots.TestModuleProperties;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -39,9 +40,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CreateTestAction extends PsiElementBaseIntentionAction {
|
||||
|
||||
@@ -98,6 +100,8 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
|
||||
@Override
|
||||
public void invoke(final @NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
final Module srcModule = ModuleUtilCore.findModuleForPsiElement(element);
|
||||
if (srcModule == null) return;
|
||||
|
||||
final PsiClass srcClass = getContainingClass(element);
|
||||
|
||||
if (srcClass == null) return;
|
||||
@@ -106,19 +110,20 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
|
||||
PsiPackage srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir);
|
||||
|
||||
final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance();
|
||||
final HashSet<VirtualFile> testFolders = new HashSet<VirtualFile>();
|
||||
checkForTestRoots(srcModule, testFolders);
|
||||
if (testFolders.isEmpty() && !propertiesComponent.getBoolean(CREATE_TEST_IN_THE_SAME_ROOT)) {
|
||||
if (Messages.showOkCancelDialog(project, "Create test in the same source root?", "No Test Roots Found", Messages.getQuestionIcon()) !=
|
||||
Messages.OK) {
|
||||
return;
|
||||
Module testModule = suggestModuleForTests(project, srcModule);
|
||||
final List<VirtualFile> testRootUrls = computeTestRoots(testModule);
|
||||
if (testRootUrls.isEmpty() && computeSuitableTestRootUrls(testModule).isEmpty()) {
|
||||
testModule = srcModule;
|
||||
if (!propertiesComponent.getBoolean(CREATE_TEST_IN_THE_SAME_ROOT)) {
|
||||
if (Messages.showOkCancelDialog(project, "Create test in the same source root?", "No Test Roots Found", Messages.getQuestionIcon()) !=
|
||||
Messages.OK) {
|
||||
return;
|
||||
}
|
||||
propertiesComponent.setValue(CREATE_TEST_IN_THE_SAME_ROOT, true);
|
||||
}
|
||||
|
||||
propertiesComponent.setValue(CREATE_TEST_IN_THE_SAME_ROOT, true);
|
||||
}
|
||||
|
||||
final Module targetModule = selectTargetModule(project, srcModule, testFolders);
|
||||
final CreateTestDialog d = createTestDialog(project, targetModule, srcClass, srcPackage);
|
||||
final CreateTestDialog d = createTestDialog(project, testModule, srcClass, srcPackage);
|
||||
if (!d.showAndGet()) {
|
||||
return;
|
||||
}
|
||||
@@ -138,44 +143,59 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
|
||||
}, CodeInsightBundle.message("intention.create.test"), this);
|
||||
}
|
||||
|
||||
private static Module selectTargetModule(Project project, Module srcModule, HashSet<VirtualFile> testFolders) {
|
||||
Module targetModule = null;
|
||||
for (VirtualFile testFolder : testFolders) {
|
||||
Module targetModuleCandidate = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(testFolder);
|
||||
if (targetModuleCandidate == srcModule) {
|
||||
targetModule = srcModule;
|
||||
break;
|
||||
}
|
||||
else if (targetModule == null || TestModuleProperties.getInstance(targetModule).getProductionModule() != srcModule) {
|
||||
targetModule = targetModuleCandidate;
|
||||
@NotNull
|
||||
private static Module suggestModuleForTests(@NotNull Project project, @NotNull Module productionModule) {
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
if (productionModule.equals(TestModuleProperties.getInstance(module).getProductionModule())) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
return targetModule == null ? srcModule : targetModule;
|
||||
return productionModule;
|
||||
}
|
||||
|
||||
protected CreateTestDialog createTestDialog(Project project, Module srcModule, PsiClass srcClass, PsiPackage srcPackage) {
|
||||
return new CreateTestDialog(project, getText(), srcClass, srcPackage, srcModule);
|
||||
}
|
||||
|
||||
protected static void checkForTestRoots(Module srcModule, Set<VirtualFile> testFolders) {
|
||||
List<VirtualFile> sourceRoots = ModuleRootManager.getInstance(srcModule).getSourceRoots(JavaSourceRootType.TEST_SOURCE);
|
||||
for (VirtualFile sourceRoot : sourceRoots) {
|
||||
if (!JavaProjectRootsUtil.isInGeneratedCode(sourceRoot, srcModule.getProject())) {
|
||||
testFolders.add(sourceRoot);
|
||||
}
|
||||
static List<String> computeSuitableTestRootUrls(@NotNull Module module) {
|
||||
return suitableTestSourceFolders(module).map(SourceFolder::getUrl).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
static List<VirtualFile> computeTestRoots(@NotNull Module mainModule) {
|
||||
if (!computeSuitableTestRootUrls(mainModule).isEmpty()) {
|
||||
//create test in the same module, if the test source folder doesn't exist yet it will be created
|
||||
return suitableTestSourceFolders(mainModule)
|
||||
.map(SourceFolder::getFile)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
//create test in the same module
|
||||
if (!testFolders.isEmpty()) return;
|
||||
|
||||
//suggest to choose from all dependencies modules
|
||||
final HashSet<Module> modules = new HashSet<Module>();
|
||||
ModuleUtilCore.collectModulesDependsOn(srcModule, modules);
|
||||
for (Module module : modules) {
|
||||
testFolders.addAll(ModuleRootManager.getInstance(module).getSourceRoots(JavaSourceRootType.TEST_SOURCE));
|
||||
}
|
||||
ModuleUtilCore.collectModulesDependsOn(mainModule, modules);
|
||||
return modules.stream()
|
||||
.flatMap(CreateTestAction::suitableTestSourceFolders)
|
||||
.map(SourceFolder::getFile)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Stream<SourceFolder> suitableTestSourceFolders(@NotNull Module module) {
|
||||
Predicate<SourceFolder> forGeneratedSources = JavaProjectRootsUtil::isForGeneratedSources;
|
||||
return Arrays.stream(ModuleRootManager.getInstance(module).getContentEntries())
|
||||
.flatMap(entry -> entry.getSourceFolders(JavaSourceRootType.TEST_SOURCE).stream())
|
||||
.filter(forGeneratedSources.negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #computeTestRoots(Module)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
protected static void checkForTestRoots(Module srcModule, Set<VirtualFile> testFolders) {
|
||||
testFolders.addAll(computeTestRoots(srcModule));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static PsiClass getContainingClass(PsiElement element) {
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
|
||||
if (psiClass == null) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.CommonBundle;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.ide.util.TreeClassChooser;
|
||||
import com.intellij.ide.util.TreeClassChooserFactory;
|
||||
@@ -38,12 +37,14 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
@@ -59,6 +60,7 @@ import com.intellij.testIntegration.TestFramework;
|
||||
import com.intellij.testIntegration.TestIntegrationUtils;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
@@ -510,14 +512,20 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
|
||||
final VirtualFile selectedRoot = new ReadAction<VirtualFile>() {
|
||||
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
|
||||
final HashSet<VirtualFile> testFolders = new HashSet<VirtualFile>();
|
||||
CreateTestAction.checkForTestRoots(myTargetModule, testFolders);
|
||||
final List<VirtualFile> testFolders = CreateTestAction.computeTestRoots(myTargetModule);
|
||||
List<VirtualFile> roots;
|
||||
if (testFolders.isEmpty()) {
|
||||
roots = ModuleRootManager.getInstance(myTargetModule).getSourceRoots(JavaModuleSourceRootTypes.SOURCES);
|
||||
roots = new ArrayList<>();
|
||||
List<String> urls = CreateTestAction.computeSuitableTestRootUrls(myTargetModule);
|
||||
for (String url : urls) {
|
||||
ContainerUtil.addIfNotNull(roots, VfsUtil.createDirectories(VfsUtilCore.urlToPath(url)));
|
||||
}
|
||||
if (roots.isEmpty()) {
|
||||
JavaProjectRootsUtil.collectSuitableDestinationSourceRoots(myTargetModule, roots);
|
||||
}
|
||||
if (roots.isEmpty()) return;
|
||||
} else {
|
||||
roots = new ArrayList<VirtualFile>(testFolders);
|
||||
roots = new ArrayList<>(testFolders);
|
||||
}
|
||||
|
||||
if (roots.size() == 1) {
|
||||
|
||||
Reference in New Issue
Block a user