mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 22:09:38 +07:00
543 lines
22 KiB
Java
543 lines
22 KiB
Java
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
|
package com.intellij.roots;
|
|
|
|
import com.intellij.ProjectTopics;
|
|
import com.intellij.configurationStore.StateStorageManagerKt;
|
|
import com.intellij.openapi.application.ApplicationManager;
|
|
import com.intellij.openapi.application.ex.PathManagerEx;
|
|
import com.intellij.openapi.module.Module;
|
|
import com.intellij.openapi.module.ModuleManager;
|
|
import com.intellij.openapi.project.Project;
|
|
import com.intellij.openapi.projectRoots.JavaSdk;
|
|
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
|
import com.intellij.openapi.projectRoots.Sdk;
|
|
import com.intellij.openapi.projectRoots.SdkModificator;
|
|
import com.intellij.openapi.roots.*;
|
|
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
|
|
import com.intellij.openapi.roots.libraries.Library;
|
|
import com.intellij.openapi.roots.libraries.LibraryTable;
|
|
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
|
import com.intellij.openapi.util.io.FileUtil;
|
|
import com.intellij.openapi.vcs.VcsConfiguration;
|
|
import com.intellij.openapi.vcs.changes.VcsIgnoreManager;
|
|
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
import com.intellij.openapi.vfs.VirtualFile;
|
|
import com.intellij.openapi.vfs.VirtualFileManager;
|
|
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
|
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
|
|
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
|
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
|
|
import com.intellij.testFramework.IdeaTestUtil;
|
|
import com.intellij.testFramework.JavaModuleTestCase;
|
|
import com.intellij.testFramework.PlatformTestUtil;
|
|
import com.intellij.testFramework.VfsTestUtil;
|
|
import com.intellij.util.TimeoutUtil;
|
|
import com.intellij.util.containers.ContainerUtil;
|
|
import com.intellij.util.messages.MessageBusConnection;
|
|
import com.intellij.util.ui.UIUtil;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.jps.model.java.JavaResourceRootType;
|
|
|
|
import java.io.File;
|
|
import java.nio.file.Paths;
|
|
import java.util.List;
|
|
|
|
public class RootsChangedTest extends JavaModuleTestCase {
|
|
private MyModuleRootListener myModuleRootListener;
|
|
|
|
@Override
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
|
|
getOrCreateProjectBaseDir();
|
|
MessageBusConnection connection = myProject.getMessageBus().connect(getTestRootDisposable());
|
|
myModuleRootListener = new MyModuleRootListener(myProject);
|
|
connection.subscribe(ProjectTopics.PROJECT_ROOTS, myModuleRootListener);
|
|
}
|
|
|
|
@Override
|
|
protected void tearDown() throws Exception {
|
|
myModuleRootListener = null;
|
|
super.tearDown();
|
|
}
|
|
|
|
public void testEventsAfterFileModifications() {
|
|
File root = new File(FileUtil.getTempDirectory());
|
|
|
|
File dir1 = new File(root, "dir1");
|
|
assertTrue(dir1.mkdirs());
|
|
VirtualFile vDir1 = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir1);
|
|
assertNotNull(vDir1);
|
|
|
|
Module moduleA = createModule("a.iml");
|
|
myModuleRootListener.reset();
|
|
|
|
ModuleRootModificationUtil.addContentRoot(moduleA, vDir1.getPath());
|
|
UIUtil.dispatchAllInvocationEvents();
|
|
|
|
assertEventsCount(1);
|
|
assertSameElements(ModuleRootManager.getInstance(moduleA).getContentRoots(), vDir1);
|
|
|
|
VfsTestUtil.deleteFile(vDir1);
|
|
assertEventsCount(1);
|
|
assertEmpty(ModuleRootManager.getInstance(moduleA).getContentRoots());
|
|
|
|
File dir2 = new File(root, "dir2");
|
|
assertTrue(dir2.mkdirs());
|
|
VirtualFile vDir2 = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir2);
|
|
assertNotNull(vDir2);
|
|
|
|
rename(vDir2, "dir1");
|
|
assertEventsCount(1);
|
|
assertSameElements(ModuleRootManager.getInstance(moduleA).getContentRoots(), vDir2);
|
|
|
|
// when the existing root is renamed, it remains a root
|
|
rename(vDir2, "dir2");
|
|
assertNoEvents();
|
|
assertSameElements(ModuleRootManager.getInstance(moduleA).getContentRoots(), vDir2);
|
|
|
|
// and event if it is moved, it's still a root
|
|
File subdir = new File(root, "subdir");
|
|
assertTrue(subdir.mkdirs());
|
|
VirtualFile vSubdir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(subdir);
|
|
assertNotNull(vSubdir);
|
|
|
|
move(vDir2, vSubdir);
|
|
assertEventsCount(1);
|
|
assertSameElements(ModuleRootManager.getInstance(moduleA).getContentRoots(), vDir2);
|
|
}
|
|
|
|
public void testProjectLibraryChangeEvent() {
|
|
final LibraryTable projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
|
|
verifyLibraryTableEditing(projectLibraryTable);
|
|
}
|
|
|
|
public void testGlobalLibraryChangeEvent() {
|
|
final LibraryTable globalLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable();
|
|
verifyLibraryTableEditing(globalLibraryTable);
|
|
}
|
|
|
|
public void testProjectLibraryEventsInUncommittedModel() {
|
|
final LibraryTable projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
|
|
verifyLibraryTableEditingInUncommittedModel(projectLibraryTable);
|
|
}
|
|
|
|
public void testGlobalLibraryEventsInUncommittedModel() {
|
|
final LibraryTable globalLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable();
|
|
verifyLibraryTableEditingInUncommittedModel(globalLibraryTable);
|
|
}
|
|
|
|
public void testEditLibraryForModuleLoadFromXml() {
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
Module a = loadModule(Paths.get(PathManagerEx.getHomePath(getClass())).resolve("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml"));
|
|
assertEventsCount(1);
|
|
|
|
final Sdk jdk = ProjectJdkTable.getInstance().createSdk("new-jdk", JavaSdk.getInstance());
|
|
ProjectJdkTable.getInstance().addJdk(jdk, getTestRootDisposable());
|
|
assertNoEvents();
|
|
|
|
ModuleRootModificationUtil.setModuleSdk(a, jdk);
|
|
assertEventsCount(1);
|
|
|
|
SdkModificator sdkModificator = jdk.getSdkModificator();
|
|
sdkModificator.addRoot(getTempDir().createVirtualDir(), OrderRootType.CLASSES);
|
|
sdkModificator.commitChanges();
|
|
});
|
|
|
|
assertEventsCount(1);
|
|
}
|
|
|
|
public void testModuleJdkEditing() {
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
final Module moduleA = createModule("a.iml");
|
|
final Module moduleB = createModule("b.iml");
|
|
assertEventsCount(2);
|
|
|
|
final Sdk jdk = ProjectJdkTable.getInstance().createSdk("new-jdk", JavaSdk.getInstance());
|
|
final Sdk unused = ProjectJdkTable.getInstance().createSdk("unused", JavaSdk.getInstance());
|
|
ProjectJdkTable.getInstance().addJdk(jdk, getTestRootDisposable());
|
|
ProjectJdkTable.getInstance().addJdk(unused, getTestRootDisposable());
|
|
assertNoEvents();
|
|
|
|
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
|
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
|
rootModelA.setSdk(jdk);
|
|
rootModelB.setSdk(jdk);
|
|
ModifiableRootModel[] rootModels = {rootModelA, rootModelB};
|
|
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
|
assertEventsCount(1);
|
|
|
|
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
|
sdkModificator.addRoot(getTempDir().createVirtualDir(), OrderRootType.CLASSES);
|
|
sdkModificator.commitChanges();
|
|
assertEventsCount(1);
|
|
|
|
final SdkModificator sdkModificator2 = unused.getSdkModificator();
|
|
sdkModificator2.addRoot(getTempDir().createVirtualDir(), OrderRootType.CLASSES);
|
|
sdkModificator2.commitChanges();
|
|
assertNoEvents();
|
|
});
|
|
}
|
|
|
|
public void testSetupUnknownJdk() {
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
Module module = createModule("a.iml");
|
|
assertEventsCount(1);
|
|
ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
|
|
model.setInvalidSdk("new-jdk", JavaSdk.getInstance().getName());
|
|
model.commit();
|
|
assertEventsCount(1);
|
|
|
|
Sdk jdk = ProjectJdkTable.getInstance().createSdk("new-jdk", JavaSdk.getInstance());
|
|
ProjectJdkTable.getInstance().addJdk(jdk, getTestRootDisposable());
|
|
assertEventsCount(1);
|
|
});
|
|
}
|
|
|
|
public void testInheritedJdkEditing() {
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
final Module moduleA = createModule("a.iml");
|
|
final Module moduleB = createModule("b.iml");
|
|
assertEventsCount(2);
|
|
|
|
final Sdk jdk;
|
|
final Sdk jdkBBB;
|
|
try {
|
|
jdk = (Sdk)IdeaTestUtil.getMockJdk17("AAA").clone();
|
|
ProjectJdkTable.getInstance().addJdk(jdk, getTestRootDisposable());
|
|
assertNoEvents();
|
|
|
|
jdkBBB = (Sdk)IdeaTestUtil.getMockJdk17("BBB").clone();
|
|
}
|
|
catch (CloneNotSupportedException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
ProjectJdkTable.getInstance().addJdk(jdk, getTestRootDisposable());
|
|
assertNoEvents();
|
|
|
|
ProjectRootManager.getInstance(myProject).setProjectSdk(jdkBBB);
|
|
assertNoEvents(true);
|
|
|
|
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
|
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
|
rootModelA.inheritSdk();
|
|
rootModelB.inheritSdk();
|
|
ModifiableRootModel[] rootModels = {rootModelA, rootModelB};
|
|
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
|
assertEventsCount(1);
|
|
|
|
ProjectRootManager.getInstance(myProject).setProjectSdk(jdk);
|
|
assertEventsCount(1);
|
|
|
|
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
|
sdkModificator.addRoot(getTempDir().createVirtualDir(), OrderRootType.CLASSES);
|
|
sdkModificator.commitChanges();
|
|
assertEventsCount(1);
|
|
});
|
|
}
|
|
|
|
private void verifyLibraryTableEditing(final LibraryTable libraryTable) {
|
|
final Module moduleA = createModule("a.iml");
|
|
final Module moduleB = createModule("b.iml");
|
|
assertEventsCount(2);
|
|
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
final Library libraryA = libraryTable.createLibrary("A");
|
|
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
|
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
|
libraryModifiableModel.commit();
|
|
assertNoEvents();
|
|
|
|
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
|
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
|
rootModelA.addLibraryEntry(libraryA);
|
|
rootModelB.addLibraryEntry(libraryA);
|
|
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
|
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
|
ModifiableRootModel[] rootModels = {rootModelA, rootModelB};
|
|
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
|
assertEventsCount(1);
|
|
|
|
Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
|
VirtualFile file = getTempDir().createVirtualDir();
|
|
libraryModifiableModel2.addRoot(file.getUrl(), OrderRootType.CLASSES);
|
|
libraryModifiableModel2.commit();
|
|
assertEventsCount(1);
|
|
|
|
libraryTable.removeLibrary(libraryA);
|
|
assertEventsCount(1);
|
|
|
|
final Library libraryQ = libraryTable.createLibrary("Q");
|
|
assertEventsCount(1);
|
|
|
|
libraryTable.removeLibrary(libraryQ);
|
|
assertEventsCount(1);
|
|
});
|
|
}
|
|
|
|
private void verifyLibraryTableEditingInUncommittedModel(LibraryTable libraryTable) {
|
|
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
final Module moduleA = createModule("a.iml");
|
|
final Module moduleB = createModule("b.iml");
|
|
assertEventsCount(2);
|
|
|
|
final Library libraryA = libraryTable.createLibrary("A");
|
|
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
|
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
|
libraryModifiableModel.commit();
|
|
assertNoEvents();
|
|
|
|
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
|
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
|
rootModelA.addLibraryEntry(libraryA);
|
|
rootModelB.addLibraryEntry(libraryA);
|
|
final Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
|
libraryModifiableModel2.addRoot("file:///b", OrderRootType.CLASSES);
|
|
libraryModifiableModel2.commit();
|
|
assertNoEvents();
|
|
|
|
libraryTable.removeLibrary(libraryA);
|
|
assertNoEvents(true);
|
|
|
|
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
|
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
|
assertNoEvents();
|
|
|
|
final Library libraryQ = libraryTable.createLibrary("Q");
|
|
assertNoEvents(true);
|
|
|
|
ModifiableRootModel[] rootModels = {rootModelA, rootModelB};
|
|
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
|
assertEventsCount(1);
|
|
|
|
libraryTable.removeLibrary(libraryQ);
|
|
assertEventsCount(1);
|
|
});
|
|
}
|
|
|
|
private void assertNoEvents() {
|
|
assertNoEvents(false);
|
|
}
|
|
|
|
private void assertNoEvents(boolean modificationCountMayBeIncremented) {
|
|
assertEventsCountAndIncrementModificationCount(0, false, modificationCountMayBeIncremented);
|
|
}
|
|
|
|
private void assertEventsCount(int count) {
|
|
assertEventsCountAndIncrementModificationCount(count, count != 0, false);
|
|
}
|
|
|
|
private void assertEventsCountAndIncrementModificationCount(int eventsCount, boolean modificationCountMustBeIncremented,
|
|
boolean modificationCountMayBeIncremented) {
|
|
final int beforeCount = myModuleRootListener.beforeCount;
|
|
final int afterCount = myModuleRootListener.afterCount;
|
|
assertEquals("beforeCount = " + beforeCount + ", afterCount = " + afterCount, beforeCount, afterCount);
|
|
assertEquals(eventsCount, beforeCount);
|
|
long currentModificationCount = ProjectRootManager.getInstance(myProject).getModificationCount();
|
|
if (modificationCountMayBeIncremented) {
|
|
assertTrue(currentModificationCount >= myModuleRootListener.modificationCount);
|
|
}
|
|
else if (modificationCountMustBeIncremented) {
|
|
assertTrue(currentModificationCount > myModuleRootListener.modificationCount);
|
|
}
|
|
else {
|
|
assertEquals(myModuleRootListener.modificationCount, currentModificationCount);
|
|
}
|
|
myModuleRootListener.reset();
|
|
}
|
|
|
|
private static class MyModuleRootListener implements ModuleRootListener {
|
|
private final Project myProject;
|
|
private int beforeCount;
|
|
private int afterCount;
|
|
private long modificationCount;
|
|
|
|
MyModuleRootListener(Project project) {
|
|
myProject = project;
|
|
}
|
|
|
|
@Override
|
|
public void beforeRootsChange(@NotNull ModuleRootEvent event) {
|
|
beforeCount++;
|
|
}
|
|
|
|
@Override
|
|
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
|
afterCount++;
|
|
}
|
|
|
|
private void reset() {
|
|
beforeCount = 0;
|
|
afterCount = 0;
|
|
modificationCount = ProjectRootManager.getInstance(myProject).getModificationCount();
|
|
}
|
|
}
|
|
|
|
public void testRootsChangedPerformanceInPresenceOfManyVirtualFilePointers() {
|
|
VirtualFile temp = getTempDir().createVirtualDir();
|
|
String dirName = "xxx";
|
|
VirtualFilePointerManager virtualFilePointerManager = VirtualFilePointerManager.getInstance();
|
|
for (int i = 0; i < 10_000; i++) {
|
|
virtualFilePointerManager.create(temp.getUrl() + "/" + dirName + "/" + i, getTestRootDisposable(), null);
|
|
}
|
|
|
|
VirtualFile xxx = createChildDirectory(temp, dirName);
|
|
|
|
PlatformTestUtil.startPerformanceTest("time wasted in ProjectRootManagerComponent.before/afterValidityChanged()", 10000, ()->{
|
|
for (int i = 0; i < 100; i++) {
|
|
rename(xxx, "yyy");
|
|
rename(xxx, dirName);
|
|
}
|
|
}).assertTiming();
|
|
}
|
|
|
|
// create ".idea" - based project because it's 1) needed for testShelveChangesMustNotLeadToRootsChangedEvent and 2) is more common
|
|
@Override
|
|
protected boolean isCreateDirectoryBasedProject() {
|
|
return true;
|
|
}
|
|
|
|
public void testShelveChangesMustNotLeadToRootsChangedEvent() {
|
|
// create .idea
|
|
StateStorageManagerKt.saveComponentManager(getProject());
|
|
VirtualFile shelf = createChildDirectory(getProject().getProjectFile().getParent(), "shelf");
|
|
VcsIgnoreManager vcsIgnoreManager = VcsIgnoreManager.getInstance(myProject);
|
|
|
|
myModuleRootListener.reset();
|
|
|
|
VirtualFile xxx = createChildData(shelf, "shelf1.dat");
|
|
assertTrue(vcsIgnoreManager.isPotentiallyIgnoredFile(xxx));
|
|
|
|
assertEquals(myModuleRootListener.modificationCount, ProjectRootManager.getInstance(myProject).getModificationCount());
|
|
|
|
VirtualFile newShelf = createChildDirectory(getOrCreateProjectBaseDir().getParent(), "newShelf");
|
|
VcsConfiguration vcs = VcsConfiguration.getInstance(myProject);
|
|
vcs.USE_CUSTOM_SHELF_PATH = true;
|
|
vcs.CUSTOM_SHELF_PATH = newShelf.getPath();
|
|
myModuleRootListener.reset();
|
|
|
|
VirtualFile xxx2 = createChildData(newShelf, "shelf1.dat");
|
|
assertTrue(vcsIgnoreManager.isPotentiallyIgnoredFile(xxx2));
|
|
}
|
|
|
|
public void testCreationDeletionOfRootDirectoriesMustLeadToRootsChanged() {
|
|
File root = new File(FileUtil.getTempDirectory());
|
|
|
|
File dir1 = new File(root, "dir1");
|
|
assertTrue(dir1.mkdirs());
|
|
VirtualFile contentRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir1);
|
|
assertNotNull(contentRoot);
|
|
|
|
Module moduleA = createModule("a.iml");
|
|
ModuleRootModificationUtil.addContentRoot(moduleA, contentRoot.getPath());
|
|
String excludedUrl = contentRoot.getUrl() + "/excluded";
|
|
String sourceUrl = contentRoot.getUrl() + "/src";
|
|
String testSourceUrl = contentRoot.getUrl() + "/testSrc";
|
|
String outputUrl = contentRoot.getUrl() + "/out";
|
|
String testOutputUrl = contentRoot.getUrl() + "/testOut";
|
|
String resourceUrl = contentRoot.getUrl() + "/res";
|
|
String testResourceUrl = contentRoot.getUrl() + "/testRes";
|
|
|
|
ModuleRootModificationUtil.updateModel(moduleA, model -> {
|
|
ContentEntry entry = ContainerUtil.find(model.getContentEntries(), e-> contentRoot.equals(e.getFile()));
|
|
|
|
entry.addExcludeFolder(excludedUrl);
|
|
entry.addSourceFolder(sourceUrl, false);
|
|
entry.addSourceFolder(testSourceUrl, true);
|
|
entry.addSourceFolder(resourceUrl, JavaResourceRootType.RESOURCE);
|
|
entry.addSourceFolder(testResourceUrl, JavaResourceRootType.TEST_RESOURCE);
|
|
|
|
model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPath(outputUrl);
|
|
model.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPathForTests(testOutputUrl);
|
|
});
|
|
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, excludedUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, sourceUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, testSourceUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, resourceUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, testResourceUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, outputUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, testOutputUrl, 1);
|
|
checkRootChangedOnDirCreationDeletion(contentRoot, "xxx", 0);
|
|
}
|
|
|
|
private void checkRootChangedOnDirCreationDeletion(VirtualFile contentRoot, String dirUrl, int mustGenerateEvents) {
|
|
myModuleRootListener.reset();
|
|
UIUtil.dispatchAllInvocationEvents();
|
|
|
|
VirtualFile dir = createChildDirectory(contentRoot, new File(dirUrl).getName());
|
|
assertEventsCount(mustGenerateEvents);
|
|
|
|
myModuleRootListener.reset();
|
|
UIUtil.dispatchAllInvocationEvents();
|
|
delete(dir);
|
|
assertEventsCount(mustGenerateEvents);
|
|
}
|
|
|
|
public void testEmptyDirectoryCreatedAndSomeRogueFileListenerImmediatelyCallsGetChildrenPreventingFurtherCreationEventsForFilesThatHappenedToBeAlreadyThereByThatMoment() {
|
|
File ioRoot = new File(FileUtil.getTempDirectory());
|
|
|
|
VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioRoot);
|
|
vRoot.getChildren();
|
|
|
|
Module module = createModule("a.iml");
|
|
ModuleRootModificationUtil.addContentRoot(module, vRoot.getPath());
|
|
ModuleRootModificationUtil.updateModel(module, model -> model.getContentEntries()[0].addExcludeFolder(vRoot.getUrl() + "/parent/excluded"));
|
|
|
|
MessageBusConnection connect = ApplicationManager.getApplication().getMessageBus().connect(getTestRootDisposable());
|
|
BulkFileListener rogueListenerWhichStupidlyGetChildrenRightAway = new BulkFileListener() {
|
|
@Override
|
|
public void after(@NotNull List<? extends VFileEvent> events) {
|
|
for (VFileEvent event : events) {
|
|
VirtualFile file = event.getFile();
|
|
if (event instanceof VFileCreateEvent && file != null) {
|
|
file.getChildren();// aaaaaaaaah!
|
|
}
|
|
}
|
|
}
|
|
};
|
|
connect.subscribe(VirtualFileManager.VFS_CHANGES, rogueListenerWhichStupidlyGetChildrenRightAway);
|
|
|
|
myModuleRootListener.reset();
|
|
|
|
File iParent = new File(ioRoot, "parent");
|
|
assertTrue(iParent.mkdirs());
|
|
vRoot.refresh(true, true);
|
|
|
|
TimeoutUtil.sleep(1000); // hope that now async refresh has found "parent" and is waiting for EDT to fire events
|
|
|
|
File ioExcluded = new File(iParent, "excluded");
|
|
assertTrue(ioExcluded.mkdirs());
|
|
UIUtil.dispatchAllInvocationEvents(); // now events are fired
|
|
|
|
assertNotNull(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioExcluded));
|
|
|
|
assertEventsCount(1);
|
|
}
|
|
|
|
public void testChangesInsideCompilerOutputDirectoryMustNotLeadToRootsChange() {
|
|
File temp = new File(FileUtil.getTempDirectory());
|
|
VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(temp);
|
|
VirtualFile content = VfsTestUtil.createDir(root, "content");
|
|
|
|
Module module = createModule("a.iml");
|
|
ModuleRootModificationUtil.addContentRoot(module, content.getPath());
|
|
VirtualFile out = VfsTestUtil.createDir(root, "out");
|
|
|
|
ModuleRootModificationUtil.updateModel(module, model -> {
|
|
CompilerModuleExtension moduleExtension = model.getModuleExtension(CompilerModuleExtension.class);
|
|
moduleExtension.inheritCompilerOutputPath(false);
|
|
moduleExtension.setCompilerOutputPath(out);
|
|
moduleExtension.setCompilerOutputPathForTests(out);
|
|
});
|
|
|
|
myModuleRootListener.reset();
|
|
VirtualFile f1 = VfsTestUtil.createFile(out, "x/x.txt");
|
|
VirtualFile f2 = VfsTestUtil.createFile(out, "x/x.class");
|
|
assertEventsCount(0);
|
|
VfsTestUtil.deleteFile(f1);
|
|
VfsTestUtil.deleteFile(f2);
|
|
assertEventsCount(0);
|
|
}
|
|
}
|