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