@@ -6,15 +6,13 @@ import com.intellij.openapi.ui.ComboBox
6
6
import com.intellij.openapi.ui.DialogPanel
7
7
import com.intellij.ui.ContextHelpLabel
8
8
import com.intellij.ui.components.JBLabel
9
- import com.intellij.ui.dsl.builder.Align
10
- import com.intellij.ui.dsl.builder.bindIntValue
11
- import com.intellij.ui.dsl.builder.bindItem
12
- import com.intellij.ui.dsl.builder.bindValue
13
- import com.intellij.ui.dsl.builder.labelTable
14
- import com.intellij.ui.dsl.builder.panel
9
+ import com.intellij.ui.dsl.builder.*
10
+ import com.intellij.ui.layout.selected
15
11
import com.intellij.ui.layout.selectedValueMatches
16
12
import com.intellij.util.ui.UIUtil
17
13
import com.intellij.util.ui.components.BorderLayoutPanel
14
+ import javax.swing.*
15
+ import kotlin.reflect.KClass
18
16
import org.utbot.framework.SummariesGenerationType
19
17
import org.utbot.framework.UtSettings
20
18
import org.utbot.framework.codegen.domain.ForceStaticMocking
@@ -27,10 +25,6 @@ import org.utbot.framework.plugin.api.TreatOverflowAsError
27
25
import org.utbot.framework.plugin.api.isSummarizationCompatible
28
26
import org.utbot.intellij.plugin.ui.components.CodeGenerationSettingItemRenderer
29
27
import org.utbot.intellij.plugin.util.showSettingsEditor
30
- import javax.swing.DefaultComboBoxModel
31
- import javax.swing.JCheckBox
32
- import javax.swing.JPanel
33
- import kotlin.reflect.KClass
34
28
35
29
class SettingsWindow (val project : Project ) {
36
30
private val settings = project.service<Settings >()
@@ -43,89 +37,74 @@ class SettingsWindow(val project: Project) {
43
37
private lateinit var enableSummarizationGenerationCheckBox: JCheckBox
44
38
private lateinit var enableExperimentalLanguagesCheckBox: JCheckBox
45
39
40
+ private fun Row.createCombo (loader : KClass <* >, values : Array <* >) {
41
+ comboBox(DefaultComboBoxModel (values))
42
+ .bindItem(
43
+ getter = { settings.providerNameByServiceLoader(loader) },
44
+ setter = { settings.setProviderByLoader(loader, it as CodeGenerationSettingItem ) },
45
+ ).component.renderer = CodeGenerationSettingItemRenderer ()
46
+ }
47
+
46
48
val panel: JPanel = panel {
47
49
row(" Generated test language:" ) {
48
- codegenLanguageCombo = comboBox(DefaultComboBoxModel (CodegenLanguage .values()))
50
+ codegenLanguageCombo = comboBox(DefaultComboBoxModel (CodegenLanguage .values())).gap( RightGap . COLUMNS )
49
51
.apply {
50
- component.renderer = CodeGenerationSettingItemRenderer ()
51
- ContextHelpLabel .create(" You can generate test methods in Java or Kotlin regardless of your source code language." )
52
- }.bindItem(
53
- getter = { settings.providerNameByServiceLoader(CodegenLanguage ::class ) as CodegenLanguage },
54
- setter = { settings.setProviderByLoader(CodegenLanguage ::class , it as CodeGenerationSettingItem ) }
55
- ).component
52
+ component.renderer = CodeGenerationSettingItemRenderer ()
53
+ ContextHelpLabel .create(" You can generate test methods in Java or Kotlin regardless of your source code language." )
54
+ }.bindItem(
55
+ getter = { settings.providerNameByServiceLoader(CodegenLanguage ::class ) as CodegenLanguage },
56
+ setter = {
57
+ settings.setProviderByLoader(
58
+ CodegenLanguage ::class ,
59
+ it as CodeGenerationSettingItem
60
+ )
61
+ }
62
+ ).component
56
63
codegenLanguageCombo.addActionListener {
57
64
if (! codegenLanguageCombo.item.isSummarizationCompatible()) {
58
65
enableSummarizationGenerationCheckBox.isSelected = false
59
66
}
60
67
}
61
- }
62
- val valuesComboBox: (KClass <* >, Array <* >) -> Unit = { loader, values ->
63
- val serviceLabels = mapOf (
64
- RuntimeExceptionTestsBehaviour ::class to "Tests with exceptions:",
65
- TreatOverflowAsError ::class to "Overflow detection:",
66
- JavaDocCommentStyle ::class to "Javadoc comment style:"
67
- )
68
-
69
- row(serviceLabels[loader] ? : error(" Unknown service loader: $loader " )) {
70
- comboBox(DefaultComboBoxModel (values))
71
- .bindItem(
72
- getter = { settings.providerNameByServiceLoader(loader) },
73
- setter = { settings.setProviderByLoader(loader, it as CodeGenerationSettingItem ) },
74
- ).component.renderer = CodeGenerationSettingItemRenderer ()
75
- }
76
- }
77
-
78
- row(" Hanging test timeout:" ) {
79
- spinner(
80
- range = IntRange (
81
- HangingTestsTimeout .MIN_TIMEOUT_MS .toInt(),
82
- HangingTestsTimeout .MAX_TIMEOUT_MS .toInt()
83
- ),
84
- step = 50
85
- ).bindIntValue(
86
- getter = {
87
- settings.hangingTestsTimeout.timeoutMs
88
- .coerceIn(HangingTestsTimeout .MIN_TIMEOUT_MS , HangingTestsTimeout .MAX_TIMEOUT_MS ).toInt()
89
- },
90
- setter = {
91
- settings.hangingTestsTimeout = HangingTestsTimeout (it.toLong())
92
- }
93
- )
94
68
95
- label(" milliseconds per method" )
96
- contextHelp(
97
- " Set this timeout to define which test is \" hanging\" . Increase it to test the " +
98
- " time-consuming method or decrease if the execution speed is critical for you."
99
- )
100
- }
101
-
102
- mapOf (
103
- RuntimeExceptionTestsBehaviour ::class to RuntimeExceptionTestsBehaviour .values(),
104
- TreatOverflowAsError ::class to TreatOverflowAsError .values(),
105
- JavaDocCommentStyle ::class to JavaDocCommentStyle .values()
106
- ).forEach { (loader, values) ->
107
- valuesComboBox(loader, values)
108
- }
109
-
110
- row {
111
- runInspectionAfterTestGenerationCheckBox = checkBox(" Display detected errors on the Problems tool window" )
69
+ enableExperimentalLanguagesCheckBox = checkBox(" Experimental languages support" )
112
70
.onApply {
113
- settings.state.runInspectionAfterTestGeneration =
114
- runInspectionAfterTestGenerationCheckBox .isSelected
71
+ settings.state.enableExperimentalLanguagesSupport =
72
+ enableExperimentalLanguagesCheckBox .isSelected
115
73
}
116
74
.onReset {
117
- runInspectionAfterTestGenerationCheckBox.isSelected =
118
- settings.state.runInspectionAfterTestGeneration
119
- }
120
- .onIsModified {
121
- runInspectionAfterTestGenerationCheckBox.isSelected xor settings.state.runInspectionAfterTestGeneration
75
+ enableExperimentalLanguagesCheckBox.isSelected =
76
+ settings.experimentalLanguagesSupport == true
122
77
}
78
+ .onIsModified { enableExperimentalLanguagesCheckBox.isSelected xor settings.experimentalLanguagesSupport }
123
79
.component
80
+ contextHelp(" Enable JavaScript and Python if IDE supports them" )
81
+ }.bottomGap(BottomGap .MEDIUM )
82
+
83
+ row(" Tests with exceptions:" ) {
84
+ createCombo(RuntimeExceptionTestsBehaviour ::class , RuntimeExceptionTestsBehaviour .values())
85
+ }
86
+ row(" Overflow detection:" ) {
87
+ createCombo(TreatOverflowAsError ::class , TreatOverflowAsError .values())
88
+ }
89
+ row {
90
+ runInspectionAfterTestGenerationCheckBox =
91
+ checkBox(" Display detected errors on the Problems tool window" )
92
+ .onApply {
93
+ settings.state.runInspectionAfterTestGeneration =
94
+ runInspectionAfterTestGenerationCheckBox.isSelected
95
+ }
96
+ .onReset {
97
+ runInspectionAfterTestGenerationCheckBox.isSelected =
98
+ settings.state.runInspectionAfterTestGeneration
99
+ }
100
+ .onIsModified {
101
+ runInspectionAfterTestGenerationCheckBox.isSelected xor settings.state.runInspectionAfterTestGeneration
102
+ }
103
+ .component
124
104
contextHelp(" Automatically run code inspection after test generation" )
125
105
}
126
-
127
106
row {
128
- enableSummarizationGenerationCheckBox = checkBox(" Enable Summaries Generation " )
107
+ enableSummarizationGenerationCheckBox = checkBox(" Enable summaries generation " )
129
108
.onApply {
130
109
settings.state.summariesGenerationType =
131
110
if (enableSummarizationGenerationCheckBox.isSelected) SummariesGenerationType .FULL else SummariesGenerationType .NONE
@@ -139,7 +118,11 @@ class SettingsWindow(val project: Project) {
139
118
}.enabledIf(codegenLanguageCombo.selectedValueMatches(CodegenLanguage ? ::isSummarizationCompatible))
140
119
.component
141
120
}
142
-
121
+ indent {
122
+ row(" Javadoc comment style:" ) {
123
+ createCombo(JavaDocCommentStyle ::class , JavaDocCommentStyle .values())
124
+ }.enabledIf(enableSummarizationGenerationCheckBox.selected).bottomGap(BottomGap .MEDIUM )
125
+ }
143
126
144
127
row {
145
128
forceMockCheckBox = checkBox(" Force mocking static methods" )
@@ -152,22 +135,6 @@ class SettingsWindow(val project: Project) {
152
135
.component
153
136
contextHelp(" Overrides other mocking settings" )
154
137
}
155
-
156
- row {
157
- enableExperimentalLanguagesCheckBox = checkBox(" Experimental languages support" )
158
- .onApply {
159
- settings.state.enableExperimentalLanguagesSupport =
160
- enableExperimentalLanguagesCheckBox.isSelected
161
- }
162
- .onReset {
163
- enableExperimentalLanguagesCheckBox.isSelected =
164
- settings.experimentalLanguagesSupport == true
165
- }
166
- .onIsModified { enableExperimentalLanguagesCheckBox.isSelected xor settings.experimentalLanguagesSupport }
167
- .component
168
- contextHelp(" Enable JavaScript and Python if IDE supports them" )
169
- }
170
-
171
138
row(" Classes to be forcedly mocked:" ) {}
172
139
row {
173
140
val updater = Runnable {
@@ -183,35 +150,75 @@ class SettingsWindow(val project: Project) {
183
150
.onIsModified { excludeTable.isModified() }
184
151
185
152
forceMockCheckBox.addActionListener { updater.run () }
186
- }
153
+ }.bottomGap( BottomGap . MEDIUM )
187
154
155
+ row(" Hanging test timeout:" ) {
156
+ spinner(
157
+ range = IntRange (
158
+ HangingTestsTimeout .MIN_TIMEOUT_MS .toInt(),
159
+ HangingTestsTimeout .MAX_TIMEOUT_MS .toInt()
160
+ ),
161
+ step = 50
162
+ ).bindIntValue(
163
+ getter = {
164
+ settings.hangingTestsTimeout.timeoutMs
165
+ .coerceIn(HangingTestsTimeout .MIN_TIMEOUT_MS , HangingTestsTimeout .MAX_TIMEOUT_MS ).toInt()
166
+ },
167
+ setter = {
168
+ settings.hangingTestsTimeout = HangingTestsTimeout (it.toLong())
169
+ }
170
+ )
171
+
172
+ label(" milliseconds per method" )
173
+ contextHelp(
174
+ " Set this timeout to define which test is \" hanging\" . Increase it to test the " +
175
+ " time-consuming method or decrease if the execution speed is critical for you."
176
+ )
177
+ }
188
178
val fuzzLabel = JBLabel (" Fuzzing" )
189
179
val symLabel = JBLabel (" Symbolic execution" )
190
- row(" Test generation method:" ) {
191
- val granularity = 20
192
- slider(0 , granularity, 1 , granularity / 4 ).apply {
193
- // clear all labels
194
- labelTable(emptyMap())
195
- }.bindValue(
196
- getter = { ((1 - settings.fuzzingValue) * granularity).toInt() },
197
- setter = { settings.fuzzingValue = 1 - it / granularity.toDouble() }
198
- )
199
- .align(Align .FILL )
200
- .component.apply {
201
- this .toolTipText =
202
- " <html><body>While fuzzer \" guesses\" the values to enter as much execution paths as possible, symbolic executor tries to \" deduce\" them. Choose the proportion of generation time allocated for each of these methods within Test generation timeout. The slide has no effect for Spring Projects.</body></html>"
203
- addChangeListener {
204
- fuzzLabel.text = " Fuzzing " + " %.0f %%" .format(100.0 * (granularity - value) / granularity)
205
- symLabel.text = " %.0f %%" .format(100.0 * value / granularity) + " Symbolic execution"
206
- }
207
- }
208
- }.enabled(UtSettings .useFuzzing)
209
180
row {
210
181
cell(BorderLayoutPanel ().apply {
211
- addToLeft(fuzzLabel)
212
- addToRight(symLabel)
182
+ topGap(TopGap .SMALL )
183
+ addToLeft(JBLabel (" Test generation method:" ).apply { verticalAlignment = SwingConstants .TOP })
184
+ addToCenter(BorderLayoutPanel ().apply {
185
+ val granularity = 20
186
+ val slider = object : JSlider () {
187
+ val updater = Runnable () {
188
+ val fuzzingPercent = 100.0 * (granularity - value) / granularity
189
+ fuzzLabel.text = " Fuzzing %.0f %%" .format(fuzzingPercent)
190
+ symLabel.text = " %.0f %% Symbolic execution" .format(100.0 - fuzzingPercent)
191
+ }
192
+
193
+ override fun getValue () = ((1 - settings.fuzzingValue) * granularity).toInt()
194
+
195
+ override fun setValue (n : Int ) {
196
+ val tmp = value
197
+ settings.fuzzingValue = 1 - n / granularity.toDouble()
198
+ if (tmp != n) {
199
+ updater.run ()
200
+ }
201
+ }
202
+ }
203
+ UIUtil .setSliderIsFilled(slider, true )
204
+ slider.minimum = 0
205
+ slider.maximum = granularity
206
+ slider.minorTickSpacing = 1
207
+ slider.majorTickSpacing = granularity / 4
208
+ slider.paintTicks = true
209
+ slider.paintTrack = true
210
+ slider.paintLabels = false
211
+ slider.toolTipText =
212
+ " <html><body>While fuzzer \" guesses\" the values to enter as much execution paths as possible, symbolic executor tries to \" deduce\" them. Choose the proportion of generation time allocated for each of these methods within Test generation timeout. The slide has no effect for Spring Projects.</body></html>"
213
+ slider.updater.run ()
214
+ addToTop(slider)
215
+ addToBottom(BorderLayoutPanel ().apply {
216
+ addToLeft(fuzzLabel)
217
+ addToRight(symLabel)
218
+ })
219
+ })
213
220
}).align(Align .FILL )
214
- }
221
+ }.enabled( UtSettings .useFuzzing)
215
222
if (! UtSettings .useFuzzing) {
216
223
row {
217
224
comment(" Fuzzing is disabled in configuration file." )
0 commit comments