From fda8e9febfc072f0f14d1aa702c3135eb881229d Mon Sep 17 00:00:00 2001 From: Alexey Menshutin Date: Thu, 15 Dec 2022 13:34:51 +0800 Subject: [PATCH] Add disjunction with null condition to isMock constraint --- .../examples/mock/CommonMocksExampleTest.kt | 10 ++++++++ .../main/kotlin/org/utbot/engine/Traverser.kt | 25 +++++++++++++------ .../examples/mock/CommonMocksExample.java | 9 +++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt index 74054cfe05..9dc536f2e6 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt @@ -56,4 +56,14 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common coverage = DoNotCalculate ) } + + @Test + fun testMocksForNullOfDifferentTypes() { + check( + CommonMocksExample::mocksForNullOfDifferentTypes, + eq(1), + mockStrategy = MockStrategyApi.OTHER_PACKAGES, + coverage = DoNotCalculate + ) + } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt index d51af92ab4..631167f3fe 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt @@ -1249,6 +1249,8 @@ class Traverser( ): ObjectValue { touchAddress(addr) + val nullEqualityConstraint = mkEq(addr, nullObjectAddr) + if (mockInfoGenerator != null) { val mockInfo = mockInfoGenerator.generate(addr) @@ -1260,8 +1262,11 @@ class Traverser( queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo))) // add typeConstraint for mocked object. It's a declared type of the object. - queuedSymbolicStateUpdates += typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all().asHardConstraint() - queuedSymbolicStateUpdates += mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue).asHardConstraint() + val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all() + val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue) + + queuedSymbolicStateUpdates += typeConstraint.asHardConstraint() + queuedSymbolicStateUpdates += mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint() return mockedObject } @@ -1286,8 +1291,10 @@ class Traverser( typeStoragePossiblyWithOverriddenTypes } + val typeHardConstraint = typeRegistry.typeConstraint(addr, typeStorage).all().asHardConstraint() + wrapper(type, addr)?.let { - queuedSymbolicStateUpdates += typeRegistry.typeConstraint(addr, typeStorage).all().asHardConstraint() + queuedSymbolicStateUpdates += typeHardConstraint return it } @@ -1303,8 +1310,11 @@ class Traverser( queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo))) // add typeConstraint for mocked object. It's a declared type of the object. - queuedSymbolicStateUpdates += typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all().asHardConstraint() - queuedSymbolicStateUpdates += mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue).asHardConstraint() + val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all() + val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue) + + queuedSymbolicStateUpdates += typeConstraint.asHardConstraint() + queuedSymbolicStateUpdates += mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint() return mockedObject } @@ -1313,9 +1323,10 @@ class Traverser( // We should create an object with typeStorage of all possible real types and concrete implementation // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'. val concreteImplementation = wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete + val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse) - queuedSymbolicStateUpdates += typeRegistry.typeConstraint(addr, typeStorage).all().asHardConstraint() - queuedSymbolicStateUpdates += mkEq(typeRegistry.isMock(addr), UtFalse).asHardConstraint() + queuedSymbolicStateUpdates += typeHardConstraint + queuedSymbolicStateUpdates += mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint() return ObjectValue(typeStorage, addr, concreteImplementation) } diff --git a/utbot-sample/src/main/java/org/utbot/examples/mock/CommonMocksExample.java b/utbot-sample/src/main/java/org/utbot/examples/mock/CommonMocksExample.java index 873ea187d2..d65209b356 100644 --- a/utbot-sample/src/main/java/org/utbot/examples/mock/CommonMocksExample.java +++ b/utbot-sample/src/main/java/org/utbot/examples/mock/CommonMocksExample.java @@ -1,5 +1,7 @@ package org.utbot.examples.mock; +import org.utbot.api.mock.UtMock; +import org.utbot.examples.mock.others.Random; import org.utbot.examples.mock.service.impl.ExampleClass; import org.utbot.examples.objects.ObjectWithFinalStatic; import org.utbot.examples.objects.RecursiveTypeClass; @@ -35,4 +37,11 @@ public int clinitMockExample() { return -ObjectWithFinalStatic.keyValue; } } + + public int mocksForNullOfDifferentTypes(Integer intValue, Random random) { + UtMock.assume(intValue == null); + UtMock.assume(random == null); + + return 0; + } }