diff --git a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt index 3516e12..8a956ba 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt @@ -17,14 +17,14 @@ internal sealed class BoundParameterForMap { abstract fun map(src: S): Any? - private class Plain( + internal class Plain( override val name: String, override val propertyGetter: Method ) : BoundParameterForMap() { override fun map(src: S): Any? = propertyGetter.invoke(src) } - private class UseConverter( + internal class UseConverter( override val name: String, override val propertyGetter: Method, private val converter: KFunction<*> @@ -32,36 +32,36 @@ internal sealed class BoundParameterForMap { override fun map(src: S): Any? = converter.call(propertyGetter.invoke(src)) } - private class UseKMapper( + internal class UseKMapper( override val name: String, override val propertyGetter: Method, private val kMapper: KMapper<*> ) : BoundParameterForMap() { // 1引数で呼び出すとMap/Pairが適切に処理されないため、2引数目にダミーを噛ませている - override fun map(src: S): Any? = kMapper.map(propertyGetter.invoke(src), PARAMETER_DUMMY) + override fun map(src: S): Any? = propertyGetter.invoke(src)?.let { kMapper.map(it, PARAMETER_DUMMY) } } - private class UseBoundKMapper( + internal class UseBoundKMapper( override val name: String, override val propertyGetter: Method, private val boundKMapper: BoundKMapper ) : BoundParameterForMap() { - override fun map(src: S): Any? = boundKMapper.map(propertyGetter.invoke(src) as T) + override fun map(src: S): Any? = (propertyGetter.invoke(src))?.let { boundKMapper.map(it as T) } } - private class ToEnum( + internal class ToEnum( override val name: String, override val propertyGetter: Method, private val paramClazz: Class<*> ) : BoundParameterForMap() { - override fun map(src: S): Any? = EnumMapper.getEnum(paramClazz, propertyGetter.invoke(src) as String) + override fun map(src: S): Any? = EnumMapper.getEnum(paramClazz, propertyGetter.invoke(src) as String?) } - private class ToString( + internal class ToString( override val name: String, override val propertyGetter: Method ) : BoundParameterForMap() { - override fun map(src: S): String? = propertyGetter.invoke(src).toString() + override fun map(src: S): String? = propertyGetter.invoke(src)?.toString() } companion object { diff --git a/src/test/kotlin/com/mapk/kmapper/BoundParameterForMapTest.kt b/src/test/kotlin/com/mapk/kmapper/BoundParameterForMapTest.kt new file mode 100644 index 0000000..654c3e1 --- /dev/null +++ b/src/test/kotlin/com/mapk/kmapper/BoundParameterForMapTest.kt @@ -0,0 +1,148 @@ +package com.mapk.kmapper + +import com.mapk.kmapper.testcommons.JvmLanguage +import kotlin.reflect.full.memberProperties +import kotlin.reflect.jvm.javaGetter +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +@DisplayName("BoundKMapperのパラメータテスト") +class BoundParameterForMapTest { + data class IntSrc(val int: Int?) + data class StringSrc(val str: String?) + data class InnerSrc(val int: Int?, val str: String?) + data class ObjectSrc(val obj: Any?) + + data class ObjectDst(val int: Int?, val str: String?) + + @Nested + @DisplayName("Plainのテスト") + inner class PlainTest { + private val parameter = + BoundParameterForMap.Plain("", StringSrc::class.memberProperties.single().javaGetter!!) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(StringSrc("sss")) + assertEquals("sss", result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(StringSrc(null))) + } + } + + @Nested + @DisplayName("UseConverterのテスト") + inner class UseConverterTest { + // アクセシビリティの問題で公開状態に設定 + @Suppress("MemberVisibilityCanBePrivate") + fun makeTwiceOrNull(int: Int?) = int?.let { it * 2 } + + private val parameter = BoundParameterForMap.UseConverter( + "", IntSrc::class.memberProperties.single().javaGetter!!, this::makeTwiceOrNull + ) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(IntSrc(1)) + assertEquals(2, result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(IntSrc(null))) + } + } + + @Nested + @DisplayName("UseKMapperのテスト") + inner class UseKMapperTest { + private val parameter = BoundParameterForMap.UseKMapper( + "", ObjectSrc::class.memberProperties.single().javaGetter!!, KMapper(::ObjectDst) + ) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(ObjectSrc(mapOf("int" to 0, "str" to null))) + assertEquals(ObjectDst(0, null), result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(ObjectSrc(null))) + } + } + + @Nested + @DisplayName("UseBoundKMapperのテスト") + inner class UseBoundKMapperTest { + private val parameter = BoundParameterForMap.UseBoundKMapper( + "", ObjectSrc::class.memberProperties.single().javaGetter!!, BoundKMapper(::ObjectDst, InnerSrc::class) + ) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(ObjectSrc(InnerSrc(null, "str"))) + assertEquals(ObjectDst(null, "str"), result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(ObjectSrc(null))) + } + } + + @Nested + @DisplayName("ToEnumのテスト") + inner class ToEnumTest { + private val parameter = BoundParameterForMap.ToEnum( + "", StringSrc::class.memberProperties.single().javaGetter!!, JvmLanguage::class.java + ) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(StringSrc("Java")) + assertEquals(JvmLanguage.Java, result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(StringSrc(null))) + } + } + + @Nested + @DisplayName("ToStringのテスト") + inner class ToStringTest { + private val parameter = + BoundParameterForMap.ToString("", IntSrc::class.memberProperties.single().javaGetter!!) + + @Test + @DisplayName("not null") + fun isNotNull() { + val result = parameter.map(IntSrc(1)) + assertEquals("1", result) + } + + @Test + @DisplayName("null") + fun isNull() { + assertNull(parameter.map(IntSrc(null))) + } + } +} diff --git a/src/test/kotlin/com/mapk/kmapper/EnumMappingTest.kt b/src/test/kotlin/com/mapk/kmapper/EnumMappingTest.kt index 045d7a2..207e83e 100644 --- a/src/test/kotlin/com/mapk/kmapper/EnumMappingTest.kt +++ b/src/test/kotlin/com/mapk/kmapper/EnumMappingTest.kt @@ -2,16 +2,13 @@ package com.mapk.kmapper +import com.mapk.kmapper.testcommons.JvmLanguage import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource -enum class JvmLanguage { - Java, Scala, Groovy, Kotlin -} - private class EnumMappingDst(val language: JvmLanguage?) @DisplayName("文字列 -> Enumのマッピングテスト") diff --git a/src/test/kotlin/com/mapk/kmapper/testcommons/JvmLanguage.kt b/src/test/kotlin/com/mapk/kmapper/testcommons/JvmLanguage.kt new file mode 100644 index 0000000..1a062a6 --- /dev/null +++ b/src/test/kotlin/com/mapk/kmapper/testcommons/JvmLanguage.kt @@ -0,0 +1,5 @@ +package com.mapk.kmapper.testcommons + +enum class JvmLanguage { + Java, Scala, Groovy, Kotlin +}