14f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar/*
24f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * Copyright (C) 2016 The Android Open Source Project
34f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar *
44f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
54f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * you may not use this file except in compliance with the License.
64f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * You may obtain a copy of the License at
74f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar *
84f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
94f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar *
104f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * Unless required by applicable law or agreed to in writing, software
114f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
124f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * See the License for the specific language governing permissions and
144f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar * limitations under the License.
154f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar */
164f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
17ba069d50913c3fb250bb60ec310439db36895337Alan Viverettepackage androidx.room.processor
184f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
194f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport COMMON
20ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.Dao
21ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.Insert
22ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.OnConflictStrategy
23ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.ext.CommonTypeNames
24ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.ext.typeName
25ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.testing.TestInvocation
26ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.testing.TestProcessor
27ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.vo.InsertionMethod
28ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.room.vo.InsertionMethod.Type
294f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.auto.common.MoreElements
304f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.auto.common.MoreTypes
314f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.common.truth.Truth.assertAbout
324f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.testing.compile.CompileTester
334f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.testing.compile.JavaFileObjects
344f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.google.testing.compile.JavaSourcesSubjectFactory
354f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.squareup.javapoet.ArrayTypeName
364f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.squareup.javapoet.ClassName
374f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.squareup.javapoet.ParameterizedTypeName
384f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport com.squareup.javapoet.TypeName
394f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.hamcrest.CoreMatchers.`is`
404f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.hamcrest.CoreMatchers.nullValue
414f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.hamcrest.MatcherAssert.assertThat
424f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.junit.Test
434f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.junit.runner.RunWith
444f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarimport org.junit.runners.JUnit4
454f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
464f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
474f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar@RunWith(JUnit4::class)
484f0db7db556b473393dfc31bba5ea67def574877Yigit Boyarclass InsertionMethodProcessorTest {
494f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    companion object {
504f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        const val DAO_PREFIX = """
514f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                package foo.bar;
52ba069d50913c3fb250bb60ec310439db36895337Alan Viverette                import androidx.room.*;
534f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                import java.util.*;
544f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Dao
554f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract class MyClass {
564f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
574f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        const val DAO_SUFFIX = "}"
586f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas        val USER_TYPE_NAME: TypeName = COMMON.USER_TYPE_NAME
596f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas        val BOOK_TYPE_NAME: TypeName = ClassName.get("foo.bar", "Book")
604f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
614f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
624f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
634f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun readNoParams() {
644f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
654f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
664f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
674f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo();
68d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
694f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("foo"))
704f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(0))
714f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
7286b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(0))
734f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.failsToCompile().withErrorContaining(
744f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                ProcessorErrors.INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT)
754f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
764f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
774f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
784f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertSingle() {
794f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
804f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
814f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
824f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public long foo(User user);
83d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
844f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("foo"))
854f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(1))
864f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            val param = insertion.parameters.first()
874f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.type.typeName(), `is`(USER_TYPE_NAME))
884f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.entityType?.typeName(), `is`(USER_TYPE_NAME))
8986b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["user"]?.typeName,
904f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    `is`(ClassName.get("foo.bar", "User") as TypeName))
914f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.LONG))
924f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
934f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
944f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
954f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
964f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertNotAnEntity() {
974f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
984f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
994f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
1004f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo(NotAnEntity notValid);
101d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
1024f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("foo"))
1034f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(1))
1044f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            val param = insertion.parameters.first()
1054f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.entityType, `is`(nullValue()))
10686b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(0))
1074f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.failsToCompile().withErrorContaining(
108958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar                ProcessorErrors.CANNOT_FIND_ENTITY_FOR_SHORTCUT_QUERY_PARAMETER
1094f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        )
1104f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
1114f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1124f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
1134f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertTwo() {
1144f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
1154f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
1164f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
117f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                abstract public void foo(User u1, User u2);
118d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
1194f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("foo"))
1204f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1214f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(2))
1224f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            insertion.parameters.forEach {
1234f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                assertThat(it.type.typeName(), `is`(USER_TYPE_NAME))
1244f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                assertThat(it.entityType?.typeName(), `is`(USER_TYPE_NAME))
1254f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            }
12686b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(2))
12786b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["u1"]?.typeName, `is`(USER_TYPE_NAME))
12886b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["u2"]?.typeName, `is`(USER_TYPE_NAME))
1294f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.map { it.name }, `is`(listOf("u1", "u2")))
130f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
1314f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
1324f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
1334f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1344f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
1354f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertList() {
1364f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
1374f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
1384f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
1394f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public List<Long> insertUsers(List<User> users);
140d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
1414f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("insertUsers"))
1424f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(1))
1434f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            val param = insertion.parameters.first()
1444f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.type.typeName(), `is`(
1454f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    ParameterizedTypeName.get(
1464f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            ClassName.get("java.util", "List"), USER_TYPE_NAME) as TypeName))
1474f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.entityType?.typeName(), `is`(USER_TYPE_NAME))
14886b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
14986b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
1504f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(
1514f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    ParameterizedTypeName.get(ClassName.get("java.util", "List"),
1524f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            ClassName.get("java.lang", "Long")) as TypeName
1534f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            ))
1544f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
1554f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
1564f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1574f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
1584f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertArray() {
1594f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
1604f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
1614f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
1624f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void insertUsers(User[] users);
163d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
1644f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("insertUsers"))
1654f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(1))
1664f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            val param = insertion.parameters.first()
1674f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.type.typeName(), `is`(
1684f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    ArrayTypeName.of(COMMON.USER_TYPE_NAME) as TypeName))
16986b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
17086b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
1714f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
1724f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
1734f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
1744f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1754f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
1764f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertSet() {
1774f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
1784f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
1794f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
1804f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void insertUsers(Set<User> users);
181d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
1824f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.name, `is`("insertUsers"))
1834f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(1))
1844f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            val param = insertion.parameters.first()
1854f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(param.type.typeName(), `is`(
1864f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    ParameterizedTypeName.get(ClassName.get("java.util", "Set")
1874f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            , COMMON.USER_TYPE_NAME) as TypeName))
18886b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
18986b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
1904f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
1914f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
1924f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
1934f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
1944f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
195efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    fun insertQueue() {
196efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        singleInsertMethod(
197efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                """
198efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                @Insert
199efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                abstract public void insertUsers(Queue<User> users);
200d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
201efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.name, `is`("insertUsers"))
202efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.parameters.size, `is`(1))
203efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            val param = insertion.parameters.first()
204efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(param.type.typeName(), `is`(
205efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                    ParameterizedTypeName.get(ClassName.get("java.util", "Queue")
20686b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki                            , USER_TYPE_NAME) as TypeName))
20786b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
20886b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
209efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
210efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        }.compilesWithoutError()
211efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    }
212efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki
213efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    @Test
214efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    fun insertIterable() {
215efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        singleInsertMethod("""
216efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                @Insert
217efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                abstract public void insert(Iterable<User> users);
218d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
219efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.name, `is`("insert"))
220efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.parameters.size, `is`(1))
221efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            val param = insertion.parameters.first()
222efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(param.type.typeName(), `is`(ParameterizedTypeName.get(
22386b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki                    ClassName.get("java.lang", "Iterable"), USER_TYPE_NAME) as TypeName))
22486b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
22586b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
226efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
227efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        }.compilesWithoutError()
228efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    }
229efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki
230efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    @Test
231efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    fun insertCustomCollection() {
232efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        singleInsertMethod("""
233efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                static class MyList<Irrelevant, Item> extends ArrayList<Item> {}
234efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                @Insert
235efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                abstract public void insert(MyList<String, User> users);
236d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
237efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.name, `is`("insert"))
238efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.parameters.size, `is`(1))
239efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            val param = insertion.parameters.first()
240efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(param.type.typeName(), `is`(ParameterizedTypeName.get(
241efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki                    ClassName.get("foo.bar", "MyClass.MyList"),
24286b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki                    CommonTypeNames.STRING, USER_TYPE_NAME) as TypeName))
24386b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(1))
24486b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["users"]?.typeName, `is`(USER_TYPE_NAME))
245efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
246efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki        }.compilesWithoutError()
247efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    }
248efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki
249efc6d0fa448a1b64c889a73c6795256f5df654afYuichi Araki    @Test
2504f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun insertDifferentTypes() {
2514f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
2524f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
2534f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
2544f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo(User u1, Book b1);
255d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
2564f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.size, `is`(2))
2574f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters[0].type.typeName().toString(),
2584f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    `is`("foo.bar.User"))
2594f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters[1].type.typeName().toString(),
2604f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    `is`("foo.bar.Book"))
2614f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.parameters.map { it.name }, `is`(listOf("u1", "b1")))
2624f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.returnType.typeName(), `is`(TypeName.VOID))
26386b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities.size, `is`(2))
26486b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["u1"]?.typeName, `is`(USER_TYPE_NAME))
26586b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki            assertThat(insertion.entities["b1"]?.typeName, `is`(BOOK_TYPE_NAME))
26686b3f8d9bd637749668174e0736fe9fbecbcfb09Yuichi Araki        }.compilesWithoutError()
2674f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
2684f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
2694f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
2704f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun onConflict_Default() {
2714f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
2724f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
2734f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
2744f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo(User user);
275d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
276333b4b5e49c48adf7fb928d445b6f7f276b54a02Yigit Boyar            assertThat(insertion.onConflict, `is`(OnConflictStrategy.ABORT))
2774f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.compilesWithoutError()
2784f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
2794f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
2804f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
2814f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun onConflict_Invalid() {
2824f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
2834f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
2844f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert(onConflict = -1)
2854f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo(User user);
286d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { _, _ ->
2874f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_ON_CONFLICT_VALUE)
2884f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
2894f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
2904f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
2914f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun onConflict_EachValue() {
2924f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        listOf(
2934f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                Pair("REPLACE", 1),
2944f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                Pair("ROLLBACK", 2),
2954f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                Pair("ABORT", 3),
2964f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                Pair("FAIL", 4),
2974f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                Pair("IGNORE", 5)
2984f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        ).forEach { pair ->
2994f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            singleInsertMethod(
3004f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    """
301333b4b5e49c48adf7fb928d445b6f7f276b54a02Yigit Boyar                @Insert(onConflict=OnConflictStrategy.${pair.first})
3024f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public void foo(User user);
303d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
3044f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                assertThat(insertion.onConflict, `is`(pair.second))
3054f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            }.compilesWithoutError()
3064f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }
3074f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
3084f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
3094f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
3104f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun invalidReturnType() {
3114f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        singleInsertMethod(
3124f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                """
3134f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
3144f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                abstract public int foo(User user);
315d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
3164f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            assertThat(insertion.insertionType, `is`(nullValue()))
3174f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }.failsToCompile().withErrorContaining(
3184f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                ProcessorErrors.INVALID_INSERTION_METHOD_RETURN_TYPE)
3194f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
3204f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
3214f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    @Test
322f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    fun mismatchedReturnType() {
323f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        singleInsertMethod(
324f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                """
325f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                @Insert
326f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                abstract public long[] foo(User user);
327d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
328f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            assertThat(insertion.insertionType, `is`(nullValue()))
329f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        }.failsToCompile().withErrorContaining(
330f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                ProcessorErrors.insertionMethodReturnTypeMismatch(
331f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        ArrayTypeName.of(TypeName.LONG),
332f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        InsertionMethodProcessor.SINGLE_ITEM_SET.map { it.returnTypeName }))
333f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    }
334f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar
335f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    @Test
336f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    fun mismatchedReturnType2() {
337f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        singleInsertMethod(
338f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                """
339f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                @Insert
340f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                abstract public long foo(User... user);
341d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
342f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            assertThat(insertion.insertionType, `is`(nullValue()))
343f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        }.failsToCompile().withErrorContaining(
344f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                ProcessorErrors.insertionMethodReturnTypeMismatch(
345f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        TypeName.LONG,
346f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        InsertionMethodProcessor.MULTIPLE_ITEM_SET.map { it.returnTypeName }))
347f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    }
348f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar
349f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    @Test
350f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    fun mismatchedReturnType3() {
351f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        singleInsertMethod(
352f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                """
353f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                @Insert
354f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                abstract public long foo(User user1, User user2);
355d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
356f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            assertThat(insertion.insertionType, `is`(nullValue()))
357f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        }.failsToCompile().withErrorContaining(
358f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                ProcessorErrors.insertionMethodReturnTypeMismatch(
359f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        TypeName.LONG,
360f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        InsertionMethodProcessor.VOID_SET.map { it.returnTypeName }))
361f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    }
362f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar
363f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar    @Test
3644f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    fun validReturnTypes() {
3654f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        listOf(
366f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                Pair("void", Type.INSERT_VOID),
367f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                Pair("long", Type.INSERT_SINGLE_ID),
368f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                Pair("long[]", Type.INSERT_ID_ARRAY),
369dd6aaec8254abfee2dd82a5f2c59282f8eeee9eeYuichi Araki                Pair("Long[]", Type.INSERT_ID_ARRAY_BOX),
370f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                Pair("List<Long>", Type.INSERT_ID_LIST)
371f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar        ).forEach { pair ->
372dd6aaec8254abfee2dd82a5f2c59282f8eeee9eeYuichi Araki            val dots = if (pair.second in setOf(Type.INSERT_ID_LIST, Type.INSERT_ID_ARRAY,
373dd6aaec8254abfee2dd82a5f2c59282f8eeee9eeYuichi Araki                    Type.INSERT_ID_ARRAY_BOX)) {
374f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                "..."
375f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            } else {
376f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                ""
377f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar            }
3784f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            singleInsertMethod(
3794f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                    """
3804f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                @Insert
381f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                abstract public ${pair.first} foo(User$dots user);
382d2649c45a34db46fb03a24dcb2a443a92298b5adSergey Vasilinets                """) { insertion, _ ->
3834f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                assertThat(insertion.insertMethodTypeFor(insertion.parameters.first()),
384f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                        `is`(pair.second))
385f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar                assertThat(pair.toString(), insertion.insertionType, `is`(pair.second))
3864f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar            }.compilesWithoutError()
3874f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        }
3884f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
3894f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar
3906f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas    fun singleInsertMethod(
3916f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas            vararg input: String,
3926f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas            handler: (InsertionMethod, TestInvocation) -> Unit
3936f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas    ): CompileTester {
3944f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar        return assertAbout(JavaSourcesSubjectFactory.javaSources())
3954f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                .that(listOf(JavaFileObjects.forSourceString("foo.bar.MyClass",
3964f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                        DAO_PREFIX + input.joinToString("\n") + DAO_SUFFIX
3974f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                ), COMMON.USER, COMMON.BOOK, COMMON.NOT_AN_ENTITY))
3984f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                .processedWith(TestProcessor.builder()
3994f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                        .forAnnotations(Insert::class, Dao::class)
4004f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                        .nextRunHandler { invocation ->
4014f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            val (owner, methods) = invocation.roundEnv
4024f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                    .getElementsAnnotatedWith(Dao::class.java)
4034f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                    .map {
4044f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                        Pair(it,
4054f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                invocation.processingEnv.elementUtils
4064f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                        .getAllMembers(MoreElements.asType(it))
4074f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                        .filter {
4084f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                            MoreElements.isAnnotationPresent(it,
4094f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                                    Insert::class.java)
4104f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                                        }
4114f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                                        )
412c21394d1dcb24518061aabde879baff891a426e3Sergey Vasilinets                                    }.first { it.second.isNotEmpty() }
413aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyar                            val processor = InsertionMethodProcessor(
414aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyar                                    baseContext = invocation.context,
415aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyar                                    containing = MoreTypes.asDeclared(owner.asType()),
416aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyar                                    executableElement = MoreElements.asExecutable(methods.first()))
417aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyar                            val processed = processor.process()
4184f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            handler(processed, invocation)
4194f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                            true
4204f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                        }
4214f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar                        .build())
4224f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar    }
4234f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar}
424