mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[sdk] added tests for SdkComboBox.kt and for ES combobox util
GitOrigin-RevId: 7f53b2b1a4ea117dae49853c4d9484f196b6a67a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
21e2acbaff
commit
f9d6ab9cd7
@@ -22,5 +22,6 @@
|
||||
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="assertJ" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.lang.tests" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
+1
@@ -7,6 +7,7 @@ import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.*;
|
||||
import com.intellij.openapi.projectRoots.impl.DependentSdkType;
|
||||
import com.intellij.openapi.projectRoots.impl.MockSdk;
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
|
||||
+20
-15
@@ -5,36 +5,38 @@ package com.intellij.openapi.externalSystem.service.ui
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkException
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.USE_PROJECT_JDK
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkComboBox
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkListItem
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
|
||||
fun SdkComboBox.getSelectedJdkReference(): String? {
|
||||
return when (val it = selectedItem) {
|
||||
is SdkListItem.ProjectSdkItem -> ExternalSystemJdkUtil.USE_PROJECT_JDK
|
||||
is SdkListItem.SdkItem -> it.sdk.name
|
||||
is SdkListItem.InvalidSdkItem -> it.sdkName
|
||||
fun SdkComboBox.getSelectedJdkReference() = resolveJdkReference(selectedItem)
|
||||
|
||||
private fun resolveJdkReference(item: SdkListItem?): String? {
|
||||
return when (item) {
|
||||
is SdkListItem.ProjectSdkItem -> USE_PROJECT_JDK
|
||||
is SdkListItem.SdkItem -> item.sdk.name
|
||||
is SdkListItem.InvalidSdkItem -> item.sdkName
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun SdkComboBox.setSelectedJdkReference(jdkReference: String?) {
|
||||
selectedItem = when (jdkReference) {
|
||||
null -> showNoneSdkItem()
|
||||
ExternalSystemJdkUtil.USE_PROJECT_JDK -> showProjectSdkItem()
|
||||
else -> resolveSdkItem(jdkReference)
|
||||
}
|
||||
selectedItem = resolveSdkItem(jdkReference)
|
||||
}
|
||||
|
||||
private fun SdkComboBox.resolveSdkItem(selectedJdkReference: String): SdkListItem {
|
||||
private fun SdkComboBox.resolveSdkItem(jdkReference: String?): SdkListItem {
|
||||
if (jdkReference == null) return showNoneSdkItem()
|
||||
if (jdkReference == USE_PROJECT_JDK) return showProjectSdkItem()
|
||||
try {
|
||||
val selectedJdk = ExternalSystemJdkUtil.resolveJdkName(null, selectedJdkReference)
|
||||
if (selectedJdk == null) return showInvalidSdkItem(selectedJdkReference)
|
||||
val selectedJdk = ExternalSystemJdkUtil.resolveJdkName(null, jdkReference)
|
||||
if (selectedJdk == null) return showInvalidSdkItem(jdkReference)
|
||||
return findSdkItem(selectedJdk) ?: addAndGetSdkItem(selectedJdk)
|
||||
}
|
||||
catch (ex: ExternalSystemJdkException) {
|
||||
return showInvalidSdkItem(selectedJdkReference)
|
||||
return showInvalidSdkItem(jdkReference)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +49,7 @@ private fun SdkComboBox.addAndGetSdkItem(sdk: Sdk): SdkListItem {
|
||||
|
||||
private fun SdkComboBox.findSdkItem(sdk: Sdk): SdkListItem? {
|
||||
return model.listModel.findSdkItem(sdk)
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun resolveJdkReferenceInTests(item: SdkListItem?) = resolveJdkReference(item)
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// Copyright 2000-2019 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.externalSystem.service.ui
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.USE_INTERNAL_JAVA
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.USE_PROJECT_JDK
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkListItem.*
|
||||
|
||||
class ExternalSystemJdkComboBoxUtilTest : ExternalSystemJdkComboBoxUtilTestCase() {
|
||||
fun `test reference usage`() {
|
||||
val sdk1 = createAndRegisterSdk()
|
||||
val sdk2 = createAndRegisterSdk(isProjectSdk = true)
|
||||
val sdk3 = createAndRegisterSdk()
|
||||
val invalidSdk = TestSdkGenerator.createNextSdk()
|
||||
val internalJdk = getInternalJdk()
|
||||
|
||||
val comboBox = createJdkComboBox()
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.reference(USE_PROJECT_JDK)
|
||||
.reference(sdk1)
|
||||
.reference(sdk2)
|
||||
.reference(sdk3)
|
||||
.nothing()
|
||||
|
||||
comboBox.setSelectedJdkReference(USE_PROJECT_JDK)
|
||||
assertComboBoxSelection<ProjectSdkItem>(comboBox, sdk2, USE_PROJECT_JDK)
|
||||
comboBox.setSelectedJdkReference(sdk1.name)
|
||||
assertComboBoxSelection<SdkItem>(comboBox, sdk1, sdk1.name)
|
||||
comboBox.setSelectedJdkReference(sdk2.name)
|
||||
assertComboBoxSelection<SdkItem>(comboBox, sdk2, sdk2.name)
|
||||
comboBox.setSelectedJdkReference(sdk3.name)
|
||||
assertComboBoxSelection<SdkItem>(comboBox, sdk3, sdk3.name)
|
||||
comboBox.setSelectedJdkReference(invalidSdk.name)
|
||||
assertComboBoxSelection<InvalidSdkItem>(comboBox, null, invalidSdk.name)
|
||||
comboBox.setSelectedJdkReference(USE_INTERNAL_JAVA)
|
||||
assertComboBoxSelection<SdkItem>(comboBox, internalJdk, internalJdk.name)
|
||||
comboBox.setSelectedJdkReference(null)
|
||||
assertComboBoxSelection<NoneSdkItem>(comboBox, null, null)
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.reference(null, isSelected = true)
|
||||
.reference(USE_PROJECT_JDK)
|
||||
.reference(invalidSdk.name)
|
||||
.reference(internalJdk)
|
||||
.reference(sdk1)
|
||||
.reference(sdk2)
|
||||
.reference(sdk3)
|
||||
.nothing()
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2000-2019 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.externalSystem.service.ui
|
||||
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkComboBox
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkComboBoxTestCase
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkListItem
|
||||
|
||||
abstract class ExternalSystemJdkComboBoxUtilTestCase : SdkComboBoxTestCase() {
|
||||
|
||||
override fun tearDown() {
|
||||
invokeAndWaitIfNeeded {
|
||||
runWriteAction {
|
||||
JavaAwareProjectJdkTableImpl.removeInternalJdkInTests()
|
||||
}
|
||||
}
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
fun createJdkComboBox() = createComboBox { it is JavaSdkType }
|
||||
|
||||
fun ComboBoxChecker.reference(sdk: Sdk, isSelected: Boolean = false) =
|
||||
reference(sdk.name, isSelected)
|
||||
|
||||
fun ComboBoxChecker.reference(reference: String?, isSelected: Boolean = false) =
|
||||
item<SdkListItem>(isSelected) {
|
||||
assertEquals(reference, resolveJdkReferenceInTests(it))
|
||||
}
|
||||
|
||||
fun getInternalJdk() = JavaAwareProjectJdkTableImpl.getInstanceEx().internalJdk
|
||||
|
||||
inline fun <reified I : SdkListItem> assertComboBoxSelection(comboBox: SdkComboBox, expectedSdk: Sdk?, expectedReference: String?) {
|
||||
assertComboBoxSelection<I>(comboBox, expectedSdk)
|
||||
assertEquals(expectedReference, comboBox.getSelectedJdkReference())
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,21 @@ class SdkComboBox(model: SdkComboBoxModel) : SdkComboBoxBase<SdkListItem>(model.
|
||||
setModel(model.copyAndSetListModel(listModel))
|
||||
}
|
||||
|
||||
override fun getSelectedItem(): SdkListItem? {
|
||||
return super.getSelectedItem() as SdkListItem?
|
||||
}
|
||||
|
||||
override fun setSelectedItem(anObject: Any?) {
|
||||
if (anObject is SdkListItem) {
|
||||
if (myModel.executeAction(this, anObject, ::setSelectedItem)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
when (anObject) {
|
||||
is SdkListItem.ProjectSdkItem -> showProjectSdkItem()
|
||||
is SdkListItem.InvalidSdkItem -> showInvalidSdkItem(anObject.sdkName)
|
||||
is SdkListItem.NoneSdkItem -> showNoneSdkItem()
|
||||
}
|
||||
reloadModel()
|
||||
super.setSelectedItem(anObject)
|
||||
}
|
||||
@@ -37,12 +46,14 @@ class SdkComboBox(model: SdkComboBoxModel) : SdkComboBoxBase<SdkListItem>(model.
|
||||
|
||||
fun getSelectedSdk(): Sdk? {
|
||||
return when (val it = selectedItem) {
|
||||
is SdkListItem.ProjectSdkItem -> model.sdksModel.projectSdk
|
||||
is SdkListItem.SdkItem -> it.sdk
|
||||
is SdkListItem.ProjectSdkItem -> findSdk(model.sdksModel.projectSdk)
|
||||
is SdkListItem.SdkItem -> findSdk(it.sdk)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun findSdk(sdk: Sdk?) = model.sdksModel.findSdk(sdk)
|
||||
|
||||
init {
|
||||
setModel(model)
|
||||
setRenderer(SdkListPresenter { this@SdkComboBox.model.listModel })
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.openapi.roots.ui.configuration;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -58,6 +59,17 @@ public class SdkDetector {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO[jo] fix: deadlock in combobox tests on {@link SdkDetector#myPublicationLock}
|
||||
detection must be called from edt {@link SdkDetector#getDetectedSdksWithUpdate}
|
||||
detection is synchronous for unit tests {@link com.intellij.openapi.progress.impl.CoreProgressManager#run}
|
||||
*/
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (application.isUnitTestMode() || application.isHeadlessEnvironment()) {
|
||||
LOG.warn("Sdks detection is skipped, because deadlock is coming for synchronous detection");
|
||||
return;
|
||||
}
|
||||
|
||||
EdtDetectedSdkListener actualListener = new EdtDetectedSdkListener(callbackModality, listener);
|
||||
synchronized (myPublicationLock) {
|
||||
//skip multiple registrations
|
||||
|
||||
+12
-2
@@ -121,14 +121,14 @@ public abstract class SdkListItem {
|
||||
}
|
||||
}
|
||||
|
||||
enum ActionRole {
|
||||
public enum ActionRole {
|
||||
DOWNLOAD, ADD
|
||||
}
|
||||
|
||||
public static final class ActionItem extends SdkListItem {
|
||||
@Nullable final GroupItem myGroup;
|
||||
@NotNull final ActionRole myRole;
|
||||
@NotNull final NewSdkAction myAction;
|
||||
@NotNull final NewSdkAction myAction;
|
||||
|
||||
ActionItem(@NotNull ActionRole role, @NotNull NewSdkAction action, @Nullable GroupItem group) {
|
||||
myRole = role;
|
||||
@@ -136,6 +136,16 @@ public abstract class SdkListItem {
|
||||
myGroup = group;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ActionRole getRole() {
|
||||
return myRole;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NewSdkAction getAction() {
|
||||
return myAction;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
ActionItem withGroup(@NotNull GroupItem group) {
|
||||
return new ActionItem(myRole, myAction, group);
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// Copyright 2000-2019 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.ui.configuration
|
||||
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
|
||||
class SdkComboBoxTest : SdkComboBoxTestCase() {
|
||||
|
||||
fun `test simple usage`() {
|
||||
val sdk1 = createAndRegisterSdk()
|
||||
val sdk2 = createAndRegisterSdk(isProjectSdk = true)
|
||||
val sdk3 = createAndRegisterSdk()
|
||||
val sdk4 = TestSdkGenerator.createNextSdk()
|
||||
val comboBox = createComboBox()
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.ProjectSdkItem> { assertEquals(sdk2, comboBox.getProjectSdk()) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk3, it) }
|
||||
.nothing()
|
||||
|
||||
assertComboBoxSelection<SdkListItem.NoneSdkItem>(comboBox, null)
|
||||
comboBox.setSelectedSdk(sdk1)
|
||||
assertComboBoxSelection<SdkListItem.SdkItem>(comboBox, sdk1)
|
||||
comboBox.setSelectedSdk(sdk2)
|
||||
assertComboBoxSelection<SdkListItem.SdkItem>(comboBox, sdk2)
|
||||
comboBox.setSelectedSdk(sdk3)
|
||||
assertComboBoxSelection<SdkListItem.SdkItem>(comboBox, sdk3)
|
||||
comboBox.setSelectedSdk(sdk4)
|
||||
assertComboBoxSelection<SdkListItem.InvalidSdkItem>(comboBox, null)
|
||||
comboBox.setSelectedSdk(null)
|
||||
assertComboBoxSelection<SdkListItem.NoneSdkItem>(comboBox, null)
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.NoneSdkItem>(isSelected = true)
|
||||
.item<SdkListItem.ProjectSdkItem> { assertEquals(sdk2, comboBox.getProjectSdk()) }
|
||||
.item<SdkListItem.InvalidSdkItem> { assertEquals(sdk4.name, it.sdkName) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk3, it) }
|
||||
.nothing()
|
||||
|
||||
comboBox.setSelectedItem(SdkListItem.ProjectSdkItem())
|
||||
assertComboBoxSelection<SdkListItem.ProjectSdkItem>(comboBox, sdk2)
|
||||
comboBox.setSelectedItem(SdkListItem.NoneSdkItem())
|
||||
assertComboBoxSelection<SdkListItem.NoneSdkItem>(comboBox, null)
|
||||
comboBox.setSelectedItem(SdkListItem.InvalidSdkItem("invalid sdk"))
|
||||
assertComboBoxSelection<SdkListItem.InvalidSdkItem>(comboBox, null)
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.NoneSdkItem>()
|
||||
.item<SdkListItem.ProjectSdkItem> { assertEquals(sdk2, comboBox.getProjectSdk()) }
|
||||
.item<SdkListItem.InvalidSdkItem>(isSelected = true) { assertEquals("invalid sdk", it.sdkName) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(sdk3, it) }
|
||||
.nothing()
|
||||
}
|
||||
|
||||
fun `test combobox actions`() {
|
||||
val comboBox = createComboBox()
|
||||
.withOpenDropdownPopup()
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.DOWNLOAD, it) }
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.ADD, it) }
|
||||
.nothing()
|
||||
|
||||
val download1 = comboBox.touchDownloadAction()
|
||||
val download2 = comboBox.touchDownloadAction()
|
||||
val download3 = comboBox.touchDownloadAction()
|
||||
val download4 = comboBox.touchDownloadAction()
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download3, it) }
|
||||
.item<SdkListItem.SdkItem>(isSelected = true) { assertSdkItem(download4, it) }
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.DOWNLOAD, it) }
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.ADD, it) }
|
||||
.nothing()
|
||||
|
||||
val add1 = comboBox.touchAddAction()
|
||||
val add2 = comboBox.touchAddAction()
|
||||
val add3 = comboBox.touchAddAction()
|
||||
val add4 = comboBox.touchAddAction()
|
||||
|
||||
assertComboBoxContent(comboBox)
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download3, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(download4, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(add1, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(add2, it) }
|
||||
.item<SdkListItem.SdkItem> { assertSdkItem(add3, it) }
|
||||
.item<SdkListItem.SdkItem>(isSelected = true) { assertSdkItem(add4, it) }
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.DOWNLOAD, it) }
|
||||
.item<SdkListItem.ActionItem> { assertActionItem(SdkListItem.ActionRole.ADD, it) }
|
||||
.nothing()
|
||||
|
||||
assertCollectionContent(comboBox.model.sdksModel.projectSdks.values.sortedBy { it.name })
|
||||
.element<Sdk> { assertSdk(download1, it) }
|
||||
.element<Sdk> { assertSdk(download2, it) }
|
||||
.element<Sdk> { assertSdk(download3, it) }
|
||||
.element<Sdk> { assertSdk(download4, it) }
|
||||
.element<Sdk> { assertSdk(add1, it) }
|
||||
.element<Sdk> { assertSdk(add2, it) }
|
||||
.element<Sdk> { assertSdk(add3, it) }
|
||||
.element<Sdk> { assertSdk(add4, it) }
|
||||
.nothing()
|
||||
|
||||
assertCollectionContent(ProjectJdkTable.getInstance().getSdksOfType(TestSdkType))
|
||||
.nothing()
|
||||
}
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
// Copyright 2000-2019 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.ui.configuration
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.SdkType
|
||||
import com.intellij.openapi.projectRoots.SdkTypeId
|
||||
import com.intellij.openapi.roots.ui.configuration.SdkComboBoxModel.Companion.createSdkComboBoxModel
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import java.util.function.Predicate
|
||||
|
||||
abstract class SdkComboBoxTestCase : SdkTestCase() {
|
||||
|
||||
fun createComboBox(filter: (SdkTypeId) -> Boolean = { true }): SdkComboBox {
|
||||
val sdksModel = TestProjectSdksModel()
|
||||
sdksModel.reset(project)
|
||||
Disposer.register(project, sdksModel)
|
||||
val model = createSdkComboBoxModel(project, sdksModel, Predicate { TestSdkType == it || filter(it) })
|
||||
return SdkComboBox(model)
|
||||
}
|
||||
|
||||
class ComboBoxChecker(val comboBox: SdkComboBox) :
|
||||
CollectionChecker<SdkListItem>(comboBox.itemSequence.iterator(), comboBox.dumpToString()) {
|
||||
|
||||
inline fun <reified I : SdkListItem> item(
|
||||
isSelected: Boolean = false,
|
||||
noinline assertItem: SdkComboBox.(I) -> Unit = {}
|
||||
): ComboBoxChecker {
|
||||
element<I> {
|
||||
assertSelection(comboBox, it, isSelected)
|
||||
comboBox.assertItem(it)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun assertSelection(comboBox: SdkComboBox, elementToCheck: SdkListItem, mustBeSelected: Boolean) {
|
||||
if (mustBeSelected) {
|
||||
val message = "'${comboBox.dumpToString(elementToCheck)}' must be selected"
|
||||
assertTrue(message, comboBox.selectedItem == elementToCheck)
|
||||
}
|
||||
else {
|
||||
val message = "'${comboBox.dumpToString(elementToCheck)}' must not be selected"
|
||||
assertFalse(message, comboBox.selectedItem == elementToCheck)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class CollectionChecker<T : Any>(val iterator: Iterator<T?>, val dump: String) {
|
||||
|
||||
inline fun <reified I : T> element(noinline assertItem: (I) -> Unit = {}): CollectionChecker<T> {
|
||||
assertTrue(dump, iterator.hasNext())
|
||||
val element = iterator.next()
|
||||
val item = assertIsInstance<I>(dump, element)
|
||||
withMessageIfException { assertItem(item) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun nothing() {
|
||||
assertFalse(dump, iterator.hasNext())
|
||||
}
|
||||
|
||||
fun <R> withMessageIfException(action: () -> R): R {
|
||||
try {
|
||||
return action()
|
||||
}
|
||||
catch (ex: Throwable) {
|
||||
System.err.println("${ex::class.java.name}: $dump")
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Works in team with:
|
||||
* [SdkConfigurationUtil.selectSdkHome(SdkType, Component, Consumer<in String>)],
|
||||
* [SdkComboBoxTestCase.TestProjectSdksModel]
|
||||
*/
|
||||
object CanarySdk : TestSdk("canary", "canary-home", "canary-version") {
|
||||
fun <R> replaceByTestSdk(action: () -> R): R {
|
||||
return invokeAndWaitIfNeeded {
|
||||
runWriteAction {
|
||||
val projectSdkTable = ProjectJdkTable.getInstance()
|
||||
projectSdkTable.addJdk(CanarySdk)
|
||||
try {
|
||||
action()
|
||||
}
|
||||
finally {
|
||||
projectSdkTable.removeJdk(CanarySdk)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestProjectSdksModel : ProjectSdksModel(), Disposable {
|
||||
override fun addSdk(type: SdkType, home: String, callback: com.intellij.util.Consumer<in Sdk>?) {
|
||||
if (home == CanarySdk.homePath) {
|
||||
val sdk = TestSdkGenerator.createNextSdk()
|
||||
setupSdk(sdk, callback)
|
||||
}
|
||||
else {
|
||||
super.addSdk(type, home, callback)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSdk(newJdk: TestSdk, callback: com.intellij.util.Consumer<in Sdk>?) {
|
||||
val sdkType = newJdk.sdkType as SdkType
|
||||
if (!sdkType.setupSdkPaths(newJdk, this)) return
|
||||
doAdd(newJdk, callback)
|
||||
}
|
||||
|
||||
override fun reset(project: Project?) {
|
||||
disposeEditableSdks()
|
||||
super.reset(project)
|
||||
}
|
||||
|
||||
override fun dispose() = disposeEditableSdks()
|
||||
|
||||
private fun disposeEditableSdks() {
|
||||
for (editable in projectSdks.values) {
|
||||
if (editable is Disposable) {
|
||||
Disposer.dispose(editable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun assertSdkItem(expected: Sdk, item: SdkListItem.SdkItem) {
|
||||
assertSdk(expected, item.sdk)
|
||||
}
|
||||
|
||||
fun assertActionItem(role: SdkListItem.ActionRole, item: SdkListItem.ActionItem) {
|
||||
assertEquals(role, item.role)
|
||||
assertEquals(TestSdkType, item.action.sdkType)
|
||||
}
|
||||
|
||||
inline fun <reified I : SdkListItem> assertComboBoxSelection(comboBox: SdkComboBox, expectedSdk: Sdk?) {
|
||||
assertEquals(comboBox.dumpToString(), expectedSdk, comboBox.getSelectedSdk())
|
||||
assertIsInstance<I>(comboBox.dumpToString(), comboBox.getSelectedItem())
|
||||
}
|
||||
|
||||
fun assertComboBoxContent(comboBox: SdkComboBox) = ComboBoxChecker(comboBox)
|
||||
|
||||
fun assertCollectionContent(collection: Collection<*>) = CollectionChecker(collection.iterator(), collection.toString())
|
||||
|
||||
inline fun <reified T> assertIsInstance(message: String, o: Any?): T {
|
||||
requireNotNull(o) { message }
|
||||
assertTrue("Expected instance of: ${T::class.java.name} actual: ${o::class.java.name}, $message", o is T)
|
||||
return o as T
|
||||
}
|
||||
|
||||
fun SdkComboBox.getProjectSdk() = model.sdksModel.projectSdk?.let { TestSdkGenerator.findTestSdk(it) }
|
||||
|
||||
val SdkComboBox.itemSequence
|
||||
get() = sequence {
|
||||
val model = getModel()
|
||||
for (i in 0 until model.getSize()) {
|
||||
yield(model.getElementAt(i))
|
||||
}
|
||||
}
|
||||
|
||||
fun SdkComboBox.touchDownloadAction(): TestSdk {
|
||||
selectedItem = itemSequence
|
||||
.filterIsInstance<SdkListItem.ActionItem>()
|
||||
.first { it.role == SdkListItem.ActionRole.DOWNLOAD }
|
||||
return TestSdkGenerator.getCurrentSdk()
|
||||
}
|
||||
|
||||
fun SdkComboBox.touchAddAction(): TestSdk {
|
||||
CanarySdk.replaceByTestSdk {
|
||||
selectedItem = itemSequence
|
||||
.filterIsInstance<SdkListItem.ActionItem>()
|
||||
.first { it.role == SdkListItem.ActionRole.ADD }
|
||||
}
|
||||
return TestSdkGenerator.getCurrentSdk()
|
||||
}
|
||||
|
||||
fun SdkComboBox.withOpenDropdownPopup(): SdkComboBox {
|
||||
firePopupMenuWillBecomeVisible()
|
||||
return this
|
||||
}
|
||||
|
||||
fun SdkComboBox.dumpToString(): String {
|
||||
val elements = itemSequence.joinToString { (if (selectedItem == it) "* " else "") + dumpToString(it) }
|
||||
return "ComboBox { $elements }"
|
||||
}
|
||||
|
||||
fun SdkComboBox.dumpToString(element: SdkListItem?): String {
|
||||
return when (element) {
|
||||
is SdkListItem.NoneSdkItem -> "[none]"
|
||||
is SdkListItem.ProjectSdkItem -> "[project] ${getProjectSdk()?.name}"
|
||||
is SdkListItem.InvalidSdkItem -> "[invalid] ${element.sdkName}"
|
||||
is SdkListItem.SdkItem -> "[sdk] ${element.sdk.name}"
|
||||
is SdkListItem.SuggestedItem -> "[suggested] ${element.homePath}"
|
||||
is SdkListItem.ActionItem -> "[action] ${element.myRole} ${element.myAction.sdkType.name}"
|
||||
is SdkListItem.GroupItem -> "[group] {${element.mySubItems.joinToString { dumpToString(it) }}}"
|
||||
null -> "null"
|
||||
else -> element::class.java.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
// Copyright 2000-2019 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.ui.configuration
|
||||
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.projectRoots.*
|
||||
import com.intellij.openapi.projectRoots.impl.MockSdk
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jdom.Element
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
import javax.swing.JComponent
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
abstract class SdkTestCase : LightPlatformTestCase() {
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
TestSdkGenerator.reset()
|
||||
SdkType.EP_NAME.getPoint(null)
|
||||
.registerExtension(TestSdkType, project)
|
||||
SdkDownload.EP_NAME.getPoint(null)
|
||||
.registerExtension(TestSdkDownloader, project)
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
Disposer.disposeChildren(project)
|
||||
closeAndDeleteProject()
|
||||
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
fun createAndRegisterSdk(isProjectSdk: Boolean = false): Sdk {
|
||||
val sdk = TestSdkGenerator.createNextSdk()
|
||||
registerSdk(sdk)
|
||||
if (isProjectSdk) {
|
||||
setProjectSdk(sdk)
|
||||
}
|
||||
return sdk
|
||||
}
|
||||
|
||||
private fun registerSdk(sdk: Sdk) {
|
||||
invokeAndWaitIfNeeded {
|
||||
runWriteAction {
|
||||
val jdkTable = ProjectJdkTable.getInstance()
|
||||
jdkTable.addJdk(sdk, project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setProjectSdk(sdk: Sdk) {
|
||||
invokeAndWaitIfNeeded {
|
||||
runWriteAction {
|
||||
val rootManager = ProjectRootManager.getInstance(project)
|
||||
rootManager.projectSdk = sdk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TestSdkType : SdkType("test-type"), JavaSdkType {
|
||||
override fun getPresentableName(): String = name
|
||||
override fun isValidSdkHome(path: String?): Boolean = true
|
||||
override fun suggestSdkName(currentSdkName: String?, sdkHome: String?): String = "sdk-name"
|
||||
override fun suggestHomePath(): String? = null
|
||||
override fun createAdditionalDataConfigurable(sdkModel: SdkModel, sdkModificator: SdkModificator): AdditionalDataConfigurable? = null
|
||||
override fun saveAdditionalData(additionalData: SdkAdditionalData, additional: Element) {}
|
||||
override fun getBinPath(sdk: Sdk): String = File(sdk.homePath, "bin").path
|
||||
override fun getToolsPath(sdk: Sdk): String = File(sdk.homePath, "lib/tools.jar").path
|
||||
override fun getVMExecutablePath(sdk: Sdk): String = File(sdk.homePath, "bin/java").path
|
||||
}
|
||||
|
||||
open class TestSdk(name: String, homePath: String, versionString: String)
|
||||
: MockSdk(name, homePath, versionString, MultiMap(), TestSdkType) {
|
||||
override fun getHomePath(): String = super.getHomePath()!!
|
||||
}
|
||||
|
||||
object TestSdkDownloader : SdkDownload {
|
||||
override fun supportsDownload(sdkTypeId: SdkTypeId) = sdkTypeId == TestSdkType
|
||||
|
||||
override fun showDownloadUI(
|
||||
sdkTypeId: SdkTypeId,
|
||||
sdkModel: SdkModel,
|
||||
parentComponent: JComponent,
|
||||
selectedSdk: Sdk?,
|
||||
sdkCreatedCallback: Consumer<SdkDownloadTask>
|
||||
) {
|
||||
val sdk = TestSdkGenerator.createNextSdk()
|
||||
sdkCreatedCallback.accept(object : SdkDownloadTask {
|
||||
override fun doDownload(indicator: ProgressIndicator) {}
|
||||
override fun getPlannedVersion() = sdk.versionString
|
||||
override fun getSuggestedSdkName() = sdk.name
|
||||
override fun getPlannedHomeDir() = sdk.homePath
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
object TestSdkGenerator {
|
||||
private var createdSdkCounter = 0
|
||||
private lateinit var createdSdks: MutableMap<String, TestSdk>
|
||||
|
||||
fun findTestSdk(sdk: Sdk): TestSdk? = createdSdks[sdk.name]
|
||||
|
||||
fun getCurrentSdk() = createdSdks.values.last()
|
||||
|
||||
fun createNextSdk(): TestSdk {
|
||||
val name = "test-name (${createdSdkCounter++})"
|
||||
val versionString = "11"
|
||||
val homePath = FileUtil.getTempDirectory() + "/jdk-$name"
|
||||
generateJdkStructure(homePath, versionString)
|
||||
createdSdks[name] = TestSdk(name, homePath, versionString)
|
||||
return getCurrentSdk()
|
||||
}
|
||||
|
||||
private fun generateJdkStructure(homePath: String, versionString: String) {
|
||||
createFile("$homePath/release")
|
||||
createFile("$homePath/jre/lib/rt.jar")
|
||||
createFile("$homePath/bin/javac")
|
||||
createFile("$homePath/bin/java")
|
||||
val properties = Properties()
|
||||
properties.setProperty("JAVA_FULL_VERSION", versionString)
|
||||
File("$homePath/release").outputStream().use {
|
||||
properties.store(it, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFile(path: String) {
|
||||
val file = File(path)
|
||||
file.parentFile.mkdirs()
|
||||
file.createNewFile()
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
createdSdkCounter = 0
|
||||
createdSdks = LinkedHashMap()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun assertSdk(expected: Sdk, actual: Sdk) {
|
||||
assertEquals(expected.name, actual.name)
|
||||
assertEquals(expected.sdkType, actual.sdkType)
|
||||
assertEquals(expected, TestSdkGenerator.findTestSdk(actual))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user