From 667806cccd89b474744ad400473dcf642734fddc Mon Sep 17 00:00:00 2001 From: Thijs Koppen Date: Mon, 6 Nov 2023 21:39:51 +0100 Subject: [PATCH] Add unit tests for processor create...() functions --- .../processor/PanacheEntityBaseProcessor.kt | 10 +- .../processor/PanacheCompanionBaseTests.kt | 94 ++++++++++++++----- .../icken/processor/PanacheEntityBaseTests.kt | 88 +++++++++++++---- .../kotlin/ch/icken/processor/TestCommon.kt | 4 + 4 files changed, 153 insertions(+), 43 deletions(-) diff --git a/library/src/main/kotlin/ch/icken/processor/PanacheEntityBaseProcessor.kt b/library/src/main/kotlin/ch/icken/processor/PanacheEntityBaseProcessor.kt index d911a0f..11e98c0 100644 --- a/library/src/main/kotlin/ch/icken/processor/PanacheEntityBaseProcessor.kt +++ b/library/src/main/kotlin/ch/icken/processor/PanacheEntityBaseProcessor.kt @@ -84,19 +84,19 @@ class PanacheEntityBaseProcessor( primaryConstructor(constructorBuilder.build()) // Generate properties - ksProperties.forEach { ksPropertyDeclaration -> - val propertyName = ksPropertyDeclaration.simpleName.asString() - val isJoinColumn = ksPropertyDeclaration.hasAnnotation(JakartaPersistenceJoinColumn) + ksProperties.forEach { ksProperty -> + val propertyName = ksProperty.simpleName.asString() + val isJoinColumn = ksProperty.hasAnnotation(JakartaPersistenceJoinColumn) val propertyBuilder = if (isJoinColumn) { - val joinObjectName = ksPropertyDeclaration.typeName + COLUMN_NAME_OBJECT_SUFFIX + val joinObjectName = ksProperty.typeName + COLUMN_NAME_OBJECT_SUFFIX val joinBaseClassName = joinObjectName + COLUMN_NAME_BASE_CLASS_SUFFIX val joinBaseClass = ClassName(packageName, joinBaseClassName) PropertySpec.builder(propertyName, joinBaseClass) .initializer("%T(%S)", joinBaseClass, "$propertyName.") } else { - val ksPropertyType = ksPropertyDeclaration.type.resolve() + val ksPropertyType = ksProperty.type.resolve() val columnNameParameterType = ksPropertyType.toClassName() .copy(nullable = ksPropertyType.isMarkedNullable) diff --git a/library/src/test/kotlin/ch/icken/processor/PanacheCompanionBaseTests.kt b/library/src/test/kotlin/ch/icken/processor/PanacheCompanionBaseTests.kt index be01850..41484a7 100644 --- a/library/src/test/kotlin/ch/icken/processor/PanacheCompanionBaseTests.kt +++ b/library/src/test/kotlin/ch/icken/processor/PanacheCompanionBaseTests.kt @@ -16,22 +16,23 @@ package ch.icken.processor +import ch.icken.processor.ClassNames.LongClassName import ch.icken.processor.GenerationOptions.ADD_GENERATED_ANNOTATION import ch.icken.processor.QualifiedNames.HibernatePanacheCompanionBase import ch.icken.processor.QualifiedNames.HibernatePanacheEntityBase import ch.icken.processor.QualifiedNames.JakartaPersistenceEntity +import ch.icken.processor.QualifiedNames.JakartaPersistenceId import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.KSFunctionDeclaration -import com.google.devtools.ksp.symbol.KSName +import com.google.devtools.ksp.symbol.* import com.google.devtools.ksp.validate +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.ksp.toClassName import io.mockk.* import io.mockk.impl.annotations.MockK import io.mockk.junit5.MockKExtension import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -41,16 +42,14 @@ class PanacheCompanionBaseTests : TestCommon() { @MockK private lateinit var resolver: Resolver - private lateinit var processor: PanacheCompanionBaseProcessor - - @BeforeEach - fun beforeEach() { - processor = spyk(PanacheCompanionBaseProcessor( - options = mapOf(ADD_GENERATED_ANNOTATION to "false"), - codeGenerator = mockk(), - logger = mockk() - )) - } + private val codeGenerator = mockk(relaxed = true) + private val processor = spyk(PanacheCompanionBaseProcessor( + options = mapOf(ADD_GENERATED_ANNOTATION to "false"), + codeGenerator = codeGenerator, + logger = mockk().also { + every { it.info(any()) } just Runs + } + )) //region process @Test @@ -111,7 +110,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -133,7 +134,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -154,7 +157,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -173,7 +178,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -191,7 +198,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -208,7 +217,9 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -225,8 +236,49 @@ class PanacheCompanionBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createQueryBuilderExtensions(any(), any(), any()) } + verify(exactly = 0) { + processor.createQueryBuilderExtensions(any(), any(), any()) + } assertEquals(1, invalid.size) } //endregion + + //region createQueryBuilderExtensions + @Test + fun testCreateQueryBuilderExtensions() { + + // Given + val packageName = "ch.icken.model" + val simpleName = "Employee" + val className = ClassName(packageName, simpleName) + + val classSimpleName = mockk() + every { classSimpleName.asString() } returns simpleName + + val idPropertyType = mockk() + every { idPropertyType.toClassName() } returns LongClassName + + val idPropertyTypeReference = mockk() + every { idPropertyTypeReference.resolve() } returns idPropertyType + + val idProperty = mockk() + every { idProperty.hasAnnotation(eq(JakartaPersistenceId)) } returns true + every { idProperty.type } returns idPropertyTypeReference + + val ksClass = mockk() + every { ksClass.toClassName() } returns className + every { ksClass.simpleName } returns classSimpleName + every { ksClass.getAllProperties() } returns sequenceOf(idProperty) + + val ksClasses = listOf(ksClass) + + // When + processor.createQueryBuilderExtensions(packageName, ksClasses, false) + + // Then + verify(exactly = 1) { + codeGenerator.createNewFile(any(), any(), any()) + } + } + //endregion } diff --git a/library/src/test/kotlin/ch/icken/processor/PanacheEntityBaseTests.kt b/library/src/test/kotlin/ch/icken/processor/PanacheEntityBaseTests.kt index 3ce7265..72b4a58 100644 --- a/library/src/test/kotlin/ch/icken/processor/PanacheEntityBaseTests.kt +++ b/library/src/test/kotlin/ch/icken/processor/PanacheEntityBaseTests.kt @@ -16,6 +16,7 @@ package ch.icken.processor +import ch.icken.processor.ClassNames.StringClassName import ch.icken.processor.GenerationOptions.ADD_GENERATED_ANNOTATION import ch.icken.processor.QualifiedNames.HibernatePanacheEntityBase import ch.icken.processor.QualifiedNames.JakartaPersistenceColumn @@ -24,15 +25,13 @@ import ch.icken.processor.QualifiedNames.JakartaPersistenceJoinColumn import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.KSFunctionDeclaration -import com.google.devtools.ksp.symbol.KSPropertyDeclaration +import com.google.devtools.ksp.symbol.* import com.google.devtools.ksp.validate +import com.squareup.kotlinpoet.ksp.toClassName import io.mockk.* import io.mockk.impl.annotations.MockK import io.mockk.junit5.MockKExtension import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -42,16 +41,14 @@ class PanacheEntityBaseTests : TestCommon() { @MockK private lateinit var resolver: Resolver - private lateinit var processor: PanacheEntityBaseProcessor - - @BeforeEach - fun beforeEach() { - processor = spyk(PanacheEntityBaseProcessor( - options = mapOf(ADD_GENERATED_ANNOTATION to "false"), - codeGenerator = mockk(), - logger = mockk() - )) - } + private val codeGenerator = mockk(relaxed = true) + private val processor = spyk(PanacheEntityBaseProcessor( + options = mapOf(ADD_GENERATED_ANNOTATION to "false"), + codeGenerator = codeGenerator, + logger = mockk().also { + every { it.info(any()) } just Runs + } + )) //region process @Test @@ -193,7 +190,9 @@ class PanacheEntityBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createColumnNamesObject(any(), any(), any()) } + verify(exactly = 0) { + processor.createColumnNamesObject(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -210,7 +209,9 @@ class PanacheEntityBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createColumnNamesObject(any(), any(), any()) } + verify(exactly = 0) { + processor.createColumnNamesObject(any(), any(), any()) + } assertEquals(0, invalid.size) } @@ -227,8 +228,61 @@ class PanacheEntityBaseTests : TestCommon() { val invalid = processor.process(resolver) // Then - verify(exactly = 0) { processor.createColumnNamesObject(any(), any(), any()) } + verify(exactly = 0) { + processor.createColumnNamesObject(any(), any(), any()) + } assertEquals(1, invalid.size) } //endregion + + //region createColumnNamesObject + @Test + fun testCreateColumnNamesObject() { + + // Given + val packageName = "ch.icken.model" + val classPackageName = mockk() + every { classPackageName.asString() } returns packageName + + val classSimpleName = mockk() + every { classSimpleName.asString() } returns "Employee" + + val ksClass = mockk() + every { ksClass.packageName } returns classPackageName + every { ksClass.simpleName } returns classSimpleName + + val firstNameSimpleName = mockk() + every { firstNameSimpleName.asString() } returns "firstName" + + val firstNameType = mockk() + every { firstNameType.toClassName() } returns StringClassName + every { firstNameType.isMarkedNullable } returns false + + val firstNameTypeReference = mockk() + every { firstNameTypeReference.resolve() } returns firstNameType + + val firstName = mockk() + every { firstName.simpleName } returns firstNameSimpleName + every { firstName.hasAnnotation(eq(JakartaPersistenceJoinColumn)) } returns false + every { firstName.type } returns firstNameTypeReference + + val departmentSimpleName = mockk() + every { departmentSimpleName.asString() } returns "department" + + val department = mockk() + every { department.simpleName } returns departmentSimpleName + every { department.hasAnnotation(eq(JakartaPersistenceJoinColumn)) } returns true + every { department.typeName } returns "Department" + + val ksProperties = listOf(firstName, department) + + // When + processor.createColumnNamesObject(ksClass, ksProperties, true) + + // Then + verify(exactly = 1) { + codeGenerator.createNewFile(any(), any(), any()) + } + } + //endregion } diff --git a/library/src/test/kotlin/ch/icken/processor/TestCommon.kt b/library/src/test/kotlin/ch/icken/processor/TestCommon.kt index dd88a18..e6de818 100644 --- a/library/src/test/kotlin/ch/icken/processor/TestCommon.kt +++ b/library/src/test/kotlin/ch/icken/processor/TestCommon.kt @@ -18,6 +18,7 @@ package ch.icken.processor import com.google.devtools.ksp.symbol.* import com.google.devtools.ksp.validate +import com.squareup.kotlinpoet.ksp.toClassName import io.mockk.mockkStatic import org.junit.jupiter.api.BeforeAll @@ -29,8 +30,11 @@ abstract class TestCommon { mockkStatic(KSAnnotated::hasAnnotation) mockkStatic(KSAnnotation::isClass) mockkStatic(KSClassDeclaration::isSubclass) + mockkStatic(KSClassDeclaration::toClassName) mockkStatic(KSDeclaration::isClass) mockkStatic(KSNode::validate) + mockkStatic(KSPropertyDeclaration::typeName) + mockkStatic(KSType::toClassName) } } }