From 398edf1d1eeeab891e15cbbe151f04db60161ff5 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Tue, 22 Nov 2022 15:23:01 +0300 Subject: [PATCH] Enum classes are instantiated correctly if some methods are overriden --- .../utbot/examples/enums/ComplexEnumExamplesTest.kt | 2 -- .../framework/codegen/tree/CgStatementConstructor.kt | 10 +++++++--- .../framework/codegen/tree/CgVariableConstructor.kt | 12 ++++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/enums/ComplexEnumExamplesTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/enums/ComplexEnumExamplesTest.kt index b4d969962e..a3c02068b8 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/enums/ComplexEnumExamplesTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/enums/ComplexEnumExamplesTest.kt @@ -1,6 +1,5 @@ package org.utbot.examples.enums -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.utbot.examples.enums.ComplexEnumExamples.Color import org.utbot.examples.enums.ComplexEnumExamples.Color.BLUE @@ -75,7 +74,6 @@ class ComplexEnumExamplesTest : UtValueTestCaseChecker( } @Test - @Disabled("TODO: nested anonymous classes are not supported: https://github.com/UnitTestBot/UTBotJava/issues/617") fun testFindState() { check( ComplexEnumExamples::findState, diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt index b1de9332d0..adb4fba2cb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgStatementConstructor.kt @@ -63,6 +63,8 @@ import org.utbot.framework.plugin.api.util.fieldClassId import org.utbot.framework.plugin.api.util.isPrimitive import org.utbot.framework.plugin.api.util.methodClassId import org.utbot.framework.plugin.api.util.denotableType +import org.utbot.framework.plugin.api.util.id +import org.utbot.framework.plugin.api.util.isEnum import org.utbot.framework.plugin.api.util.supertypeOfAnonymousClass import java.lang.reflect.Constructor import java.lang.reflect.Method @@ -500,11 +502,13 @@ internal class CgStatementConstructorImpl(context: CgContext) : } private fun guardEnumConstantAccess(access: CgEnumConstantAccess): ExpressionWithType { - val (enumClass, constant) = access + val (enumAccessClass, constant) = access - return if (enumClass.isAccessibleFrom(testClassPackageName)) { - ExpressionWithType(enumClass, access) + return if (enumAccessClass.isAccessibleFrom(testClassPackageName)) { + ExpressionWithType(enumAccessClass, access) } else { + val enumClass: ClassId = + if (enumAccessClass.isEnum) enumAccessClass else enumAccessClass.outerClass!!.id val enumClassVariable = newVar(classCgClassId) { classClassId[forName](enumClass.name) } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt index 26d008efa3..21d02a838c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt @@ -58,6 +58,7 @@ import org.utbot.framework.plugin.api.util.findFieldByIdOrNull import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.intClassId import org.utbot.framework.plugin.api.util.isArray +import org.utbot.framework.plugin.api.util.isEnum import org.utbot.framework.plugin.api.util.isPrimitiveWrapperOrString import org.utbot.framework.plugin.api.util.isStatic import org.utbot.framework.plugin.api.util.stringClassId @@ -445,8 +446,15 @@ open class CgVariableConstructor(val context: CgContext) : } private fun constructEnumConstant(model: UtEnumConstantModel, baseName: String?): CgVariable { - return newVar(model.classId, baseName) { - CgEnumConstantAccess(model.classId, model.value.name) + val classId = model.classId + + require(classId.isEnum || + classId.isAnonymous && classId.outerClass?.isEnum == true) { + "Enum constant model $model should be a enum or an anonymous class that overrides enum methods" + } + + return newVar(classId, baseName) { + CgEnumConstantAccess(classId, model.value.name) } }