Skip to content

Primitive stream wrappers #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions utbot-api/src/main/java/org/utbot/api/mock/UtMock.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ public static void assumeOrExecuteConcretely(boolean predicate) {
// In oppose to assume, we don't have predicate check here
// to avoid RuntimeException during concrete execution
}

@SuppressWarnings("unused")
public static void disableClassCastExceptionCheck(Object object) {}
}
6 changes: 3 additions & 3 deletions utbot-core/src/main/kotlin/org/utbot/common/FileUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ object FileUtil {
// https://stackoverflow.com/a/68822715
fun byteCountToDisplaySize(bytes: Long): String =
when {
bytes >= 1 shl 30 -> "%.1f GB".format(bytes / (1 shl 30))
bytes >= 1 shl 20 -> "%.1f MB".format(bytes / (1 shl 20))
bytes >= 1 shl 10 -> "%.0f kB".format(bytes / (1 shl 10))
bytes >= 1 shl 30 -> "%.1f GB".format(bytes.toDouble() / (1 shl 30))
bytes >= 1 shl 20 -> "%.1f MB".format(bytes.toDouble() / (1 shl 20))
bytes >= 1 shl 10 -> "%.0f kB".format(bytes.toDouble() / (1 shl 10))
else -> "$bytes bytes"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.utbot.framework.plugin.api.util.method
import org.utbot.framework.plugin.api.util.primitiveTypeJvmNameOrNull
import org.utbot.framework.plugin.api.util.safeJField
import org.utbot.framework.plugin.api.util.shortClassId
import org.utbot.framework.plugin.api.util.supertypeOfAnonymousClass
import org.utbot.framework.plugin.api.util.toReferenceTypeBytecodeSignature
import org.utbot.framework.plugin.api.util.voidClassId
import soot.ArrayType
Expand Down Expand Up @@ -697,8 +698,14 @@ open class ClassId @JvmOverloads constructor(
*/
val prettifiedName: String
get() {
val className = jClass.canonicalName ?: name // Explicit jClass reference to get null instead of exception
return className
val baseName = when {
// anonymous classes have empty simpleName and their canonicalName is null,
// so we create a specific name for them
isAnonymous -> "Anonymous${supertypeOfAnonymousClass.prettifiedName}"
// in other cases where canonical name is still null, we use ClassId.name instead
else -> jClass.canonicalName ?: name // Explicit jClass reference to get null instead of exception
}
return baseName
.substringAfterLast(".")
.replace(Regex("[^a-zA-Z0-9]"), "")
.let { if (this.isArray) it + "Array" else it }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,34 @@ infix fun ClassId.isSubtypeOf(type: ClassId): Boolean {

infix fun ClassId.isNotSubtypeOf(type: ClassId): Boolean = !(this isSubtypeOf type)

/**
* - Anonymous class that extends a class will have this class as its superclass and no interfaces.
* - Anonymous class that implements an interface, will have the only interface
* and [java.lang.Object] as its superclass.
*
* @return [ClassId] of a type that the given anonymous class inherits
*/
val ClassId.supertypeOfAnonymousClass: ClassId
get() {
if (this is BuiltinClassId) error("Cannot obtain info about supertypes of BuiltinClassId $canonicalName")
if (!isAnonymous) error("An anonymous class expected, but got $canonicalName")

val clazz = jClass
val superclass = clazz.superclass.id
val interfaces = clazz.interfaces.map { it.id }

return when {
// anonymous class actually inherits from Object, e.g. Object obj = new Object() { ... };
superclass == objectClassId && interfaces.isEmpty() -> objectClassId
// anonymous class implements some interface
superclass == objectClassId -> {
interfaces.singleOrNull() ?: error("Anonymous class can have no more than one interface")
}
// anonymous class inherits from some class other than java.lang.Object
else -> superclass
}
}

val ClassId.kClass: KClass<*>
get() = jClass.kotlin

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,13 @@ inline fun <reified T> withoutSandbox(block: () -> T): T {
UtSettings.disableSandbox = prev
}
}

inline fun <reified T> withPathSelectorStepsLimit(stepsLimit: Int, block: () -> T): T {
val prev = UtSettings.pathSelectorStepsLimit
UtSettings.pathSelectorStepsLimit = stepsLimit
try {
return block()
} finally {
UtSettings.pathSelectorStepsLimit = prev
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.utbot.tests.infrastructure.isException
import org.utbot.framework.plugin.api.CodegenLanguage
import org.utbot.testcheckers.eq
import org.utbot.testcheckers.withoutConcrete
import org.utbot.tests.infrastructure.AtLeast
import org.utbot.tests.infrastructure.CodeGeneration
import java.util.Optional
import java.util.stream.Stream
Expand All @@ -28,6 +29,7 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
CodeGenerationLanguageLastStage(CodegenLanguage.KOTLIN, CodeGeneration)
)
) {
@Disabled("TODO enable after anonymous function support")
@Test
fun testReturningStreamExample() {
withoutConcrete {
Expand All @@ -42,6 +44,7 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
}
}

@Disabled("TODO enable after anonymous function support")
@Test
fun testReturningStreamAsParameterExample() {
withoutConcrete {
Expand Down Expand Up @@ -69,10 +72,49 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
fun testMapExample() {
checkWithException(
BaseStreamExample::mapExample,
eq(2),
{ c, r -> null in c && r.isException<NullPointerException>() },
{ c, r -> r.getOrThrow().contentEquals(c.map { it * 2 }.toTypedArray()) },
coverage = DoNotCalculate
ignoreExecutionsNumber,
{ c, r -> (null in c && r.isException<NullPointerException>()) || r.getOrThrow().contentEquals(c.map { it * 2 }.toTypedArray()) },
// { c, r -> r.getOrThrow().contentEquals(c.map { it * 2 }.toTypedArray()) },
coverage = AtLeast(90)
)
}

@Test
fun testMapToIntExample() {
checkWithException(
BaseStreamExample::mapToIntExample,
ignoreExecutionsNumber,
{ c, r ->
(null in c && r.isException<NullPointerException>()) ||
r.getOrThrow().contentEquals(c.map { it.toInt() }.toIntArray())
},
coverage = AtLeast(90)
)
}

@Test
fun testMapToLongExample() {
checkWithException(
BaseStreamExample::mapToLongExample,
ignoreExecutionsNumber,
{ c, r ->
(null in c && r.isException<NullPointerException>()) ||
r.getOrThrow().contentEquals(c.map { it.toLong() }.toLongArray())
},
coverage = AtLeast(90)
)
}

@Test
fun testMapToDoubleExample() {
checkWithException(
BaseStreamExample::mapToDoubleExample,
ignoreExecutionsNumber,
{ c, r ->
(null in c && r.isException<NullPointerException>()) ||
r.getOrThrow().contentEquals(c.map { it.toDouble() }.toDoubleArray())
},
coverage = AtLeast(90)
)
}

Expand All @@ -87,7 +129,36 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
}

@Test
@Disabled("Java 11 transition -- Yura looks at this. We have similar issue with Strings")
fun testFlatMapToIntExample() {
check(
BaseStreamExample::flatMapToIntExample,
ignoreExecutionsNumber,
{ c, r -> r.contentEquals(c.flatMap { listOf(it?.toInt() ?: 0, it?.toInt() ?: 0) }.toIntArray()) },
coverage = FullWithAssumptions(assumeCallsNumber = 1)
)
}

@Test
fun testFlatMapToLongExample() {
check(
BaseStreamExample::flatMapToLongExample,
ignoreExecutionsNumber,
{ c, r -> r.contentEquals(c.flatMap { listOf(it?.toLong() ?: 0L, it?.toLong() ?: 0L) }.toLongArray()) },
coverage = FullWithAssumptions(assumeCallsNumber = 1)
)
}

@Test
fun testFlatMapToDoubleExample() {
check(
BaseStreamExample::flatMapToDoubleExample,
ignoreExecutionsNumber,
{ c, r -> r.contentEquals(c.flatMap { listOf(it?.toDouble() ?: 0.0, it?.toDouble() ?: 0.0) }.toDoubleArray()) },
coverage = FullWithAssumptions(assumeCallsNumber = 1)
)
}

@Test
fun testDistinctExample() {
check(
BaseStreamExample::distinctExample,
Expand Down Expand Up @@ -146,17 +217,17 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
fun testForEachExample() {
checkThisAndStaticsAfter(
BaseStreamExample::forEachExample,
eq(2),
ignoreExecutionsNumber,
*streamConsumerStaticsMatchers,
coverage = DoNotCalculate
coverage = AtLeast(92)
)
}

@Test
fun testToArrayExample() {
check(
BaseStreamExample::toArrayExample,
ignoreExecutionsNumber,
eq(2),
{ c, r -> c.toTypedArray().contentEquals(r) },
coverage = FullWithAssumptions(assumeCallsNumber = 1)
)
Expand Down Expand Up @@ -311,10 +382,11 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
fun testIteratorExample() {
checkWithException(
BaseStreamExample::iteratorSumExample,
eq(2),
ignoreExecutionsNumber,
{ c, r -> c.isEmpty() && r.getOrThrow() == 0 },
{ c, r -> null in c && r.isException<NullPointerException>() },
{ c, r -> null !in c && r.getOrThrow() == c.sum() },
coverage = DoNotCalculate
{ c, r -> c.isNotEmpty() && null !in c && r.getOrThrow() == c.sum() },
coverage = AtLeast(75)
)
}

Expand All @@ -325,7 +397,7 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
BaseStreamExample::streamOfExample,
ignoreExecutionsNumber,
// NOTE: the order of the matchers is important because Stream could be used only once
{ c, r -> c.isNotEmpty() && c.contentEquals(r!!.toArray()) },
{ c, r -> c.isNotEmpty() && !Stream.empty<Int>().toArray().contentEquals(r!!.toArray()) },
{ c, r -> c.isEmpty() && Stream.empty<Int>().toArray().contentEquals(r!!.toArray()) },
coverage = FullWithAssumptions(assumeCallsNumber = 1)
)
Expand Down Expand Up @@ -395,14 +467,24 @@ class BaseStreamExampleTest : UtValueTestCaseChecker(
)
}

private val streamConsumerStaticsMatchers = arrayOf(
{ _: BaseStreamExample, c: List<Int?>, _: StaticsType, _: Int? -> null in c },
{ _: BaseStreamExample, c: List<Int?>, statics: StaticsType, r: Int? ->
val x = statics.values.single().value as Int

r!! + c.sumOf { it ?: 0 } == x
}
)
@Test
fun testSourceCollectionMutationExample() {
check(
BaseStreamExample::sourceCollectionMutationExample,
eq(1),
{ r -> r == true },
coverage = AtLeast(97)
)
}
}

private fun <E : Comparable<E>> Sequence<E>.isSorted(): Boolean = zipWithNext { a, b -> a <= b }.all { it }
internal val streamConsumerStaticsMatchers = arrayOf(
{ _: Any, c: List<Int?>, _: StaticsType, _: Int? -> null in c },
{ _: Any, c: List<Int?>, statics: StaticsType, r: Int? ->
val x = statics.values.single().value as Int

r!! + c.sumOf { it ?: 0 } == x
}
)

internal fun <E : Comparable<E>> Sequence<E>.isSorted(): Boolean = zipWithNext { a, b -> a <= b }.all { it }
Loading