Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Clarify some ObjectValueProvider entities
  • Loading branch information
Markoutte committed Dec 12, 2022
commit 3897c5ec0ee1be9e9f7fdfac3328677a68fab6a8
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.utbot.fuzzer.IdentityPreservingIdGenerator
import org.utbot.fuzzer.objects.FuzzerMockableMethodId
import org.utbot.fuzzer.objects.assembleModel
import org.utbot.fuzzing.providers.FieldDescription
import org.utbot.fuzzing.providers.findSuitableFields
import org.utbot.fuzzing.providers.findAccessibleModifableFields
import org.utbot.fuzzing.providers.isAccessible

/**
Expand Down Expand Up @@ -64,7 +64,7 @@ class ObjectModelProvider(
// and mutate some fields. Only if there's no option next block
// with empty constructor should be used.
if (constructorId.parameters.isEmpty()) {
val fields = findSuitableFields(constructorId.classId, description.packageName)
val fields = findAccessibleModifableFields(constructorId.classId, description.packageName)
if (fields.isNotEmpty()) {
yield(
ModelConstructor(fields.map { FuzzedType(it.classId) }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,67 +23,22 @@ class ObjectValueProvider(
NumberValueProvider.classId
)

override fun accept(type: FuzzedType) = !shouldPass(type.classId)
override fun accept(type: FuzzedType) = !isIgnored(type.classId)

override fun generate(
description: FuzzedDescription,
type: FuzzedType
) = sequence {
val classId = type.classId
// this adds mock support, but we should discuss first if mock is really needed
// if (description.description.shouldMock(classId)) {
// yield(createMock(classId, description))
// } else {
// prefer constructors without recursion call, but use them if no other options
val constructors = findTypesOfNonRecursiveConstructor(type, description.description.packageName)
.takeIf { it.isNotEmpty() }
?.asSequence()
?: classId.allConstructors.filter {
isAccessible(it.constructor, description.description.packageName)
}
constructors.forEach { constructorId ->
yield(createValue(classId, constructorId, description))
}
// }
}

@Suppress("unused")
private fun createMock(classId: ClassId, description: FuzzedDescription): Seed.Recursive<FuzzedType, FuzzedValue> {
return Seed.Recursive(
construct = Routine.Create(emptyList()) {
UtCompositeModel(
id = idGenerator.createId(),
classId = classId,
isMock = true,
).fuzzed {
summary = "%var% = mock"
}
},
modify = sequence {
findSuitableFields(classId, description.description.packageName).forEach { fd ->
when {
fd.canBeSetDirectly -> {
yield(Routine.Call(listOf(FuzzedType(fd.classId))) { self, values ->
val model = self.model as UtCompositeModel
model.fields[FieldId(classId, fd.name)] = values.first().model
})
}

fd.setter != null && fd.getter != null -> {
yield(Routine.Call(listOf(FuzzedType(fd.classId))) { self, values ->
val model = self.model as UtCompositeModel
model.mocks[fd.getter.executableId] = values.map { it.model }
})
}
}
}
},
empty = Routine.Empty {
UtNullModel(classId).fuzzed {
summary = "%var% = null"
}
val constructors = findTypesOfNonRecursiveConstructor(type, description.description.packageName)
.takeIf { it.isNotEmpty() }
?.asSequence()
?: classId.allConstructors.filter {
isAccessible(it.constructor, description.description.packageName)
}
)
constructors.forEach { constructorId ->
yield(createValue(classId, constructorId, description))
}
}

private fun createValue(classId: ClassId, constructorId: ConstructorId, description: FuzzedDescription): Seed.Recursive<FuzzedType, FuzzedValue> {
Expand All @@ -104,7 +59,7 @@ class ObjectValueProvider(
}
},
modify = sequence {
findSuitableFields(classId, description.description.packageName).forEach { fd ->
findAccessibleModifableFields(classId, description.description.packageName).forEach { fd ->
when {
fd.canBeSetDirectly -> {
yield(Routine.Call(listOf(FuzzedType(fd.classId))) { self, values ->
Expand Down Expand Up @@ -137,8 +92,9 @@ class ObjectValueProvider(
)
}

private fun shouldPass(type: ClassId): Boolean {
private fun isIgnored(type: ClassId): Boolean {
return unwantedConstructorsClasses.contains(type)
|| type.isIterableOrMap
|| type.isPrimitiveWrapper
|| type.isEnum
|| type.isAbstract
Expand Down Expand Up @@ -193,7 +149,7 @@ internal class FieldDescription(
val getter: Method?
)

internal fun findSuitableFields(classId: ClassId, packageName: String?): List<FieldDescription> {
internal fun findAccessibleModifableFields(classId: ClassId, packageName: String?): List<FieldDescription> {
val jClass = classId.jClass
return jClass.declaredFields.map { field ->
val setterAndGetter = jClass.findPublicSetterGetterIfHasPublicGetter(field, packageName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,20 @@ public boolean testTreeSetWithComparable(NavigableSet<Integer> set) {
return false;
}

public static class ConcreteList<T> extends LinkedList<T> {}
public static class ConcreteList<T extends Number> extends LinkedList<T> {
public boolean equals(Collection<T> collection) {
if (collection.size() != size()) {
return false;
}
int i = 0;
for (T t : collection) {
if (!java.util.Objects.equals(get(i), t)) {
return false;
}
}
return true;
}
}

/**
* Should create concrete class
Expand Down