diff --git a/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaBuilderTestRenderer.kt b/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaBuilderTestRenderer.kt new file mode 100644 index 000000000..f44d42212 --- /dev/null +++ b/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaBuilderTestRenderer.kt @@ -0,0 +1,134 @@ +package io.vrap.codegen.languages.javalang.client.builder.test + +import io.vrap.codegen.languages.extensions.deprecated +import io.vrap.codegen.languages.extensions.isPatternProperty +import io.vrap.codegen.languages.java.base.extensions.* +import io.vrap.rmf.codegen.di.AllObjectTypes +import io.vrap.rmf.codegen.firstLowerCase + +import io.vrap.rmf.codegen.io.TemplateFile +import io.vrap.rmf.codegen.rendering.FileProducer +import io.vrap.rmf.codegen.rendering.ObjectTypeRenderer +import io.vrap.rmf.codegen.rendering.utils.* +import io.vrap.rmf.codegen.types.VrapEnumType +import io.vrap.rmf.codegen.types.VrapObjectType +import io.vrap.rmf.codegen.types.VrapTypeProvider +import io.vrap.rmf.raml.model.types.* +import javax.lang.model.SourceVersion +import kotlin.random.Random + +class JavaBuilderTestRenderer constructor(override val vrapTypeProvider: VrapTypeProvider, @AllObjectTypes private val allObjectTypes: List): FileProducer, JavaEObjectTypeExtensions, JavaObjectTypeExtensions { + + override fun produceFiles(): List { + return allObjectTypes.filter { !it.isAbstract() && !it.deprecated() }.map { render(it) } + } + + fun render(type: ObjectType): TemplateFile { + val vrapType = vrapTypeProvider.doSwitch(type).toJavaVType() as VrapObjectType + + val properties = type.properties.filterNot { it.deprecated() || it.isPatternProperty() || it.name == type.discriminator() } + val content = """ + |package ${vrapType.`package`}; + | + |import com.tngtech.junit.dataprovider.DataProvider; + |import com.tngtech.junit.dataprovider.DataProviderExtension; + |import com.tngtech.junit.dataprovider.UseDataProvider; + |import com.tngtech.junit.dataprovider.UseDataProviderExtension; + |import org.assertj.core.api.Assertions; + |import org.junit.jupiter.api.Test; + |import org.junit.jupiter.api.TestTemplate; + |import org.junit.jupiter.api.extension.ExtendWith; + | + |import java.time.LocalDate; + |import java.time.LocalTime; + |import java.time.ZonedDateTime; + |import java.util.Collections; + | + |@ExtendWith(UseDataProviderExtension.class) + |@ExtendWith(DataProviderExtension.class) + |public class ${vrapType.simpleClassName}Test { + | ${if (properties.isNotEmpty()) """ + | @TestTemplate + | @UseDataProvider("objectBuilder") + | public void buildUnchecked(${vrapType.simpleClassName}Builder builder) { + | ${vrapType.simpleClassName} ${vrapType.simpleClassName.firstLowerCase()} = builder.buildUnchecked(); + | Assertions.assertThat(${vrapType.simpleClassName.firstLowerCase()}).isInstanceOf(${vrapType.simpleClassName}.class); + | } + | + | @DataProvider + | public static Object[][] objectBuilder() { + | return new Object[][] { + | <<${properties.joinToString(",\n") { "new Object[] { ${builder(type, it)} }" }}>> + | }; + | } + | + | <<${properties.joinToString("\n") { getterSetterTest(type, it) }}>>""" else ""} + |} + """.trimMargin().keepAngleIndent() + + return TemplateFile( + relativePath = "${vrapType.`package`}.${vrapType.simpleClassName}Test".replace(".", "/") + ".java", + content = content + ) + } + + private fun builder(type: ObjectType, property: Property): String { + var propertyName = property.name + val checkedPropertyType = property.type + val vrapType = vrapTypeProvider.doSwitch(type).toJavaVType() as VrapObjectType + if(SourceVersion.isKeyword(propertyName)) { + propertyName = "_$propertyName" + } + + return "${vrapType.simpleClassName}.builder().${propertyName}(${propertyValue(propertyName, checkedPropertyType, Random(propertyName.hashCode()))})" + } + + private fun getterSetterTest(type: ObjectType, property: Property): String { + val vrapType = vrapTypeProvider.doSwitch(type).toJavaVType() as VrapObjectType + var methodName = property.name.lowerCamelCase() + if(SourceVersion.isKeyword(methodName)) { + methodName = "_$methodName" + } + val propertyValue = propertyValue(property.name, property.type, Random(property.name.hashCode())) + return """ + |@Test + |public void ${methodName}() { + | ${vrapType.simpleClassName} value = ${vrapType.simpleClassName}.of(); + | value.set${property.name.upperCamelCase()}($propertyValue); + | Assertions.assertThat(value.get${property.name.upperCamelCase()}()).isEqualTo($propertyValue); + |} + """.trimMargin() + } + + private fun propertyValue(name: String, type: AnyType, r: Random) : Any { + val vrapType = type.toVrapType(); + + val checkedType = if (type.isInlineType) type.type else type + return when (type) { + is ArrayType -> "Collections.singletonList(${propertyValue(name, type.items, r)})" + is BooleanType -> true + is IntegerType -> when (type.format) { + NumberFormat.INT64 -> "${r.nextInt(1, 10)}L" + else -> r.nextInt(1, 10) + } + is NumberType -> when (type.format) { + NumberFormat.DOUBLE -> r.nextDouble() + NumberFormat.FLOAT -> r.nextFloat() + NumberFormat.INT64 -> "${r.nextInt(1, 10)}L" + else -> r.nextInt(1, 10) + } + is StringType -> when (vrapType) { + is VrapEnumType -> "${vrapType.fullClassName()}.findEnum(\"${checkedType.enum.firstOrNull()?.value ?: name}\")" + else -> "\"${name}\"" + } + is ObjectType -> when(vrapType.fullClassName()) { + "java.lang.Object" -> "\"${name}\"" + else -> "new ${vrapType.fullClassName()}Impl()" + } + is DateOnlyType -> "LocalDate.parse(\"2023-06-01\")" + is TimeOnlyType -> "LocalTime.parse(\"12:00\")" + is DateTimeType -> "ZonedDateTime.parse(\"2023-06-01T12:00Z\")" + else -> "\"${name}\"" + } + } +} diff --git a/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaTestModule.kt b/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaTestModule.kt index 18a8f491b..f90b87b3c 100644 --- a/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaTestModule.kt +++ b/languages/javalang/builder-renderer/java-builder-client/src/main/kotlin/io/vrap/codegen/languages/javalang/client/builder/test/JavaTestModule.kt @@ -12,6 +12,11 @@ object JavaTestModule: Module { setOf( JavaRequestTestRenderer(generatorModule.vrapTypeProvider()) ), generatorModule.allResources().filterNot { it.deprecated() } + ), + FileGenerator( + setOf( + JavaBuilderTestRenderer(generatorModule.vrapTypeProvider(), generatorModule.allObjectTypes()) + ) ) ) } diff --git a/languages/javalang/builder-renderer/java-builder-client/src/test/kotlin/io/vrap/codegen/languages/javalang/client/builder/BuilderTestCodeGenerator.kt b/languages/javalang/builder-renderer/java-builder-client/src/test/kotlin/io/vrap/codegen/languages/javalang/client/builder/BuilderTestCodeGenerator.kt index ef25b816a..290e09c5e 100644 --- a/languages/javalang/builder-renderer/java-builder-client/src/test/kotlin/io/vrap/codegen/languages/javalang/client/builder/BuilderTestCodeGenerator.kt +++ b/languages/javalang/builder-renderer/java-builder-client/src/test/kotlin/io/vrap/codegen/languages/javalang/client/builder/BuilderTestCodeGenerator.kt @@ -40,7 +40,7 @@ class BuilderTestCodeGenerator { private val apiPath : Path = Paths.get(if (userProvidedPath == null) "../../../../api-spec/api.raml" else userProvidedPath) private val importApiPath : Path = Paths.get(if (importApiProvidedPath == null) "../../../../api-spec/api.raml" else importApiProvidedPath) private val outputFolder : Path = Paths.get(if (generatedCodePath == null) "build/gensrc/main/java-generated" else generatedCodePath) - private val testOutputFolder : Path = Paths.get(if (generatedCodePath == null) "build/gensrc/test/java-generated" else generatedTestCodePath) + private val testOutputFolder : Path = Paths.get(if (generatedTestCodePath == null) "build/gensrc/test/java-generated" else generatedTestCodePath) private val predicateOutputFolder : Path = Paths.get(if (generatedPredicateCodePath == null) "build/gensrc/main/java-predicates-generated" else generatedPredicateCodePath) val apiProvider: RamlApiProvider = RamlApiProvider(apiPath)