Skip to content

Commit 3ff2983

Browse files
Merge branch 'main' into Vassiliy-Kudryashov/273-indexnotreadyexception-thrown-in-idea-with-installed-unittestbot-plugin
2 parents ce937cb + a2883ee commit 3ff2983

File tree

59 files changed

+1137
-1213
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1137
-1213
lines changed

.github/ISSUE_TEMPLATE/test_request.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ assignees: ''
1111

1212
*Check that the IntelliJ Idea UTBot plugin can be successfully installed*
1313

14-
- [ ] Choose appropriate workflow from the next list (by default, use the latest one) https://github.com/UnitTestBot/UTBotJava/actions/workflows/publish-plugin-and-cli.yml
14+
- [ ] Choose appropriate workflow from the list (by default, filter by main branch and take the latest one) https://github.com/UnitTestBot/UTBotJava/actions/workflows/publish-plugin-and-cli.yml
15+
- [ ] Download plugin
16+
- [ ] Check downloaded zip-file size < 100 MB
1517
- [ ] Open IntelliJ IDE
1618
- [ ] Remove previously installed UTBot plugin
1719
- [ ] Clone or reuse UTBot project (https://github.com/UnitTestBot/UTBotJava.git)

gradle.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ collections_version=0.3.4
1414
intellij_plugin_version=0.6.4
1515
jacoco_version=0.8.5
1616
commons_lang_version=3.11
17-
commons_io_version=2.8.0
1817
kotlin_logging_version=1.8.3
1918
ktor_version=1.4.1
2019
clikt_version=3.2.0

utbot-core/src/main/kotlin/org/utbot/common/FileUtil.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ object FileUtil {
223223
this.parentFile.mkdirs()
224224
this.createNewFile()
225225
}
226+
227+
// https://stackoverflow.com/a/68822715
228+
fun byteCountToDisplaySize(bytes: Long): String =
229+
when {
230+
bytes >= 1 shl 30 -> "%.1f GB".format(bytes / (1 shl 30))
231+
bytes >= 1 shl 20 -> "%.1f MB".format(bytes / (1 shl 20))
232+
bytes >= 1 shl 10 -> "%.0f kB".format(bytes / (1 shl 10))
233+
else -> "$bytes bytes"
234+
}
226235
}
227236

228237
/**

utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ object UtSettings {
270270
/**
271271
* Fuzzer tries to generate and run tests during this time.
272272
*/
273-
var fuzzingTimeoutInMillis: Int by getIntProperty(3_000)
273+
var fuzzingTimeoutInMillis: Long by getLongProperty(3_000L)
274274

275275
/**
276276
* Generate tests that treat possible overflows in arithmetic operations as errors

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,13 @@ val Type.classId: ClassId
610610
* [elementClassId] if this class id represents an array class, then this property
611611
* represents the class id of the array's elements. Otherwise, this property is null.
612612
*/
613-
open class ClassId(
613+
open class ClassId @JvmOverloads constructor(
614614
val name: String,
615-
val elementClassId: ClassId? = null
615+
val elementClassId: ClassId? = null,
616+
// Treat simple class ids as non-nullable
617+
open val isNullable: Boolean = false
616618
) {
619+
617620
open val canonicalName: String
618621
get() = jClass.canonicalName ?: error("ClassId $name does not have canonical name")
619622

@@ -677,10 +680,6 @@ open class ClassId(
677680
open val isSynthetic: Boolean
678681
get() = jClass.isSynthetic
679682

680-
open val isNullable: Boolean
681-
// Treat simple class ids as non-nullable
682-
get() = false
683-
684683
/**
685684
* Collects all declared methods (including private and protected) from class and all its superclasses to sequence
686685
*/
@@ -755,6 +754,7 @@ class BuiltinClassId(
755754
override val simpleName: String,
756755
// by default we assume that the class is not a member class
757756
override val simpleNameWithEnclosings: String = simpleName,
757+
override val isNullable: Boolean = false,
758758
override val isPublic: Boolean = true,
759759
override val isProtected: Boolean = false,
760760
override val isPrivate: Boolean = false,
@@ -774,7 +774,7 @@ class BuiltinClassId(
774774
-1, 0 -> ""
775775
else -> canonicalName.substring(0, index)
776776
},
777-
) : ClassId(name) {
777+
) : ClassId(name = name, isNullable = isNullable) {
778778
init {
779779
BUILTIN_CLASSES_BY_NAMES[name] = this
780780
}
@@ -1081,7 +1081,7 @@ enum class CodegenLanguage(
10811081
@Suppress("unused") override val description: String = "Generate unit tests in $displayName"
10821082
) : CodeGenerationSettingItem {
10831083
JAVA(displayName = "Java"),
1084-
KOTLIN(displayName = "Kotlin");
1084+
KOTLIN(displayName = "Kotlin (experimental)");
10851085

10861086
enum class OperatingSystem {
10871087
WINDOWS,

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,21 @@ val idToPrimitive: Map<ClassId, Class<*>> = mapOf(
236236
*/
237237
fun isPrimitiveWrapperOrString(type: ClassId): Boolean = (type in primitiveWrappers) || (type == stringClassId)
238238

239+
/**
240+
* Returns a wrapper of a given type if it is primitive or a type itself otherwise.
241+
*/
242+
fun wrapIfPrimitive(type: ClassId): ClassId = when (type) {
243+
booleanClassId -> booleanWrapperClassId
244+
byteClassId -> byteWrapperClassId
245+
charClassId -> charWrapperClassId
246+
shortClassId -> shortWrapperClassId
247+
intClassId -> intWrapperClassId
248+
longClassId -> longWrapperClassId
249+
floatClassId -> floatWrapperClassId
250+
doubleClassId -> doubleWrapperClassId
251+
else -> type
252+
}
253+
239254
/**
240255
* Note: currently uses class$innerClass form to load classes with classloader.
241256
*/

utbot-framework/build.gradle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,12 @@ dependencies {
3737
testImplementation project(':utbot-analytics')
3838

3939
// used for testing code generation
40-
testImplementation group: 'commons-io', name: 'commons-io', version: commons_io_version
4140
testImplementation group: 'junit', name: 'junit', version: junit4_version
4241
testImplementation group: 'org.junit.platform', name: 'junit-platform-console-standalone', version: junit4_platform_version
4342
testImplementation group: 'org.mockito', name: 'mockito-core', version: mockito_version
4443
testImplementation group: 'org.testng', name: 'testng', version: testng_version
4544
testImplementation group: 'org.mockito', name: 'mockito-inline', version: mockito_inline_version
4645

47-
testCompile group: 'org.mockito', name: 'mockito-inline', version: mockito_inline_version
48-
testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4j2_version
49-
5046
z3native group: 'com.microsoft.z3', name: 'z3-native-win64', version: z3_version, ext: 'zip'
5147
z3native group: 'com.microsoft.z3', name: 'z3-native-linux64', version: z3_version, ext: 'zip'
5248
z3native group: 'com.microsoft.z3', name: 'z3-native-osx', version: z3_version, ext: 'zip'

utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class UtBotSymbolicEngine(
180180

181181
fun attachMockListener(mockListener: MockListener) = mocker.mockListenerController?.attach(mockListener)
182182

183+
fun detachMockListener(mockListener: MockListener) = mocker.mockListenerController?.detach(mockListener)
184+
183185
private val statesForConcreteExecution: MutableList<ExecutionState> = mutableListOf()
184186

185187
private val traverser = Traverser(
@@ -435,7 +437,7 @@ class UtBotSymbolicEngine(
435437
})
436438
}
437439
fuzzedValues.forEach { values ->
438-
if (System.currentTimeMillis() >= until) {
440+
if (controller.job?.isActive == false || System.currentTimeMillis() >= until) {
439441
logger.info { "Fuzzing overtime: $methodUnderTest" }
440442
return@flow
441443
}

utbot-framework/src/main/kotlin/org/utbot/engine/selectors/strategies/GraphViz.kt

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
package org.utbot.engine.selectors.strategies
22

3+
import mu.KotlinLogging
4+
import org.utbot.common.FileUtil.createNewFileWithParentDirectories
35
import org.utbot.engine.CALL_DECISION_NUM
46
import org.utbot.engine.Edge
57
import org.utbot.engine.ExecutionState
68
import org.utbot.engine.InterProceduralUnitGraph
9+
import org.utbot.engine.isLibraryNonOverriddenClass
710
import org.utbot.engine.isReturn
811
import org.utbot.engine.selectors.PathSelector
912
import org.utbot.engine.stmts
1013
import org.utbot.framework.UtSettings.copyVisualizationPathToClipboard
14+
import soot.jimple.Stmt
15+
import soot.toolkits.graph.ExceptionalUnitGraph
1116
import java.awt.Toolkit
1217
import java.awt.datatransfer.StringSelection
1318
import java.io.FileWriter
1419
import java.nio.file.Files
1520
import java.nio.file.Paths
16-
import mu.KotlinLogging
17-
import org.apache.commons.io.FileUtils
18-
import org.utbot.engine.isLibraryNonOverriddenClass
19-
import org.utbot.engine.isOverridden
20-
import soot.jimple.Stmt
21-
import soot.toolkits.graph.ExceptionalUnitGraph
2221

2322
private val logger = KotlinLogging.logger {}
2423

@@ -51,10 +50,17 @@ class GraphViz(
5150
val classLoader = GraphViz::class.java.classLoader
5251

5352
for (file in requiredFileNames) {
54-
FileUtils.copyInputStreamToFile(
55-
classLoader.getResourceAsStream("html/$file"),
56-
Paths.get(graphVisDirectory.toString(), file).toFile()
57-
)
53+
classLoader.getResourceAsStream("html/$file").use { inputStream ->
54+
val path = Paths.get(graphVisDirectory.toString(), file)
55+
val targetFile = path.toFile()
56+
targetFile.createNewFileWithParentDirectories()
57+
58+
targetFile.outputStream().use { targetOutputStream ->
59+
inputStream?.copyTo(targetOutputStream) ?: logger.error {
60+
"Could not start a visualization because of missing resource html/$file"
61+
}
62+
}
63+
}
5864
}
5965
FileWriter(graphJs).use {
6066
it.write(

utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceMockListener.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.utbot.engine.util.mockListeners
22
import org.utbot.engine.EngineController
33
import org.utbot.engine.MockStrategy
44
import org.utbot.engine.UtMockInfo
5+
import org.utbot.framework.plugin.api.TestCaseGenerator
56
import org.utbot.framework.util.Conflict
67
import org.utbot.framework.util.ConflictTriggers
78

@@ -18,4 +19,13 @@ class ForceMockListener(triggers: ConflictTriggers): MockListener(triggers) {
1819

1920
triggers[Conflict.ForceMockHappened] = true
2021
}
22+
23+
companion object {
24+
fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers) : ForceMockListener {
25+
val listener = ForceMockListener(conflictTriggers)
26+
testCaseGenerator.engineActions.add { engine -> engine.attachMockListener(listener) }
27+
28+
return listener
29+
}
30+
}
2131
}

utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceStaticMockListener.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.utbot.engine.UtMockInfo
66
import org.utbot.engine.UtNewInstanceMockInfo
77
import org.utbot.engine.UtStaticMethodMockInfo
88
import org.utbot.engine.UtStaticObjectMockInfo
9+
import org.utbot.framework.plugin.api.TestCaseGenerator
910
import org.utbot.framework.util.Conflict
1011
import org.utbot.framework.util.ConflictTriggers
1112

@@ -26,4 +27,13 @@ class ForceStaticMockListener(triggers: ConflictTriggers): MockListener(triggers
2627
triggers[Conflict.ForceStaticMockHappened] = true
2728
}
2829
}
30+
31+
companion object {
32+
fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers) : ForceStaticMockListener {
33+
val listener = ForceStaticMockListener(conflictTriggers)
34+
testCaseGenerator.engineActions.add { engine -> engine.attachMockListener(listener) }
35+
36+
return listener
37+
}
38+
}
2939
}

utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/MockListener.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.engine.util.mockListeners
33
import org.utbot.engine.EngineController
44
import org.utbot.engine.MockStrategy
55
import org.utbot.engine.UtMockInfo
6+
import org.utbot.framework.plugin.api.TestCaseGenerator
67
import org.utbot.framework.util.ConflictTriggers
78

89
/**
@@ -12,4 +13,8 @@ abstract class MockListener(
1213
val triggers: ConflictTriggers
1314
) {
1415
abstract fun onShouldMock(controller: EngineController, strategy: MockStrategy, mockInfo: UtMockInfo)
16+
17+
fun detach(testCaseGenerator: TestCaseGenerator, listener: MockListener) {
18+
testCaseGenerator.engineActions.add { engine -> engine.detachMockListener(listener) }
19+
}
1520
}

utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/MockListenerController.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class MockListenerController(private val controller: EngineController) {
1414
listeners += listener
1515
}
1616

17+
fun detach(listener: MockListener) {
18+
listeners -= listener
19+
}
20+
1721
fun onShouldMock(strategy: MockStrategy, mockInfo: UtMockInfo) {
1822
listeners.map { it.onShouldMock(controller, strategy, mockInfo) }
1923
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.utbot.framework.assemble
2+
3+
import org.utbot.framework.plugin.api.UtAssembleModel
4+
import org.utbot.framework.plugin.api.UtExecutableCallModel
5+
import org.utbot.framework.plugin.api.UtPrimitiveModel
6+
import org.utbot.framework.plugin.api.util.booleanClassId
7+
import org.utbot.framework.plugin.api.util.byteClassId
8+
import org.utbot.framework.plugin.api.util.charClassId
9+
import org.utbot.framework.plugin.api.util.doubleClassId
10+
import org.utbot.framework.plugin.api.util.executableId
11+
import org.utbot.framework.plugin.api.util.floatClassId
12+
import org.utbot.framework.plugin.api.util.intClassId
13+
import org.utbot.framework.plugin.api.util.longClassId
14+
import org.utbot.framework.plugin.api.util.shortClassId
15+
import org.utbot.framework.plugin.api.util.wrapIfPrimitive
16+
17+
/**
18+
* Creates [UtAssembleModel] of the wrapper for a given [UtPrimitiveModel].
19+
*/
20+
fun assemble(model: UtPrimitiveModel): UtAssembleModel {
21+
val modelType = model.classId
22+
val assembledModelType = wrapIfPrimitive(modelType)
23+
24+
val constructorCall = when (modelType) {
25+
shortClassId -> java.lang.Short::class.java.getConstructor(Short::class.java)
26+
intClassId -> java.lang.Integer::class.java.getConstructor(Int::class.java)
27+
longClassId -> java.lang.Long::class.java.getConstructor(Long::class.java)
28+
charClassId -> java.lang.Character::class.java.getConstructor(Char::class.java)
29+
byteClassId -> java.lang.Byte::class.java.getConstructor(Byte::class.java)
30+
booleanClassId -> java.lang.Boolean::class.java.getConstructor(Boolean::class.java)
31+
floatClassId -> java.lang.Float::class.java.getConstructor(Float::class.java)
32+
doubleClassId -> java.lang.Double::class.java.getConstructor(Double::class.java)
33+
else -> error("Model type $modelType is void or non-primitive")
34+
}
35+
36+
val constructorCallModel = UtExecutableCallModel(
37+
instance = null,
38+
executable = constructorCall.executableId,
39+
params = listOf(model),
40+
returnValue = null,
41+
)
42+
43+
return UtAssembleModel(
44+
id = null,
45+
classId = assembledModelType,
46+
modelName = modelType.canonicalName,
47+
instantiationChain = listOf(constructorCallModel),
48+
modificationsChain = emptyList(),
49+
)
50+
}

0 commit comments

Comments
 (0)