added test for DirectoryIndex.getOrderEntries for modules imported from Maven

This commit is contained in:
Jan Voung
2015-11-27 13:54:59 +03:00
committed by nik
parent 0f810dc4d6
commit f6e0d010d9
@@ -22,21 +22,17 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope;
import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.DirectoryIndex;
import com.intellij.openapi.roots.impl.LibraryScopeCache;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.PathsList;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.MavenImportingTestCase;
import org.jetbrains.idea.maven.importing.ArtifactsDownloadingTestCase;
@@ -1041,6 +1037,298 @@ public class MavenClasspathsAndSearchScopesTest extends MavenImportingTestCase {
getRepositoryPath() + "/junit/junit/4.0/junit-4.0.jar");
}
public void testDirIndexOrderEntriesTransitiveCompileScope() throws IOException {
List<Module> modules = setupDirIndexTestModulesWithScope("compile");
checkDirIndexTestModulesWithCompileOrRuntimeScope(modules);
}
public void testDirIndexOrderEntriesTransitiveRuntimeScope() throws IOException {
List<Module> modules = setupDirIndexTestModulesWithScope("runtime");
checkDirIndexTestModulesWithCompileOrRuntimeScope(modules);
}
// Creates a Maven dependency graph for testing DirectoryIndex#getOrderEntries.
private List<Module> setupDirIndexTestModulesWithScope(String scope) throws IOException {
createRepositoryFile("jmock/jmock/1.0/jmock-1.0.jar");
// Dependency graph:
// m4
// |
// v
// m1 -> m2 -> m3-|
// |----------> jmock
// v
// m5 -> m6
// Dependencies are set up to be under the given scope, except that jmock is under a test scope,
// and the m5 -> m6 dep is always under a compile scope.
VirtualFile m1 = createModulePom("m1", "<groupId>test</groupId>" +
"<artifactId>m1</artifactId>" +
"<version>1</version>" +
"<dependencies>" +
" <dependency>" +
" <groupId>test</groupId>" +
" <artifactId>m2</artifactId>" +
" <version>1</version>" +
" <scope>" + scope + "</scope>" +
" </dependency>" +
"</dependencies>");
VirtualFile m2 = createModulePom("m2", "<groupId>test</groupId>" +
"<artifactId>m2</artifactId>" +
"<version>1</version>" +
"<dependencies>" +
" <dependency>" +
" <groupId>test</groupId>" +
" <artifactId>m3</artifactId>" +
" <version>1</version>" +
" <scope>" + scope + "</scope>" +
" </dependency>" +
" <dependency>" +
" <groupId>jmock</groupId>" +
" <artifactId>jmock</artifactId>" +
" <version>1.0</version>" +
" <scope>test</scope>" +
" </dependency>" +
" <dependency>" +
" <groupId>test</groupId>" +
" <artifactId>m5</artifactId>" +
" <version>1</version>" +
" <scope>" + scope + "</scope>" +
" </dependency>" +
"</dependencies>");
VirtualFile m3 = createModulePom("m3", "<groupId>test</groupId>" +
"<artifactId>m3</artifactId>" +
"<version>1</version>" +
"<dependencies>" +
" <dependency>" +
" <groupId>jmock</groupId>" +
" <artifactId>jmock</artifactId>" +
" <version>1.0</version>" +
" <scope>test</scope>" +
" </dependency>" +
"</dependencies>");
VirtualFile m4 = createModulePom("m4", "<groupId>test</groupId>" +
"<artifactId>m4</artifactId>" +
"<version>1</version>" +
"<dependencies>" +
" <dependency>" +
" <groupId>test</groupId>" +
" <artifactId>m3</artifactId>" +
" <version>1</version>" +
" <scope>" + scope + "</scope>" +
" </dependency>" +
"</dependencies>");
// The default setupInWriteAction only creates directories up to m4.
// Create directories for m5 and m6 which we will use for this test.
new WriteCommandAction.Simple(myProject) {
@Override
protected void run() throws Throwable {
createProjectSubDirs("m5/src/main/java",
"m5/src/test/java",
"m6/src/main/java",
"m6/src/test/java");
}
}.execute();
VirtualFile m5 = createModulePom("m5", "<groupId>test</groupId>" +
"<artifactId>m5</artifactId>" +
"<version>1</version>" +
"<dependencies>" +
" <dependency>" +
" <groupId>test</groupId>" +
" <artifactId>m6</artifactId>" +
" <version>1</version>" +
" <scope>compile</scope>" +
" </dependency>" +
"</dependencies>");
VirtualFile m6 = createModulePom("m6", "<groupId>test</groupId>" +
"<artifactId>m6</artifactId>" +
"<version>1</version>");
importProjects(m1, m2, m3, m4, m5, m6);
assertModules("m1", "m2", "m3", "m4", "m5", "m6");
createOutputDirectories();
return Arrays.asList(getModule("m1"), getModule("m2"), getModule("m3"), getModule("m4"),
getModule("m5"), getModule("m6"));
}
// Checks that the DirectoryIndex#getOrderEntries() returns the expected values
// for the dependency graph set up by setupDirIndexTestModulesWithScope().
// The result is the same for "compile" and "runtime" scopes.
private void checkDirIndexTestModulesWithCompileOrRuntimeScope(List<Module> modules) {
assertEquals(6, modules.size());
DirectoryIndex index = DirectoryIndex.getInstance(myProject);
VirtualFile m3JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m3/src/main/java"), true);
assertNotNull(m3JavaDir);
// Should be: m1 -> m3, m2 -> m3, m3 -> source, and m4 -> m3
List<OrderEntry> orderEntries = index.getOrderEntries(index.getInfoForFile(m3JavaDir));
assertEquals(4, orderEntries.size());
List<Module> ownerModules = orderEntriesToOwnerModules(orderEntries);
List<Module> depModules = orderEntriesToDepModules(orderEntries);
assertOrderedElementsAreEqual(ownerModules,
Arrays.asList(modules.get(0), modules.get(1), modules.get(2), modules.get(3)));
assertOrderedElementsAreEqual(depModules,
Arrays.asList(modules.get(2), modules.get(2), null, modules.get(2)));
// m3 -> source
OrderEntry m3E2 = orderEntries.get(2);
assertInstanceOf(m3E2, ModuleSourceOrderEntry.class);
VirtualFile m6javaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m6/src/main/java"), true);
assertNotNull(m6javaDir);
// Should be m1 -> m6, m2 -> m6, m5 -> m6, m6 -> source
List<OrderEntry> m6OrderEntries = index.getOrderEntries(index.getInfoForFile(m6javaDir));
assertEquals(4, m6OrderEntries.size());
List<Module> m6OwnerModules = orderEntriesToOwnerModules(m6OrderEntries);
List<Module> m6DepModules = orderEntriesToDepModules(m6OrderEntries);
assertOrderedElementsAreEqual(m6OwnerModules,
Arrays.asList(modules.get(0), modules.get(1), modules.get(4), modules.get(5)));
assertOrderedElementsAreEqual(m6DepModules,
Arrays.asList(modules.get(5), modules.get(5), modules.get(5), null));
// m6 -> source
OrderEntry m6E3 = m6OrderEntries.get(3);
assertInstanceOf(m6E3, ModuleSourceOrderEntry.class);
VirtualFile jmockDir = VfsUtil.findFileByIoFile(new File(getRepositoryPath(), "jmock/jmock/1.0/jmock-1.0.jar"), true);
assertNotNull(jmockDir);
VirtualFile jmockJar = JarFileSystem.getInstance().getJarRootForLocalFile(jmockDir);
assertNotNull(jmockJar);
// m2 -> jmock, m3 -> jmock
List<OrderEntry> jmockOrderEntries = index.getOrderEntries(index.getInfoForFile(jmockJar));
assertEquals(2, jmockOrderEntries.size());
OrderEntry jmockE0 = jmockOrderEntries.get(0);
assertEquals(modules.get(1), jmockE0.getOwnerModule());
assertInstanceOf(jmockE0, LibraryOrderEntry.class);
OrderEntry jmockE1 = jmockOrderEntries.get(1);
assertEquals(modules.get(2), jmockE1.getOwnerModule());
assertInstanceOf(jmockE1, LibraryOrderEntry.class);
}
public void testDirIndexOrderEntriesTransitiveTestScope() throws IOException {
// This test is a bit different from the above tests of compile or runtime scope,
// because test scope does not propagate transitive dependencies.
List<Module> modules = setupDirIndexTestModulesWithScope("test");
assertEquals(6, modules.size());
DirectoryIndex index = DirectoryIndex.getInstance(myProject);
VirtualFile m3JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m3/src/main/java"), true);
assertNotNull(m3JavaDir);
// Should be no transitive deps: m2 -> m3, m3 -> source, and m4 -> m3
List<OrderEntry> orderEntries = index.getOrderEntries(index.getInfoForFile(m3JavaDir));
assertEquals(3, orderEntries.size());
List<Module> ownerModules = orderEntriesToOwnerModules(orderEntries);
List<Module> depModules = orderEntriesToDepModules(orderEntries);
assertOrderedElementsAreEqual(ownerModules,
Arrays.asList(modules.get(1), modules.get(2), modules.get(3)));
assertOrderedElementsAreEqual(depModules,
Arrays.asList(modules.get(2), null, modules.get(2)));
// m3 -> source
OrderEntry m3E1 = orderEntries.get(1);
assertInstanceOf(m3E1, ModuleSourceOrderEntry.class);
VirtualFile m6javaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m6/src/main/java"), true);
assertNotNull(m6javaDir);
// Still has some transitive deps because m5 -> m6 is hardcoded to be compile scope
// m2 -> m6, m5 -> m6, m6 -> source
List<OrderEntry> m6OrderEntries = index.getOrderEntries(index.getInfoForFile(m6javaDir));
assertEquals(3, m6OrderEntries.size());
List<Module> m6OwnerModules = orderEntriesToOwnerModules(m6OrderEntries);
List<Module> m6DepModules = orderEntriesToDepModules(m6OrderEntries);
assertOrderedElementsAreEqual(m6OwnerModules,
Arrays.asList(modules.get(1), modules.get(4), modules.get(5)));
assertOrderedElementsAreEqual(m6DepModules,
Arrays.asList(modules.get(5), modules.get(5), null));
// m6 -> source
OrderEntry m6E2 = m6OrderEntries.get(2);
assertInstanceOf(m6E2, ModuleSourceOrderEntry.class);
VirtualFile jmockDir = VfsUtil.findFileByIoFile(new File(getRepositoryPath(), "jmock/jmock/1.0/jmock-1.0.jar"), true);
assertNotNull(jmockDir);
VirtualFile jmockJar = JarFileSystem.getInstance().getJarRootForLocalFile(jmockDir);
assertNotNull(jmockJar);
// m2 -> jmock, m3 -> jmock
List<OrderEntry> jmockOrderEntries = index.getOrderEntries(index.getInfoForFile(jmockJar));
assertEquals(2, jmockOrderEntries.size());
OrderEntry jmockE0 = jmockOrderEntries.get(0);
assertEquals(modules.get(1), jmockE0.getOwnerModule());
assertInstanceOf(jmockE0, LibraryOrderEntry.class);
OrderEntry jmockE1 = jmockOrderEntries.get(1);
assertEquals(modules.get(2), jmockE1.getOwnerModule());
assertInstanceOf(jmockE1, LibraryOrderEntry.class);
}
public void testDirIndexOrderEntriesStartingFromRegularModule() throws IOException {
final List<Module> modules = setupDirIndexTestModulesWithScope("compile");
assertEquals(6, modules.size());
final Module nonMavenM1 = createModule("nonMavenM1");
final Module nonMavenM2 = createModule("nonMavenM2");
new WriteCommandAction.Simple(myProject) {
@Override
protected void run() throws Throwable {
ModuleRootModificationUtil.addDependency(nonMavenM1, nonMavenM2, DependencyScope.COMPILE, true);
ModuleRootModificationUtil.addDependency(nonMavenM2, modules.get(0), DependencyScope.COMPILE, true);
createProjectSubDirs("nonMavenM1/src/main/java", "nonMavenM1/src/test/java",
"nonMavenM2/src/main/java", "nonMavenM2/src/test/java");
VirtualFile nonMavenM1JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "nonMavenM1/src/main/java"), true);
assertNotNull(nonMavenM1JavaDir);
PsiTestUtil.addSourceContentToRoots(nonMavenM1, nonMavenM1JavaDir);
VirtualFile nonMavenM2JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "nonMavenM2/src/main/java"), true);
assertNotNull(nonMavenM2JavaDir);
PsiTestUtil.addSourceContentToRoots(nonMavenM2, nonMavenM2JavaDir);
}
}.execute().throwException();
assertModuleModuleDeps("nonMavenM1", "nonMavenM2");
assertModuleModuleDeps("nonMavenM2", "m1");
assertModuleModuleDeps("m1", "m2", "m3", "m5", "m6");
DirectoryIndex index = DirectoryIndex.getInstance(myProject);
VirtualFile m3JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m3/src/main/java"), true);
assertNotNull(m3JavaDir);
// Should be: m1 -> m3, m2 -> m3, m3 -> source, and m4 -> m3
// It doesn't trace back to nonMavenM1 and nonMavenM2.
List<OrderEntry> orderEntries = index.getOrderEntries(index.getInfoForFile(m3JavaDir));
List<Module> ownerModules = orderEntriesToOwnerModules(orderEntries);
List<Module> depModules = orderEntriesToDepModules(orderEntries);
assertOrderedElementsAreEqual(ownerModules,
Arrays.asList(modules.get(0), modules.get(1), modules.get(2), modules.get(3)));
assertOrderedElementsAreEqual(depModules,
Arrays.asList(modules.get(2), modules.get(2), null, modules.get(2)));
VirtualFile m6javaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "m6/src/main/java"), true);
assertNotNull(m6javaDir);
// Should be m1 -> m6, m2 -> m6, m5 -> m6, m6 -> source
List<OrderEntry> m6OrderEntries = index.getOrderEntries(index.getInfoForFile(m6javaDir));
List<Module> m6OwnerModules = orderEntriesToOwnerModules(m6OrderEntries);
List<Module> m6DepModules = orderEntriesToDepModules(m6OrderEntries);
assertOrderedElementsAreEqual(m6OwnerModules,
Arrays.asList(modules.get(0), modules.get(1), modules.get(4), modules.get(5)));
assertOrderedElementsAreEqual(m6DepModules,
Arrays.asList(modules.get(5), modules.get(5), modules.get(5), null));
VirtualFile nonMavenM2JavaDir = VfsUtil.findFileByIoFile(new File(getProjectPath(), "nonMavenM2/src/main/java"), true);
assertNotNull(nonMavenM2JavaDir);
// Should be nonMavenM1 -> nonMavenM2, nonMavenM2 -> source
List<OrderEntry> nonMavenM2JavaOrderEntries = index.getOrderEntries(index.getInfoForFile(nonMavenM2JavaDir));
List<Module> nonMavenM2OwnerModules = orderEntriesToOwnerModules(nonMavenM2JavaOrderEntries);
List<Module> nonMavenM2DepModules = orderEntriesToDepModules(nonMavenM2JavaOrderEntries);
assertOrderedElementsAreEqual(nonMavenM2OwnerModules, Arrays.asList(nonMavenM1, nonMavenM2));
assertOrderedElementsAreEqual(nonMavenM2DepModules, Arrays.asList(nonMavenM2, null));
}
private static List<Module> orderEntriesToOwnerModules(List<OrderEntry> orderEntries) {
return ContainerUtil.map(orderEntries, new Function<OrderEntry,Module>() {
@Override
public Module fun(OrderEntry orderEntry) { return orderEntry.getOwnerModule(); }
});
}
private static List<Module> orderEntriesToDepModules(List<OrderEntry> orderEntries) {
return ContainerUtil.map(orderEntries, new Function<OrderEntry,Module>() {
@Override
public Module fun(OrderEntry orderEntry) {
return (orderEntry instanceof ModuleOrderEntry) ? ((ModuleOrderEntry)orderEntry).getModule() : null;
}
});
}
private void assertAllProductionClasspath(String moduleName, String... paths) throws Exception {
assertCompileProductionClasspath(moduleName, paths);
assertRuntimeProductionClasspath(moduleName, paths);