mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[project model] add more tests for project model classes
Check editing libraries and library tables, multi-commit for several root models, concurrent modifications. GitOrigin-RevId: 7ae294c1c4a20b0b18dd1f4ee46757e5995a0ce6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b1c54a5a97
commit
3b93d897dd
@@ -9,8 +9,6 @@ import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.OrderEntryUtil;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTableImpl;
|
||||
@@ -19,21 +17,20 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.roots.ModuleRootManagerTestCase;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@@ -66,14 +63,6 @@ public class LibraryTest extends ModuleRootManagerTestCase {
|
||||
assertFalse(LibraryTableImplUtil.isValidLibrary(library));
|
||||
}
|
||||
|
||||
public void testAddRemoveModuleLibrary() {
|
||||
ModuleRootModificationUtil.addModuleLibrary(myModule, getJDomJar().getUrl());
|
||||
Library library = assertOneElement(OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(myModule)));
|
||||
assertTrue(LibraryTableImplUtil.isValidLibrary(library));
|
||||
ModuleRootModificationUtil.updateModel(myModule, model -> model.getModuleLibraryTable().removeLibrary(library));
|
||||
assertFalse(LibraryTableImplUtil.isValidLibrary(library));
|
||||
}
|
||||
|
||||
public void testLibrarySerialization() throws IOException {
|
||||
final long moduleModificationCount = ModuleRootManagerEx.getInstanceEx(myModule).getModificationCountForTests();
|
||||
|
||||
@@ -103,16 +92,6 @@ public class LibraryTest extends ModuleRootManagerTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public void testResolveDependencyToAddedLibrary() {
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
|
||||
model.addInvalidLibrary("jdom", LibraryTablesRegistrar.PROJECT_LEVEL);
|
||||
commit(model);
|
||||
assertEmpty(getLibraries());
|
||||
|
||||
Library library = createLibrary("jdom", getJDomJar(), null);
|
||||
assertSameElements(getLibraries(), library);
|
||||
}
|
||||
|
||||
public void testFindLibraryByNameAfterRename() {
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
|
||||
@@ -187,94 +166,6 @@ public class LibraryTest extends ModuleRootManagerTestCase {
|
||||
assertEquals("a", assertOneElement(getProjectLibraryTable().getLibraries()).getName());
|
||||
}
|
||||
|
||||
public void testNonCommittedLibraryIsDisposed() {
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
LibraryTable.ModifiableModel model = table.getModifiableModel();
|
||||
Library library = model.createLibrary("a");
|
||||
model.removeLibrary(library);
|
||||
commit(model);
|
||||
assertEmpty(table.getLibraries());
|
||||
}
|
||||
|
||||
public void testMergeAddRemoveChanges() {
|
||||
Library a = createLibrary("a", null, null);
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
|
||||
LibraryTable.ModifiableModel model1 = table.getModifiableModel();
|
||||
model1.removeLibrary(a);
|
||||
|
||||
LibraryTable.ModifiableModel model2 = table.getModifiableModel();
|
||||
model2.createLibrary("b");
|
||||
commit(model1);
|
||||
commit(model2);
|
||||
|
||||
assertAllLibrariesAreNotDisposed();
|
||||
assertEquals("b", assertOneElement(table.getLibraries()).getName());
|
||||
}
|
||||
|
||||
public void testMergeAddAddChanges() {
|
||||
createLibrary("a", null, null);
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
|
||||
LibraryTable.ModifiableModel model1 = table.getModifiableModel();
|
||||
model1.createLibrary("b");
|
||||
|
||||
LibraryTable.ModifiableModel model2 = table.getModifiableModel();
|
||||
model2.createLibrary("c");
|
||||
commit(model1);
|
||||
commit(model2);
|
||||
|
||||
assertAllLibrariesAreNotDisposed();
|
||||
assertSameElements(ContainerUtil.map(table.getLibraries(), Library::getName), "a", "b", "c");
|
||||
}
|
||||
|
||||
public void testMergeRemoveRemoveChanges() {
|
||||
Library a = createLibrary("a", null, null);
|
||||
Library b = createLibrary("b", null, null);
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
|
||||
LibraryTable.ModifiableModel model1 = table.getModifiableModel();
|
||||
model1.removeLibrary(a);
|
||||
|
||||
LibraryTable.ModifiableModel model2 = table.getModifiableModel();
|
||||
model2.removeLibrary(b);
|
||||
commit(model1);
|
||||
commit(model2);
|
||||
|
||||
assertAllLibrariesAreNotDisposed();
|
||||
assertEmpty(table.getLibraries());
|
||||
}
|
||||
|
||||
private void assertAllLibrariesAreNotDisposed() {
|
||||
for (Library library : getProjectLibraryTable().getLibraries()) {
|
||||
assertEmpty(library.getUrls(OrderRootType.CLASSES));
|
||||
}
|
||||
}
|
||||
|
||||
public void testResolveDependencyToRenamedLibrary() {
|
||||
Library library = createLibrary("jdom2", getJDomJar(), null);
|
||||
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
|
||||
model.addInvalidLibrary("jdom", LibraryTablesRegistrar.PROJECT_LEVEL);
|
||||
commit(model);
|
||||
assertEmpty(getLibraries());
|
||||
|
||||
Library.ModifiableModel libModel = library.getModifiableModel();
|
||||
libModel.setName("jdom");
|
||||
commit(libModel);
|
||||
assertSameElements(getLibraries(), library);
|
||||
}
|
||||
|
||||
private Collection<Library> getLibraries() {
|
||||
CommonProcessors.CollectProcessor<Library> processor = new CommonProcessors.CollectProcessor<>();
|
||||
ModuleRootManager.getInstance(myModule).orderEntries().forEachLibrary(processor);
|
||||
return processor.getResults();
|
||||
}
|
||||
|
||||
private static void commit(final ModifiableRootModel model) {
|
||||
WriteAction.runAndWait(() -> model.commit());
|
||||
}
|
||||
|
||||
public void testNativePathSerialization() {
|
||||
LibraryTable table = getProjectLibraryTable();
|
||||
Library library = WriteAction.compute(() -> table.createLibrary("native"));
|
||||
@@ -452,40 +343,6 @@ public class LibraryTest extends ModuleRootManagerTestCase {
|
||||
assertTrue(rootsChanged.get());
|
||||
}
|
||||
|
||||
public void testAddRemoveExcludedRoot() {
|
||||
VirtualFile jar = getJDomJar();
|
||||
LibraryEx library = (LibraryEx)createLibrary("junit", jar, null);
|
||||
assertEmpty(library.getExcludedRoots());
|
||||
|
||||
LibraryEx.ModifiableModelEx model = library.getModifiableModel();
|
||||
model.addExcludedRoot(jar.getUrl());
|
||||
commit(model);
|
||||
assertOrderedEquals(library.getExcludedRoots(), jar);
|
||||
|
||||
LibraryEx.ModifiableModelEx model2 = library.getModifiableModel();
|
||||
model2.removeExcludedRoot(jar.getUrl());
|
||||
commit(model2);
|
||||
assertEmpty(library.getExcludedRoots());
|
||||
}
|
||||
|
||||
public void testRemoveExcludedRootWhenParentRootIsRemoved() {
|
||||
VirtualFile jar = getJDomJar();
|
||||
LibraryEx library = (LibraryEx)createLibrary("junit", jar, null);
|
||||
|
||||
LibraryEx.ModifiableModelEx model = library.getModifiableModel();
|
||||
VirtualFile excluded = jar.findChild("org");
|
||||
assertNotNull(excluded);
|
||||
model.addExcludedRoot(excluded.getUrl());
|
||||
commit(model);
|
||||
|
||||
assertOrderedEquals(library.getExcludedRoots(), excluded);
|
||||
LibraryEx.ModifiableModelEx model2 = library.getModifiableModel();
|
||||
model2.removeRoot(jar.getUrl(), OrderRootType.CLASSES);
|
||||
commit(model2);
|
||||
|
||||
assertEmpty(library.getExcludedRoots());
|
||||
}
|
||||
|
||||
private static void commit(final Library.ModifiableModel modifiableModel) {
|
||||
ApplicationManager.getApplication().runWriteAction(modifiableModel::commit);
|
||||
}
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
|
||||
class ApplicationLevelLibrariesInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().libraryTable
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addApplicationLevelLibrary(name)
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.testFramework.ApplicationRule
|
||||
import com.intellij.testFramework.rules.ProjectModelRule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class ConcurrentRootModelModificationTest {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val appRule = ApplicationRule()
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val projectModel = ProjectModelRule()
|
||||
|
||||
lateinit var module: Module
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
module = projectModel.createModule()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `commit one model and dispose another`() {
|
||||
val foo = projectModel.addProjectLevelLibrary("foo")
|
||||
val bar = projectModel.addProjectLevelLibrary("bar")
|
||||
val model1 = createModifiableModel(module)
|
||||
val model2 = createModifiableModel(module)
|
||||
model1.addLibraryEntry(foo)
|
||||
model2.addLibraryEntry(bar)
|
||||
commitModifiableRootModel(model1)
|
||||
model2.dispose()
|
||||
val libraryEntry = dropModuleSourceEntry(ModuleRootManager.getInstance(module), 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(foo)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `last committed model wins`() {
|
||||
val foo = projectModel.addProjectLevelLibrary("foo")
|
||||
val bar = projectModel.addProjectLevelLibrary("bar")
|
||||
val model1 = createModifiableModel(module)
|
||||
model1.addLibraryEntry(foo)
|
||||
val model2 = createModifiableModel(module)
|
||||
model2.addLibraryEntry(bar)
|
||||
commitModifiableRootModel(model1)
|
||||
commitModifiableRootModel(model2)
|
||||
val libraryEntry = dropModuleSourceEntry(ModuleRootManager.getInstance(module), 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(bar)
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.roots.libraries.*
|
||||
import com.intellij.testFramework.DisposableRule
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
||||
class LibrariesFromCustomTableInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
@Rule
|
||||
@JvmField
|
||||
val disposableRule = DisposableRule()
|
||||
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().getCustomLibraryTableByLevel("mock")!!
|
||||
|
||||
@Before
|
||||
fun registerCustomLibraryTable() {
|
||||
ExtensionPointName.create<CustomLibraryTableDescription>("com.intellij.customLibraryTable").point.registerExtension(object : CustomLibraryTableDescription {
|
||||
override fun getPresentation(): LibraryTablePresentation {
|
||||
return object : LibraryTablePresentation() {
|
||||
override fun getLibraryTableEditorTitle(): String = "Mock"
|
||||
override fun getDescription(): String = "Mock"
|
||||
override fun getDisplayName(plural: Boolean): String = "Mock"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTableLevel(): String {
|
||||
return "mock"
|
||||
}
|
||||
}, disposableRule.disposable)
|
||||
}
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addLibrary(name, libraryTable)
|
||||
}
|
||||
+62
-3
@@ -35,6 +35,7 @@ abstract class LibrariesFromLibraryTableInRootModelTestCase {
|
||||
|
||||
protected abstract fun createLibrary(name: String): Library
|
||||
protected abstract val libraryTable: LibraryTable
|
||||
protected open fun createLibrary(name: String, model: LibraryTable.ModifiableModel) = model.createLibrary(name) as LibraryEx
|
||||
|
||||
@Test
|
||||
fun `add edit remove library`() {
|
||||
@@ -219,6 +220,64 @@ abstract class LibrariesFromLibraryTableInRootModelTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rename library`() {
|
||||
val a = createLibrary("a")
|
||||
ModuleRootModificationUtil.addDependency(module, a)
|
||||
projectModel.renameLibrary(a, "b")
|
||||
val libraryEntry = dropModuleSourceEntry(ModuleRootManager.getInstance(module), 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(a)
|
||||
assertThat(libraryEntry.libraryName).isEqualTo("b")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rename library and commit after committing root model`() {
|
||||
val a = createLibrary("a")
|
||||
val model = createModifiableModel(module)
|
||||
model.addLibraryEntry(a)
|
||||
val libModel = a.modifiableModel
|
||||
libModel.name = "b"
|
||||
val libraryEntry = dropModuleSourceEntry(model, 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(a)
|
||||
assertThat(libraryEntry.libraryName).isEqualTo("a")
|
||||
val committed = commitModifiableRootModel(model)
|
||||
val committedEntry1 = dropModuleSourceEntry(committed, 1).single() as LibraryOrderEntry
|
||||
assertThat(committedEntry1.library).isEqualTo(a)
|
||||
assertThat(committedEntry1.libraryName).isEqualTo("a")
|
||||
runWriteActionAndWait { libModel.commit() }
|
||||
val committedEntry2 = dropModuleSourceEntry(committed, 1).single() as LibraryOrderEntry
|
||||
assertThat(committedEntry2.library).isEqualTo(a)
|
||||
assertThat(committedEntry2.libraryName).isEqualTo("b")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rename library before committing root model`() {
|
||||
val a = createLibrary("a")
|
||||
val model = createModifiableModel(module)
|
||||
model.addLibraryEntry(a)
|
||||
projectModel.renameLibrary(a, "b")
|
||||
val libraryEntry = dropModuleSourceEntry(model, 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(a)
|
||||
assertThat(libraryEntry.libraryName).isEqualTo("b")
|
||||
val committed = commitModifiableRootModel(model)
|
||||
val committedEntry = dropModuleSourceEntry(committed, 1).single() as LibraryOrderEntry
|
||||
assertThat(committedEntry.library).isEqualTo(a)
|
||||
assertThat(committedEntry.libraryName).isEqualTo("b")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add invalid library and rename library to that name`() {
|
||||
val library = createLibrary("foo")
|
||||
val model = createModifiableModel(module)
|
||||
model.addInvalidLibrary("bar", libraryTable.tableLevel)
|
||||
commitModifiableRootModel(model)
|
||||
|
||||
projectModel.renameLibrary(library, "bar")
|
||||
|
||||
val libraryEntry = dropModuleSourceEntry(ModuleRootManager.getInstance(module), 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(library)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `dispose model without committing`() {
|
||||
val a = createLibrary("a")
|
||||
@@ -232,7 +291,7 @@ abstract class LibrariesFromLibraryTableInRootModelTestCase {
|
||||
@Test
|
||||
fun `add not yet committed library and commit root model`() {
|
||||
val libraryTableModel = libraryTable.modifiableModel
|
||||
val a = libraryTableModel.createLibrary("a")
|
||||
val a = createLibrary("a", libraryTableModel)
|
||||
run {
|
||||
val model = createModifiableModel(module)
|
||||
val entry = model.addLibraryEntry(a)
|
||||
@@ -253,7 +312,7 @@ abstract class LibrariesFromLibraryTableInRootModelTestCase {
|
||||
@Test
|
||||
fun `add not yet committed library and commit before committing root model`() {
|
||||
val libraryTableModel = libraryTable.modifiableModel
|
||||
val a = libraryTableModel.createLibrary("a")
|
||||
val a = createLibrary("a", libraryTableModel)
|
||||
val model = createModifiableModel(module)
|
||||
val entry = model.addLibraryEntry(a)
|
||||
assertThat(entry.library).isEqualTo(a)
|
||||
@@ -268,7 +327,7 @@ abstract class LibrariesFromLibraryTableInRootModelTestCase {
|
||||
@Test
|
||||
fun `add not yet committed library with configuration accessor`() {
|
||||
val libraryTableModel = libraryTable.modifiableModel
|
||||
val a = libraryTableModel.createLibrary("a")
|
||||
val a = createLibrary("a", libraryTableModel)
|
||||
run {
|
||||
val model = createModifiableModel(module, object : RootConfigurationAccessor() {
|
||||
override fun getLibrary(library: Library?, libraryName: String?, libraryLevel: String?): Library? {
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.application.runWriteActionAndWait
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.ApplicationRule
|
||||
import com.intellij.testFramework.DisposableRule
|
||||
import com.intellij.testFramework.rules.ProjectModelRule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
abstract class LibraryTableTestCase {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val appRule = ApplicationRule()
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val projectModel = ProjectModelRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val disposableRule = DisposableRule()
|
||||
|
||||
protected abstract val libraryTable: LibraryTable
|
||||
protected abstract fun createLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit = {}): LibraryEx
|
||||
protected open fun createLibrary(name: String, model: LibraryTable.ModifiableModel) = model.createLibrary(name) as LibraryEx
|
||||
|
||||
@Test
|
||||
fun `add remove library`() {
|
||||
assertThat(libraryTable.libraries).isEmpty()
|
||||
val library = createLibrary("a")
|
||||
checkConsistency()
|
||||
assertThat(libraryTable.libraries).containsExactly(library)
|
||||
assertThat(library.isDisposed).isFalse()
|
||||
runWriteActionAndWait { libraryTable.removeLibrary(library) }
|
||||
checkConsistency()
|
||||
assertThat(libraryTable.libraries).isEmpty()
|
||||
assertThat(library.isDisposed).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listener() {
|
||||
val events = ArrayList<String>()
|
||||
libraryTable.addListener(object : LibraryTable.Listener {
|
||||
override fun afterLibraryAdded(newLibrary: Library) {
|
||||
events += "added ${newLibrary.name}"
|
||||
}
|
||||
|
||||
override fun afterLibraryRenamed(library: Library) {
|
||||
events += "renamed ${library.name}"
|
||||
}
|
||||
|
||||
override fun beforeLibraryRemoved(library: Library) {
|
||||
events += "before removed ${library.name}"
|
||||
}
|
||||
|
||||
override fun afterLibraryRemoved(library: Library) {
|
||||
events += "removed ${library.name}"
|
||||
}
|
||||
})
|
||||
val library = createLibrary("a")
|
||||
assertThat(events).containsExactly("added a")
|
||||
events.clear()
|
||||
projectModel.renameLibrary(library, "b")
|
||||
assertThat(events).containsExactly("renamed b")
|
||||
events.clear()
|
||||
runWriteActionAndWait { libraryTable.removeLibrary(library) }
|
||||
assertThat(events).containsExactly("before removed b", "removed b")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove library before committing`() {
|
||||
val library = edit {
|
||||
val library = createLibrary("a", it)
|
||||
assertThat(it.isChanged).isTrue()
|
||||
it.removeLibrary(library)
|
||||
assertThat(it.isChanged).isFalse()
|
||||
library
|
||||
}
|
||||
assertThat(libraryTable.libraries).isEmpty()
|
||||
assertThat(library.isDisposed).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `dispose model`() {
|
||||
val model = libraryTable.modifiableModel
|
||||
val library = createLibrary("a", model)
|
||||
Disposer.dispose(model)
|
||||
assertThat(libraryTable.libraries).isEmpty()
|
||||
assertThat(library.isDisposed).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `merge add remove changes`() {
|
||||
val a = createLibrary("a")
|
||||
val model1 = libraryTable.modifiableModel
|
||||
model1.removeLibrary(a)
|
||||
val model2 = libraryTable.modifiableModel
|
||||
val b = createLibrary("b", model2)
|
||||
runWriteActionAndWait {
|
||||
model1.commit()
|
||||
model2.commit()
|
||||
}
|
||||
assertThat(libraryTable.libraries).containsExactly(b)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `merge add add changes`() {
|
||||
val a = createLibrary("a")
|
||||
val model1 = libraryTable.modifiableModel
|
||||
val b = createLibrary("b", model1)
|
||||
val model2 = libraryTable.modifiableModel
|
||||
val c = createLibrary("c", model2)
|
||||
runWriteActionAndWait {
|
||||
model1.commit()
|
||||
model2.commit()
|
||||
}
|
||||
assertThat(libraryTable.libraries).containsExactly(a, b, c)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `merge remove remove changes`() {
|
||||
val a = createLibrary("a")
|
||||
val b = createLibrary("b")
|
||||
val model1 = libraryTable.modifiableModel
|
||||
model1.removeLibrary(a)
|
||||
val model2 = libraryTable.modifiableModel
|
||||
model2.removeLibrary(b)
|
||||
runWriteActionAndWait {
|
||||
model1.commit()
|
||||
model2.commit()
|
||||
}
|
||||
assertThat(libraryTable.libraries).isEmpty()
|
||||
}
|
||||
|
||||
|
||||
private fun <T> edit(action: (LibraryTable.ModifiableModel) -> T): T{
|
||||
checkConsistency()
|
||||
val model = libraryTable.modifiableModel
|
||||
checkConsistency(model)
|
||||
val result = action(model)
|
||||
checkConsistency(model)
|
||||
runWriteActionAndWait { model.commit() }
|
||||
checkConsistency()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun checkConsistency() {
|
||||
val fromIterator = ArrayList<Library>()
|
||||
libraryTable.libraryIterator.forEach { fromIterator += it }
|
||||
assertThat(fromIterator).containsExactly(*libraryTable.libraries)
|
||||
for (library in libraryTable.libraries) {
|
||||
assertThat(libraryTable.getLibraryByName(library.name!!)).isEqualTo(library)
|
||||
assertThat((library as LibraryEx).isDisposed).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkConsistency(model: LibraryTable.ModifiableModel) {
|
||||
val fromIterator = ArrayList<Library>()
|
||||
model.libraryIterator.forEach { fromIterator += it }
|
||||
assertThat(fromIterator).containsExactly(*model.libraries)
|
||||
for (library in model.libraries) {
|
||||
assertThat(model.getLibraryByName(library.name!!)).isEqualTo(library)
|
||||
assertThat((library as LibraryEx).isDisposed).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.application.runWriteActionAndWait
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.testFramework.ApplicationRule
|
||||
import com.intellij.testFramework.rules.ProjectModelRule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class LibraryTest {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val appRule = ApplicationRule()
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val projectModel = ProjectModelRule()
|
||||
|
||||
@Test
|
||||
fun `empty library`() {
|
||||
val library = projectModel.addProjectLevelLibrary("a")
|
||||
assertThat(library.name).isEqualTo("a")
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.table).isEqualTo(projectModel.projectLibraryTable)
|
||||
assertThat(library.excludedRoots).isEmpty()
|
||||
assertThat(library.getInvalidRootUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.source).isNull()
|
||||
assertThat(library.module).isNull()
|
||||
checkConsistency(library)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add remove roots`() {
|
||||
val classesRoot = projectModel.baseProjectDir.newVirtualDirectory("classes")
|
||||
val sourceRoot = projectModel.baseProjectDir.newVirtualDirectory("src")
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(classesRoot, OrderRootType.CLASSES)
|
||||
}
|
||||
checkConsistency(library)
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
assertThat(library.getFiles(OrderRootType.SOURCES)).isEmpty()
|
||||
assertThat(library.isValid(classesRoot.url, OrderRootType.CLASSES)).isTrue()
|
||||
edit(library) {
|
||||
assertThat(it.isChanged).isFalse()
|
||||
it.addRoot(sourceRoot, OrderRootType.SOURCES)
|
||||
assertThat(it.isChanged).isTrue()
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
assertThat(it.getFiles(OrderRootType.SOURCES)).containsExactly(sourceRoot)
|
||||
assertThat(library.getFiles(OrderRootType.SOURCES)).isEmpty()
|
||||
}
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
assertThat(library.getFiles(OrderRootType.SOURCES)).containsExactly(sourceRoot)
|
||||
edit(library) {
|
||||
it.removeRoot(sourceRoot.url, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged).isFalse()
|
||||
it.removeRoot(classesRoot.url, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged).isTrue()
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(it.getFiles(OrderRootType.SOURCES)).containsExactly(sourceRoot)
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
}
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.getFiles(OrderRootType.SOURCES)).containsExactly(sourceRoot)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add remove invalid root`() {
|
||||
val classesRootDir = projectModel.baseProjectDir.newVirtualDirectory("lib")
|
||||
val classesUrl = "${classesRootDir.url}/classes"
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(classesUrl, OrderRootType.CLASSES)
|
||||
assertThat(it.getUrls(OrderRootType.CLASSES)).containsExactly(classesUrl)
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
}
|
||||
checkConsistency(library)
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).containsExactly(classesUrl)
|
||||
assertThat(library.isValid(classesUrl, OrderRootType.CLASSES)).isFalse()
|
||||
assertThat(library.getInvalidRootUrls(OrderRootType.CLASSES)).containsExactly(classesUrl)
|
||||
edit(library) {
|
||||
it.removeRoot(classesUrl, OrderRootType.SOURCES)
|
||||
assertThat(it.isChanged).isFalse()
|
||||
it.removeRoot(classesUrl, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged).isTrue()
|
||||
}
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.getInvalidRootUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.isValid(classesUrl, OrderRootType.CLASSES)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add invalid root and make it valid`() {
|
||||
val classesRootDir = projectModel.baseProjectDir.newVirtualDirectory("lib")
|
||||
val classesUrl = "${classesRootDir.url}/classes"
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(classesUrl, OrderRootType.CLASSES)
|
||||
}
|
||||
checkConsistency(library)
|
||||
assertThat(library.isValid(classesUrl, OrderRootType.CLASSES)).isFalse()
|
||||
assertThat(library.getInvalidRootUrls(OrderRootType.CLASSES)).containsExactly(classesUrl)
|
||||
val classesRoot = projectModel.baseProjectDir.newVirtualDirectory("lib/classes")
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).containsExactly(classesUrl)
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
assertThat(library.getInvalidRootUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(library.isValid(classesUrl, OrderRootType.CLASSES)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add remove jar directory`() {
|
||||
val jarDir = projectModel.baseProjectDir.newVirtualDirectory("jarDir")
|
||||
val jarDirSrc = projectModel.baseProjectDir.newVirtualDirectory("jarDirSrc")
|
||||
val jarDirRec = projectModel.baseProjectDir.newVirtualDirectory("jarDirRec")
|
||||
val jarDirSrcRec = projectModel.baseProjectDir.newVirtualDirectory("jarDirSrcRec")
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addJarDirectory(jarDir, false)
|
||||
it.addJarDirectory(jarDirRec, true)
|
||||
it.addJarDirectory(jarDirSrc.url, false, OrderRootType.SOURCES)
|
||||
it.addJarDirectory(jarDirSrcRec.url, true, OrderRootType.SOURCES)
|
||||
assertThat(it.isJarDirectory(jarDir.url)).isTrue()
|
||||
assertThat(it.isJarDirectory(jarDirSrc.url)).isFalse()
|
||||
assertThat(it.isJarDirectory(jarDirSrc.url, OrderRootType.SOURCES)).isTrue()
|
||||
assertThat(it.isJarDirectory(jarDirRec.url)).isTrue()
|
||||
assertThat(it.isJarDirectory(jarDirSrcRec.url, OrderRootType.SOURCES)).isTrue()
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
assertThat(it.getUrls(OrderRootType.CLASSES)).containsExactly(jarDir.url, jarDirRec.url)
|
||||
}
|
||||
checkConsistency(library)
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).containsExactly(jarDir.url, jarDirRec.url)
|
||||
assertThat(library.isJarDirectory(jarDir.url)).isTrue()
|
||||
assertThat(library.isJarDirectory(jarDirSrc.url)).isFalse()
|
||||
assertThat(library.isJarDirectory(jarDirSrc.url, OrderRootType.SOURCES)).isTrue()
|
||||
assertThat(library.isJarDirectory(jarDirRec.url)).isTrue()
|
||||
assertThat(library.isJarDirectory(jarDirSrcRec.url, OrderRootType.SOURCES)).isTrue()
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).isEmpty()
|
||||
|
||||
fun VirtualFile.toJarRoot() = JarFileSystem.getInstance().getJarRootForLocalFile(this)
|
||||
val classesRoot = projectModel.baseProjectDir.newVirtualFile("jarDir/a.jar").toJarRoot()
|
||||
projectModel.baseProjectDir.newVirtualFile("jarDir/subDir/b.jar")
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot)
|
||||
val classesRootRec1 = projectModel.baseProjectDir.newVirtualFile("jarDirRec/a.jar").toJarRoot()
|
||||
val classesRootRec2 = projectModel.baseProjectDir.newVirtualFile("jarDirRec/subDir/a.jar").toJarRoot()
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(classesRoot, classesRootRec1, classesRootRec2)
|
||||
checkConsistency(library)
|
||||
|
||||
edit(library) {
|
||||
it.removeRoot(jarDir.url, OrderRootType.CLASSES)
|
||||
it.removeRoot(jarDirRec.url, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged)
|
||||
}
|
||||
assertThat(library.getUrls(OrderRootType.CLASSES)).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add remove excluded root`() {
|
||||
val classesRoot = projectModel.baseProjectDir.newVirtualDirectory("classes")
|
||||
val excludedRoot = projectModel.baseProjectDir.newVirtualDirectory("classes/exc")
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(classesRoot, OrderRootType.CLASSES)
|
||||
it.addExcludedRoot(excludedRoot.url)
|
||||
assertThat(it.excludedRootUrls).containsExactly(excludedRoot.url)
|
||||
}
|
||||
assertThat(library.excludedRoots).containsExactly(excludedRoot)
|
||||
|
||||
edit(library) {
|
||||
it.removeExcludedRoot(excludedRoot.url)
|
||||
assertThat(it.isChanged)
|
||||
}
|
||||
assertThat(library.excludedRoots).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove excluded root when parent is removed`() {
|
||||
val classesRoot = projectModel.baseProjectDir.newVirtualDirectory("classes")
|
||||
val excludedRoot = projectModel.baseProjectDir.newVirtualDirectory("classes/exc")
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(classesRoot, OrderRootType.CLASSES)
|
||||
it.addExcludedRoot(excludedRoot.url)
|
||||
}
|
||||
assertThat(library.excludedRoots).containsExactly(excludedRoot)
|
||||
|
||||
edit(library) {
|
||||
it.removeRoot(classesRoot.url, OrderRootType.CLASSES)
|
||||
}
|
||||
assertThat(library.excludedRoots).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rename() {
|
||||
val library = projectModel.addProjectLevelLibrary("a")
|
||||
edit(library) {
|
||||
it.name = "b"
|
||||
assertThat(it.isChanged).isTrue()
|
||||
assertThat(it.name).isEqualTo("b")
|
||||
}
|
||||
assertThat(library.name).isEqualTo("b")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `move roots up and down`() {
|
||||
val root1 = projectModel.baseProjectDir.newVirtualDirectory("root1")
|
||||
val src = projectModel.baseProjectDir.newVirtualDirectory("src")
|
||||
val root2 = projectModel.baseProjectDir.newVirtualDirectory("root2")
|
||||
val library = projectModel.addProjectLevelLibrary("a") {
|
||||
it.addRoot(root1, OrderRootType.CLASSES)
|
||||
it.addRoot(src, OrderRootType.SOURCES)
|
||||
it.addRoot(root2, OrderRootType.CLASSES)
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).containsExactly(root1, root2)
|
||||
it.moveRootDown(root1.url, OrderRootType.CLASSES)
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).containsExactly(root2, root1)
|
||||
}
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(root2, root1)
|
||||
|
||||
edit(library) {
|
||||
it.moveRootUp(root2.url, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged).isFalse()
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).containsExactly(root2, root1)
|
||||
it.moveRootUp(root1.url, OrderRootType.CLASSES)
|
||||
assertThat(it.isChanged).isTrue()
|
||||
assertThat(it.getFiles(OrderRootType.CLASSES)).containsExactly(root1, root2)
|
||||
}
|
||||
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(root1, root2)
|
||||
}
|
||||
|
||||
private fun checkConsistency(library: LibraryEx) {
|
||||
assertThat(library.rootProvider.getFiles(OrderRootType.CLASSES)).containsExactly(*library.getFiles(OrderRootType.CLASSES))
|
||||
assertThat(library.rootProvider.getFiles(OrderRootType.SOURCES)).containsExactly(*library.getFiles(OrderRootType.SOURCES))
|
||||
assertThat(library.rootProvider.getUrls(OrderRootType.CLASSES)).containsExactly(*library.getUrls(OrderRootType.CLASSES))
|
||||
assertThat(library.rootProvider.getUrls(OrderRootType.SOURCES)).containsExactly(*library.getUrls(OrderRootType.SOURCES))
|
||||
if (library.getUrls(OrderRootType.CLASSES).none { library.isJarDirectory(it) }) {
|
||||
val classesRoots = library.getUrls(OrderRootType.CLASSES).mapNotNull { VirtualFileManager.getInstance().findFileByUrl(it) }
|
||||
assertThat(library.getFiles(OrderRootType.CLASSES)).containsExactly(*classesRoots.toTypedArray())
|
||||
}
|
||||
if (library.getUrls(OrderRootType.SOURCES).none { library.isJarDirectory(it, OrderRootType.SOURCES) }) {
|
||||
val sourcesRoots = library.getUrls(OrderRootType.SOURCES).mapNotNull { VirtualFileManager.getInstance().findFileByUrl(it) }
|
||||
assertThat(library.getFiles(OrderRootType.SOURCES)).containsExactly(*sourcesRoots.toTypedArray())
|
||||
}
|
||||
val excludedRoots = library.excludedRootUrls.mapNotNull { VirtualFileManager.getInstance().findFileByUrl(it) }
|
||||
assertThat(library.excludedRoots).containsExactly(*excludedRoots.toTypedArray())
|
||||
}
|
||||
|
||||
private inline fun edit(library: LibraryEx, action: (LibraryEx.ModifiableModelEx) -> Unit) {
|
||||
checkConsistency(library)
|
||||
val model = library.modifiableModel
|
||||
action(model)
|
||||
runWriteActionAndWait { model.commit() }
|
||||
checkConsistency(library)
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.roots.libraries.CustomLibraryTableDescription
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablePresentation
|
||||
|
||||
class MockCustomLibraryTableDescription : CustomLibraryTableDescription {
|
||||
override fun getPresentation(): LibraryTablePresentation {
|
||||
return object : LibraryTablePresentation() {
|
||||
override fun getLibraryTableEditorTitle(): String = "Mock"
|
||||
override fun getDescription(): String = "Mock"
|
||||
override fun getDisplayName(plural: Boolean): String = "Mock"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTableLevel(): String {
|
||||
return "mock"
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -37,7 +37,7 @@ class ModuleLevelLibrariesInRootModelTest {
|
||||
fun `add edit remove unnamed module library`() {
|
||||
run {
|
||||
val model = createModifiableModel(module)
|
||||
val library = model.moduleLibraryTable.createLibrary()
|
||||
val library = model.moduleLibraryTable.createLibrary() as LibraryEx
|
||||
assertThat(model.moduleLibraryTable.libraries.single()).isEqualTo(library)
|
||||
val libraryEntry = dropModuleSourceEntry(model, 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.isModuleLevel).isTrue()
|
||||
@@ -47,7 +47,8 @@ class ModuleLevelLibrariesInRootModelTest {
|
||||
assertThat(libraryEntry.isExported).isFalse()
|
||||
assertThat(libraryEntry.libraryLevel).isEqualTo(LibraryTableImplUtil.MODULE_LEVEL)
|
||||
assertThat(model.findLibraryOrderEntry(library)).isEqualTo(libraryEntry)
|
||||
assertThat((library as LibraryEx).isDisposed).isFalse()
|
||||
assertThat(library.isDisposed).isFalse()
|
||||
assertThat(library.module).isEqualTo(module)
|
||||
|
||||
val committed = commitModifiableRootModel(model)
|
||||
val committedEntry = dropModuleSourceEntry(committed, 1).single() as LibraryOrderEntry
|
||||
@@ -58,6 +59,7 @@ class ModuleLevelLibrariesInRootModelTest {
|
||||
assertThat(committedEntry.library).isEqualTo(library)
|
||||
assertThat(committedEntry.libraryLevel).isEqualTo(LibraryTableImplUtil.MODULE_LEVEL)
|
||||
assertThat(library.isDisposed).isTrue()
|
||||
assertThat((committedEntry.library as LibraryEx).module).isEqualTo(module)
|
||||
assertThat((committedEntry.library as LibraryEx).isDisposed).isFalse()
|
||||
}
|
||||
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.application.runWriteActionAndWait
|
||||
import com.intellij.openapi.roots.impl.ModifiableModelCommitter
|
||||
import com.intellij.testFramework.ApplicationRule
|
||||
import com.intellij.testFramework.rules.ProjectModelRule
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class MultipleModuleRootModelTest {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val appRule = ApplicationRule()
|
||||
}
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val projectModel = ProjectModelRule()
|
||||
|
||||
@Test
|
||||
fun `commit root model before committing module`() {
|
||||
val library = projectModel.addProjectLevelLibrary("lib")
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val module = projectModel.createModule("a", moduleModel)
|
||||
val model = createModifiableModel(module)
|
||||
model.addLibraryEntry(library)
|
||||
val committed = commitModifiableRootModel(model)
|
||||
val libraryEntry = dropModuleSourceEntry(committed, 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntry.library).isEqualTo(library)
|
||||
runWriteActionAndWait { moduleModel.commit() }
|
||||
val libraryEntryForCommitted = dropModuleSourceEntry(ModuleRootManager.getInstance(module), 1).single() as LibraryOrderEntry
|
||||
assertThat(libraryEntryForCommitted.library).isEqualTo(library)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `commit root model and dispose module`() {
|
||||
val library = projectModel.addProjectLevelLibrary("lib")
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val module = projectModel.createModule("a", moduleModel)
|
||||
val model = createModifiableModel(module)
|
||||
model.addLibraryEntry(library)
|
||||
commitModifiableRootModel(model)
|
||||
runWriteActionAndWait { moduleModel.dispose() }
|
||||
assertThat(projectModel.moduleManager.modules).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create two modules with dependency between them`() {
|
||||
val moduleManager = projectModel.moduleManager
|
||||
val moduleModel = runReadAction { moduleManager.modifiableModel }
|
||||
val a = projectModel.createModule("a", moduleModel)
|
||||
val b = projectModel.createModule("b", moduleModel)
|
||||
val model = createModifiableModel(a)
|
||||
model.addModuleOrderEntry(b)
|
||||
runWriteActionAndWait { ModifiableModelCommitter.multiCommit(listOf(model), moduleModel) }
|
||||
assertThat(moduleManager.findModuleByName("a")).isEqualTo(a)
|
||||
assertThat(ModuleRootManager.getInstance(a).dependencies.single()).isEqualTo(b)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create two modules with circular dependency between them`() {
|
||||
val moduleManager = projectModel.moduleManager
|
||||
val moduleModel = runReadAction { moduleManager.modifiableModel }
|
||||
val a = projectModel.createModule("a", moduleModel)
|
||||
val b = projectModel.createModule("b", moduleModel)
|
||||
val modelA = createModifiableModel(a)
|
||||
modelA.addModuleOrderEntry(b)
|
||||
val modelB = createModifiableModel(b)
|
||||
modelB.addModuleOrderEntry(a)
|
||||
runWriteActionAndWait { ModifiableModelCommitter.multiCommit(listOf(modelA, modelB), moduleModel) }
|
||||
assertThat(moduleManager.findModuleByName("a")).isEqualTo(a)
|
||||
assertThat(moduleManager.findModuleByName("b")).isEqualTo(b)
|
||||
assertThat(ModuleRootManager.getInstance(a).dependencies.single()).isEqualTo(b)
|
||||
assertThat(ModuleRootManager.getInstance(b).dependencies.single()).isEqualTo(a)
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
|
||||
class ProjectLevelLibrariesInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = projectModel.projectLibraryTable
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addProjectLevelLibrary(name)
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.CustomLibraryTableDescription
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
import com.intellij.testFramework.DisposableRule
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
||||
class ProjectLevelLibrariesInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = projectModel.projectLibraryTable
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addProjectLevelLibrary(name)
|
||||
}
|
||||
|
||||
class ApplicationLevelLibrariesInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().libraryTable
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addApplicationLevelLibrary(name)
|
||||
|
||||
override fun createLibrary(name: String, model: LibraryTable.ModifiableModel): LibraryEx {
|
||||
return projectModel.createLibraryAndDisposeOnTearDown(name, model)
|
||||
}
|
||||
}
|
||||
|
||||
class LibrariesFromCustomTableInRootModelTest : LibrariesFromLibraryTableInRootModelTestCase() {
|
||||
@Rule
|
||||
@JvmField
|
||||
val disposableRule = DisposableRule()
|
||||
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().getCustomLibraryTableByLevel("mock")!!
|
||||
|
||||
@Before
|
||||
fun registerCustomLibraryTable() {
|
||||
ExtensionPointName.create<CustomLibraryTableDescription>("com.intellij.customLibraryTable").point.registerExtension(
|
||||
MockCustomLibraryTableDescription(), disposableRule.disposable)
|
||||
}
|
||||
|
||||
override fun createLibrary(name: String): Library = projectModel.addLibrary(name, libraryTable)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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.openapi.roots
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.CustomLibraryTableDescription
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
import org.junit.Before
|
||||
|
||||
class ProjectLibraryTableTest : LibraryTableTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = projectModel.projectLibraryTable
|
||||
|
||||
override fun createLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit): LibraryEx {
|
||||
return projectModel.addProjectLevelLibrary(name, setup)
|
||||
}
|
||||
}
|
||||
|
||||
class ApplicationLibraryTableTest : LibraryTableTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().libraryTable
|
||||
|
||||
override fun createLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit): LibraryEx {
|
||||
return projectModel.addApplicationLevelLibrary(name, setup)
|
||||
}
|
||||
|
||||
override fun createLibrary(name: String, model: LibraryTable.ModifiableModel): LibraryEx {
|
||||
return projectModel.createLibraryAndDisposeOnTearDown(name, model)
|
||||
}
|
||||
}
|
||||
|
||||
class CustomLibraryTableTest : LibraryTableTestCase() {
|
||||
override val libraryTable: LibraryTable
|
||||
get() = LibraryTablesRegistrar.getInstance().getCustomLibraryTableByLevel("mock")!!
|
||||
|
||||
@Before
|
||||
fun registerCustomLibraryTable() {
|
||||
ExtensionPointName.create<CustomLibraryTableDescription>("com.intellij.customLibraryTable").point.registerExtension(
|
||||
MockCustomLibraryTableDescription(), disposableRule.disposable)
|
||||
}
|
||||
|
||||
override fun createLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit): LibraryEx {
|
||||
return projectModel.addLibrary(name, libraryTable)
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import com.intellij.openapi.projectRoots.SdkTypeId
|
||||
import com.intellij.openapi.projectRoots.SimpleJavaSdkType
|
||||
import com.intellij.openapi.rd.attach
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
@@ -71,13 +72,13 @@ class ProjectModelRule : TestRule {
|
||||
return sdk
|
||||
}
|
||||
|
||||
fun addProjectLevelLibrary(name: String, setup: (Library.ModifiableModel) -> Unit = {}): Library {
|
||||
fun addProjectLevelLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit = {}): LibraryEx {
|
||||
return addLibrary(name, projectLibraryTable, setup)
|
||||
}
|
||||
|
||||
fun addLibrary(name: String, libraryTable: LibraryTable, setup: (Library.ModifiableModel) -> Unit = {}): Library {
|
||||
fun addLibrary(name: String, libraryTable: LibraryTable, setup: (LibraryEx.ModifiableModelEx) -> Unit = {}): LibraryEx {
|
||||
val model = libraryTable.modifiableModel
|
||||
val library = model.createLibrary(name)
|
||||
val library = model.createLibrary(name) as LibraryEx
|
||||
val libraryModel = library.modifiableModel
|
||||
setup(libraryModel)
|
||||
runWriteActionAndWait {
|
||||
@@ -87,19 +88,35 @@ class ProjectModelRule : TestRule {
|
||||
return library
|
||||
}
|
||||
|
||||
fun addApplicationLevelLibrary(name: String): Library {
|
||||
fun addApplicationLevelLibrary(name: String, setup: (LibraryEx.ModifiableModelEx) -> Unit = {}): LibraryEx {
|
||||
val libraryTable = LibraryTablesRegistrar.getInstance().libraryTable
|
||||
val library = addLibrary(name, libraryTable) {}
|
||||
val library = addLibrary(name, libraryTable, setup)
|
||||
disposeOnTearDown(library)
|
||||
return library
|
||||
}
|
||||
|
||||
private fun disposeOnTearDown(library: LibraryEx) {
|
||||
disposableRule.disposable.attach {
|
||||
runWriteActionAndWait {
|
||||
if (libraryTable.getLibraryByName(name) == library) {
|
||||
libraryTable.removeLibrary(library)
|
||||
if (!library.isDisposed && library.table.getLibraryByName(library.name!!) == library) {
|
||||
library.table.removeLibrary(library)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createLibraryAndDisposeOnTearDown(name: String, model: LibraryTable.ModifiableModel): LibraryEx {
|
||||
val library = model.createLibrary(name) as LibraryEx
|
||||
disposeOnTearDown(library)
|
||||
return library
|
||||
}
|
||||
|
||||
fun renameLibrary(library: Library, newName: String) {
|
||||
val model = library.modifiableModel
|
||||
model.name = newName
|
||||
runWriteActionAndWait { model.commit() }
|
||||
}
|
||||
|
||||
val sdkType: SdkTypeId
|
||||
get() = SimpleJavaSdkType.getInstance()
|
||||
|
||||
|
||||
@@ -103,6 +103,15 @@ class TempDirectory : ExternalResource() {
|
||||
return VfsTestUtil.createDir(virtualFileRoot, relativePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new virtual file with the given relative path from the root temp directory. Throws an exception if such a file already exists.
|
||||
*/
|
||||
fun newVirtualFile(relativePath: String, content: String = ""): VirtualFile {
|
||||
val existing = virtualFileRoot.findFileByRelativePath(relativePath)
|
||||
require(existing == null) { "Already exists: ${existing!!.path}"}
|
||||
return VfsTestUtil.createFile(virtualFileRoot, relativePath, content)
|
||||
}
|
||||
|
||||
@Deprecated("use newDirectory(relativePath) instead", ReplaceWith("newDirectory(relativePath)"))
|
||||
fun newFolder(relativePath: String): File {
|
||||
return newDirectory(relativePath)
|
||||
|
||||
Reference in New Issue
Block a user