Skip to content

Commit bae08c4

Browse files
Settings cannot be loaded because of NullPointerException #951 (#952)
1 parent 82f6a19 commit bae08c4

File tree

5 files changed

+83
-35
lines changed

5 files changed

+83
-35
lines changed

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,7 @@ open class TypeParameters(val parameters: List<ClassId> = emptyList())
11081108
class WildcardTypeParameter : TypeParameters(emptyList())
11091109

11101110
interface CodeGenerationSettingItem {
1111+
val id : String
11111112
val displayName: String
11121113
val description: String
11131114
}
@@ -1120,20 +1121,23 @@ interface CodeGenerationSettingBox {
11201121
}
11211122

11221123
enum class MockStrategyApi(
1124+
override val id : String,
11231125
override val displayName: String,
11241126
override val description: String
11251127
) : CodeGenerationSettingItem {
1126-
NO_MOCKS("Do not mock", "Do not use mock frameworks at all"),
1128+
NO_MOCKS("No mocks", "Do not mock", "Do not use mock frameworks at all"),
11271129
OTHER_PACKAGES(
1130+
"Other packages: Mockito",
11281131
"Mock package environment",
11291132
"Mock all classes outside the current package except system ones"
11301133
),
11311134
OTHER_CLASSES(
1135+
"Other classes: Mockito",
11321136
"Mock class environment",
11331137
"Mock all classes outside the class under test except system ones"
11341138
);
11351139

1136-
override fun toString() = displayName
1140+
override fun toString() = id
11371141

11381142
// Get is mandatory because of the initialization order of the inheritors.
11391143
// Otherwise, in some cases we could get an incorrect value
@@ -1144,20 +1148,23 @@ enum class MockStrategyApi(
11441148
}
11451149

11461150
enum class TreatOverflowAsError(
1151+
override val id : String,
11471152
override val displayName: String,
11481153
override val description: String,
11491154
) : CodeGenerationSettingItem {
11501155
AS_ERROR(
1156+
id = "Treat overflows as errors",
11511157
displayName = "Treat overflows as errors",
11521158
description = "Generate tests that treat possible overflows in arithmetic operations as errors " +
11531159
"that throw Arithmetic Exception",
11541160
),
11551161
IGNORE(
1162+
id = "Ignore overflows",
11561163
displayName = "Ignore overflows",
11571164
description = "Ignore possible overflows in arithmetic operations",
11581165
);
11591166

1160-
override fun toString(): String = displayName
1167+
override fun toString(): String = id
11611168

11621169
// Get is mandatory because of the initialization order of the inheritors.
11631170
// Otherwise, in some cases we could get an incorrect value
@@ -1189,13 +1196,14 @@ enum class JavaDocCommentStyle(
11891196
}
11901197

11911198
enum class MockFramework(
1199+
override val id: String = "Mockito",
11921200
override val displayName: String,
11931201
override val description: String = "Use $displayName as mock framework",
11941202
var isInstalled: Boolean = false
11951203
) : CodeGenerationSettingItem {
1196-
MOCKITO("Mockito");
1204+
MOCKITO(displayName = "Mockito");
11971205

1198-
override fun toString() = displayName
1206+
override fun toString() = id
11991207

12001208
companion object : CodeGenerationSettingBox {
12011209
override val defaultItem: MockFramework = MOCKITO
@@ -1204,11 +1212,12 @@ enum class MockFramework(
12041212
}
12051213

12061214
enum class CodegenLanguage(
1215+
override val id: String,
12071216
override val displayName: String,
12081217
@Suppress("unused") override val description: String = "Generate unit tests in $displayName"
12091218
) : CodeGenerationSettingItem {
1210-
JAVA(displayName = "Java"),
1211-
KOTLIN(displayName = "Kotlin (experimental)");
1219+
JAVA(id = "Java", displayName = "Java"),
1220+
KOTLIN(id = "Kotlin", displayName = "Kotlin (experimental)");
12121221

12131222
enum class OperatingSystem {
12141223
WINDOWS,
@@ -1247,7 +1256,7 @@ enum class CodegenLanguage(
12471256
KOTLIN -> listOf(System.getenv("JAVA_HOME"), "bin", "java")
12481257
}.joinToString(File.separator)
12491258

1250-
override fun toString(): String = displayName
1259+
override fun toString(): String = id
12511260

12521261
fun getCompilationCommand(buildDirectory: String, classPath: String, sourcesFiles: List<String>): List<String> {
12531262
val arguments = when (this) {

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/Domain.kt

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ fun testFrameworkByName(testFramework: String): TestFramework =
103103
*/
104104
sealed class StaticsMocking(
105105
var isConfigured: Boolean = false,
106+
override val id: String,
106107
override val displayName: String,
107108
override val description: String = "Use static methods mocking"
108109
) : CodeGenerationSettingItem {
109-
override fun toString(): String = displayName
110+
override fun toString(): String = id
110111

111112
// Get is mandatory because of the initialization order of the inheritors.
112113
// Otherwise, in some cases we could get an incorrect value
@@ -119,11 +120,12 @@ sealed class StaticsMocking(
119120
}
120121

121122
object NoStaticMocking : StaticsMocking(
123+
id = "No static mocking",
122124
displayName = "No static mocking",
123125
description = "Do not use additional settings to mock static fields"
124126
)
125127

126-
object MockitoStaticMocking : StaticsMocking(displayName = "Mockito static mocking") {
128+
object MockitoStaticMocking : StaticsMocking(id = "Mockito static mocking", displayName = "Mockito static mocking") {
127129

128130
val mockedStaticClassId = BuiltinClassId(
129131
name = "org.mockito.MockedStatic",
@@ -170,6 +172,7 @@ object MockitoStaticMocking : StaticsMocking(displayName = "Mockito static mocki
170172
}
171173

172174
sealed class TestFramework(
175+
override val id: String,
173176
override val displayName: String,
174177
override val description: String = "Use $displayName as test framework",
175178
) : CodeGenerationSettingItem {
@@ -235,7 +238,7 @@ sealed class TestFramework(
235238
additionalArguments: List<String>
236239
): List<String>
237240

238-
override fun toString() = displayName
241+
override fun toString() = id
239242

240243
// Get is mandatory because of the initialization order of the inheritors.
241244
// Otherwise, in some cases we could get an incorrect value, i.e. allItems = [null, JUnit5, TestNg]
@@ -246,7 +249,7 @@ sealed class TestFramework(
246249
}
247250
}
248251

249-
object TestNg : TestFramework(displayName = "TestNG") {
252+
object TestNg : TestFramework(id = "TestNG",displayName = "TestNG") {
250253
override val mainPackage: String = TEST_NG_PACKAGE
251254
override val testAnnotation: String = "@$mainPackage.Test"
252255
override val testAnnotationFqn: String = "$mainPackage.Test"
@@ -375,7 +378,7 @@ object TestNg : TestFramework(displayName = "TestNG") {
375378
""".trimIndent()
376379
}
377380

378-
object Junit4 : TestFramework("JUnit4") {
381+
object Junit4 : TestFramework(id = "JUnit4",displayName = "JUnit4") {
379382
private val parametrizedTestsNotSupportedError: Nothing
380383
get() = error("Parametrized tests are not supported for JUnit4")
381384

@@ -448,7 +451,7 @@ object Junit4 : TestFramework("JUnit4") {
448451
}
449452
}
450453

451-
object Junit5 : TestFramework("JUnit5") {
454+
object Junit5 : TestFramework(id = "JUnit5", displayName = "JUnit5") {
452455
override val mainPackage: String = JUNIT5_PACKAGE
453456
override val testAnnotation = "@$mainPackage.Test"
454457
override val testAnnotationFqn: String = "$mainPackage.Test"
@@ -589,20 +592,23 @@ object Junit5 : TestFramework("JUnit5") {
589592
}
590593

591594
enum class RuntimeExceptionTestsBehaviour(
595+
override val id: String,
592596
override val displayName: String,
593597
override val description: String
594598
) : CodeGenerationSettingItem {
595599
PASS(
600+
id = "Passing",
596601
displayName = "Pass",
597602
description = "Tests that produce Runtime exceptions should pass (by inserting throwable assertion)"
598603
),
599604
FAIL(
605+
id = "Failing",
600606
displayName = "Fail",
601607
description = "Tests that produce Runtime exceptions should fail" +
602608
"(WARNING!: failing tests may appear in testing class)"
603609
);
604610

605-
override fun toString(): String = displayName
611+
override fun toString(): String = id
606612

607613
// Get is mandatory because of the initialization order of the inheritors.
608614
// Otherwise, in some cases we could get an incorrect value
@@ -623,11 +629,13 @@ data class HangingTestsTimeout(val timeoutMs: Long) {
623629
}
624630

625631
enum class ForceStaticMocking(
632+
override val id: String,
626633
override val displayName: String,
627634
override val description: String,
628635
val warningMessage: List<String>,
629636
) : CodeGenerationSettingItem {
630637
FORCE(
638+
id = "Force static mocking",
631639
displayName = "Force static mocking",
632640
description = "Use mocks for static methods and constructors invocations even if static mocking is disabled" +
633641
"(WARNING!: can add imports from missing dependencies)",
@@ -638,6 +646,7 @@ enum class ForceStaticMocking(
638646
)
639647
),
640648
DO_NOT_FORCE(
649+
id = "Do not force static mocking",
641650
displayName = "Do not force static mocking",
642651
description = "Do not force static mocking if static mocking setting is disabled" +
643652
"(WARNING!: flaky tests can appear)",
@@ -647,7 +656,7 @@ enum class ForceStaticMocking(
647656
)
648657
);
649658

650-
override fun toString(): String = displayName
659+
override fun toString(): String = id
651660

652661
// Get is mandatory because of the initialization order of the inheritors.
653662
// Otherwise, in some cases we could get an incorrect value
@@ -658,19 +667,22 @@ enum class ForceStaticMocking(
658667
}
659668

660669
enum class ParametrizedTestSource(
670+
override val id: String,
661671
override val displayName: String,
662672
override val description: String = "Use $displayName for parametrized tests"
663673
) : CodeGenerationSettingItem {
664674
DO_NOT_PARAMETRIZE(
675+
id = "Not parametrized",
665676
displayName = "Not parametrized",
666677
description = "Do not generate parametrized tests"
667678
),
668679
PARAMETRIZE(
680+
id = "Parametrized",
669681
displayName = "Parametrized",
670682
description = "Generate parametrized tests"
671683
);
672684

673-
override fun toString(): String = displayName
685+
override fun toString(): String = id
674686

675687
// Get is mandatory because of the initialization order of the inheritors.
676688
// Otherwise, in some cases we could get an incorrect value

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/settings/SettingsWindow.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.utbot.framework.plugin.api.CodeGenerationSettingItem
2525
import org.utbot.framework.plugin.api.CodegenLanguage
2626
import org.utbot.framework.plugin.api.JavaDocCommentStyle
2727
import org.utbot.framework.plugin.api.TreatOverflowAsError
28+
import org.utbot.intellij.plugin.ui.components.CodeGenerationSettingItemRenderer
2829

2930
class SettingsWindow(val project: Project) {
3031
private val settings = project.service<Settings>()
@@ -37,7 +38,7 @@ class SettingsWindow(val project: Project) {
3738
val valuesComboBox: LayoutBuilder.(KClass<*>, Array<*>) -> Unit = { loader, values ->
3839
val serviceLabels = mapOf(
3940
CodegenLanguage::class to "Generated test language:",
40-
RuntimeExceptionTestsBehaviour::class to "Test with exceptions:",
41+
RuntimeExceptionTestsBehaviour::class to "Tests with exceptions:",
4142
TreatOverflowAsError::class to "Overflow detection:",
4243
JavaDocCommentStyle::class to "Javadoc comment style:"
4344
)
@@ -51,7 +52,10 @@ class SettingsWindow(val project: Project) {
5152
DefaultComboBoxModel(values),
5253
getter = { settings.providerNameByServiceLoader(loader) },
5354
setter = { settings.setProviderByLoader(loader, it as CodeGenerationSettingItem) },
54-
).apply { ContextHelpLabel.create(tooltipLabels[loader] ?: return@apply)() }
55+
).apply {
56+
component.renderer = CodeGenerationSettingItemRenderer()
57+
ContextHelpLabel.create(tooltipLabels[loader] ?: return@apply)()
58+
}
5559
}
5660
}
5761
}

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/GenerateTestsDialogWindow.kt

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ import org.utbot.intellij.plugin.models.mockitoCoreLibraryDescriptor
124124
import org.utbot.intellij.plugin.models.packageName
125125
import org.utbot.intellij.plugin.models.testNgLibraryDescriptor
126126
import org.utbot.intellij.plugin.settings.Settings
127+
import org.utbot.intellij.plugin.ui.components.CodeGenerationSettingItemRenderer
127128
import org.utbot.intellij.plugin.ui.components.TestFolderComboWithBrowseButton
128129
import org.utbot.intellij.plugin.ui.utils.LibrarySearchScope
129130
import org.utbot.intellij.plugin.ui.utils.addSourceRootIfAbsent
@@ -168,9 +169,9 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
168169

169170
private val testSourceFolderField = TestFolderComboWithBrowseButton(model)
170171

171-
private val codegenLanguages = ComboBox(DefaultComboBoxModel(CodegenLanguage.values()))
172-
private val testFrameworks = ComboBox(DefaultComboBoxModel(TestFramework.allItems.toTypedArray()))
173-
private val mockStrategies = ComboBox(DefaultComboBoxModel(MockStrategyApi.values()))
172+
private val codegenLanguages = createComboBox(CodegenLanguage.values())
173+
private val testFrameworks = createComboBox(TestFramework.allItems.toTypedArray())
174+
private val mockStrategies = createComboBox(MockStrategyApi.values())
174175
private val staticsMocking = JCheckBox("Mock static methods")
175176
private val timeoutSpinner =
176177
JBIntSpinner(
@@ -191,6 +192,12 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
191192
parametrizedTestSources to null
192193
)
193194

195+
private fun <T : CodeGenerationSettingItem> createComboBox(values: Array<T>) : ComboBox<T> {
196+
return ComboBox<T>(DefaultComboBoxModel(values)).also {
197+
it.renderer = CodeGenerationSettingItemRenderer()
198+
}
199+
}
200+
194201
private fun createHelpLabel(commonTooltip: String? = null) = JBLabel(AllIcons.General.ContextHelp).apply {
195202
if (!commonTooltip.isNullOrEmpty()) toolTipText = commonTooltip
196203
}
@@ -239,22 +246,16 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
239246
row("Test source root:") {
240247
component(testSourceFolderField)
241248
}
242-
row("Code generation language:") {
243-
makePanelWithHelpTooltip(
244-
codegenLanguages as ComboBox<CodeGenerationSettingItem>,
245-
itemsToHelpTooltip[codegenLanguages]
246-
)
247-
}.visible = false
248249
row("Testing framework:") {
249250
makePanelWithHelpTooltip(
250-
testFrameworks as ComboBox<CodeGenerationSettingItem>,
251+
testFrameworks,
251252
null
252253
)
253254
}
254255
row { component(parametrizedTestSources) }
255256
row("Mock strategy:") {
256257
makePanelWithHelpTooltip(
257-
mockStrategies as ComboBox<CodeGenerationSettingItem>,
258+
mockStrategies,
258259
ContextHelpLabel.create("Mock everything around the target class or the whole package except the system classes. Otherwise mock nothing.")
259260
)
260261
}
@@ -957,11 +958,11 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
957958
testFrameworks.item = if (currentFrameworkItem in enabledTestFrameworks) currentFrameworkItem else defaultItem
958959
testFrameworks.renderer = object : ColoredListCellRenderer<TestFramework>() {
959960
override fun customizeCellRenderer(
960-
list: JList<out TestFramework>, value: TestFramework?,
961+
list: JList<out TestFramework>, value: TestFramework,
961962
index: Int, selected: Boolean, hasFocus: Boolean
962963
) {
963-
this.append(value.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES)
964-
if (value == null || !value.isInstalled) {
964+
this.append(value.displayName, SimpleTextAttributes.REGULAR_ATTRIBUTES)
965+
if (!value.isInstalled) {
965966
this.append(WILL_BE_INSTALLED_LABEL, SimpleTextAttributes.ERROR_ATTRIBUTES)
966967
}
967968
}
@@ -982,10 +983,10 @@ class GenerateTestsDialogWindow(val model: GenerateTestsModel) : DialogWrapper(m
982983
private fun updateMockStrategyList() {
983984
mockStrategies.renderer = object : ColoredListCellRenderer<MockStrategyApi>() {
984985
override fun customizeCellRenderer(
985-
list: JList<out MockStrategyApi>, value: MockStrategyApi?,
986+
list: JList<out MockStrategyApi>, value: MockStrategyApi,
986987
index: Int, selected: Boolean, hasFocus: Boolean
987988
) {
988-
this.append(value.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES)
989+
this.append(value.displayName, SimpleTextAttributes.REGULAR_ATTRIBUTES)
989990
if (value != MockStrategyApi.NO_MOCKS && !MOCKITO.isInstalled) {
990991
this.append(WILL_BE_INSTALLED_LABEL, SimpleTextAttributes.ERROR_ATTRIBUTES)
991992
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.utbot.intellij.plugin.ui.components
2+
3+
import java.awt.Component
4+
import javax.swing.DefaultListCellRenderer
5+
import javax.swing.JList
6+
import org.utbot.framework.plugin.api.CodeGenerationSettingItem
7+
8+
internal class CodeGenerationSettingItemRenderer : DefaultListCellRenderer() {
9+
override fun getListCellRendererComponent(
10+
list: JList<*>?,
11+
value: Any?,
12+
index: Int,
13+
isSelected: Boolean,
14+
cellHasFocus: Boolean
15+
): Component {
16+
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus).apply {
17+
if (value is CodeGenerationSettingItem) {
18+
text = value.displayName
19+
}
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)