Run InsertionMethodProcessorTest with KSP

Bug: 160322705
Test: InsertionMethodProcessorTest
Change-Id: Icd465f455beaab6e258ca72c8013e15892d6fe13
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
index f753d89..e22402f 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
@@ -21,17 +21,15 @@
 import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.compiler.processing.XTypeElement
+import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.XTestInvocation
+import androidx.room.compiler.processing.util.runProcessorTest
 import androidx.room.ext.CommonTypeNames
 import androidx.room.ext.RxJava2TypeNames
 import androidx.room.ext.RxJava3TypeNames
 import androidx.room.solver.shortcut.result.InsertMethodAdapter
-import androidx.room.testing.TestInvocation
-import androidx.room.testing.TestProcessor
+import androidx.room.testing.context
 import androidx.room.vo.InsertionMethod
-import com.google.common.truth.Truth.assertAbout
-import com.google.testing.compile.CompileTester
-import com.google.testing.compile.JavaFileObjects
-import com.google.testing.compile.JavaSourcesSubjectFactory
 import com.squareup.javapoet.ArrayTypeName
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
@@ -43,8 +41,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import toJFO
-import javax.tools.JavaFileObject
+import toSources
 
 @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
 @RunWith(JUnit4::class)
@@ -70,14 +67,17 @@
                 @Insert
                 abstract public void foo();
                 """
-        ) { insertion, _ ->
+        ) { insertion, invocation ->
             assertThat(insertion.name, `is`("foo"))
             assertThat(insertion.parameters.size, `is`(0))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
             assertThat(insertion.entities.size, `is`(0))
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT
-        )
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT
+                )
+            }
+        }
     }
 
     @Test
@@ -99,7 +99,7 @@
                 `is`(ClassName.get("foo.bar", "User") as TypeName)
             )
             assertThat(insertion.returnType.typeName, `is`(TypeName.LONG))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -109,13 +109,16 @@
                 @Insert
                 abstract public void foo(NotAnEntity notValid);
                 """
-        ) { insertion, _ ->
+        ) { insertion, invocation ->
             assertThat(insertion.name, `is`("foo"))
             assertThat(insertion.parameters.size, `is`(1))
             assertThat(insertion.entities.size, `is`(0))
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.CANNOT_FIND_ENTITY_FOR_SHORTCUT_QUERY_PARAMETER
-        )
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.CANNOT_FIND_ENTITY_FOR_SHORTCUT_QUERY_PARAMETER
+                )
+            }
+        }
     }
 
     @Test
@@ -138,7 +141,7 @@
             assertThat(insertion.entities["u2"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.parameters.map { it.name }, `is`(listOf("u1", "u2")))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -173,7 +176,7 @@
                     ) as TypeName
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -196,7 +199,7 @@
             assertThat(insertion.entities.size, `is`(1))
             assertThat(insertion.entities["users"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -222,7 +225,7 @@
             assertThat(insertion.entities.size, `is`(1))
             assertThat(insertion.entities["users"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -248,7 +251,7 @@
             assertThat(insertion.entities.size, `is`(1))
             assertThat(insertion.entities["users"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -274,7 +277,7 @@
             assertThat(insertion.entities.size, `is`(1))
             assertThat(insertion.entities["users"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -301,7 +304,7 @@
             assertThat(insertion.entities.size, `is`(1))
             assertThat(insertion.entities["users"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.returnType.typeName, `is`(TypeName.VOID))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -326,7 +329,7 @@
             assertThat(insertion.entities.size, `is`(2))
             assertThat(insertion.entities["u1"]?.pojo?.typeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.entities["b1"]?.pojo?.typeName, `is`(BOOK_TYPE_NAME))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -338,7 +341,7 @@
                 """
         ) { insertion, _ ->
             assertThat(insertion.onConflict, `is`(OnConflictStrategy.ABORT))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -348,8 +351,13 @@
                 @Insert(onConflict = -1)
                 abstract public void foo(User user);
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_ON_CONFLICT_VALUE)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.INVALID_ON_CONFLICT_VALUE
+                )
+            }
+        }
     }
 
     @Test
@@ -368,7 +376,7 @@
                 """
             ) { insertion, _ ->
                 assertThat(insertion.onConflict, `is`(pair.second))
-            }.compilesWithoutError()
+            }
         }
     }
 
@@ -388,11 +396,14 @@
                 @Insert
                 abstract public $type foo(User user);
                 """
-            ) { insertion, _ ->
+            ) { insertion, invocation ->
                 assertThat(insertion.methodBinder.adapter, `is`(nullValue()))
-            }.failsToCompile().withErrorContaining(
-                ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
-            )
+                invocation.assertCompilationResult {
+                    hasErrorContaining(
+                        ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
+                    )
+                }
+            }
         }
     }
 
@@ -410,11 +421,14 @@
                 @Insert
                 abstract public $type foo(User user);
                 """
-            ) { insertion, _ ->
+            ) { insertion, invocation ->
                 assertThat(insertion.methodBinder.adapter, `is`(nullValue()))
-            }.failsToCompile().withErrorContaining(
-                ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
-            )
+                invocation.assertCompilationResult {
+                    hasErrorContaining(
+                        ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
+                    )
+                }
+            }
         }
     }
 
@@ -431,11 +445,14 @@
                 @Insert
                 abstract public $type foo(User... user);
                 """
-            ) { insertion, _ ->
+            ) { insertion, invocation ->
                 assertThat(insertion.methodBinder.adapter, `is`(nullValue()))
-            }.failsToCompile().withErrorContaining(
-                ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
-            )
+                invocation.assertCompilationResult {
+                    hasErrorContaining(
+                        ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
+                    )
+                }
+            }
         }
     }
 
@@ -452,11 +469,14 @@
                 @Insert
                 abstract public $type foo(User user1, User user2);
                 """
-            ) { insertion, _ ->
+            ) { insertion, invocation ->
                 assertThat(insertion.methodBinder.adapter, `is`(nullValue()))
-            }.failsToCompile().withErrorContaining(
-                ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
-            )
+                invocation.assertCompilationResult {
+                    hasErrorContaining(
+                        ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
+                    )
+                }
+            }
         }
     }
 
@@ -526,13 +546,15 @@
                 """
             ) { insertion, _ ->
                 assertThat(insertion.methodBinder.adapter, `is`(notNullValue()))
-            }.compilesWithoutError()
+            }
         }
     }
 
     @Test
     fun targetEntitySingle() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -542,13 +564,14 @@
                 @ColumnInfo(name = "ageColumn")
                 int age;
             }
-        """.toJFO("foo.bar.Username")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public long foo(Username username);
-                """,
-            additionalJFOs = listOf(usernameJfo)
+            """,
+            additionalSources = listOf(usernameSource)
         ) { insertion, _ ->
             assertThat(insertion.name, `is`("foo"))
             assertThat(insertion.parameters.size, `is`(1))
@@ -559,7 +582,7 @@
             assertThat(insertion.entities["username"]?.isPartialEntity, `is`(true))
             assertThat(insertion.entities["username"]?.entityTypeName, `is`(USER_TYPE_NAME))
             assertThat(insertion.entities["username"]?.pojo?.typeName, `is`(USERNAME_TYPE_NAME))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -568,14 +591,16 @@
             """
                 @Insert(entity = User.class)
                 abstract public long foo(User user);
-                """
+            """
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityTwo() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -585,20 +610,23 @@
                 @ColumnInfo(name = "ageColumn")
                 int age;
             }
-        """.toJFO("foo.bar.Username")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public void foo(Username usernameA, Username usernameB);
-                """,
-            additionalJFOs = listOf(usernameJfo)
+            """,
+            additionalSources = listOf(usernameSource)
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityMissingRequiredColumn() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -606,25 +634,31 @@
                 int uid;
                 String name;
             }
-        """.toJFO("foo.bar.Username")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public void foo(Username username);
-                """,
-            additionalJFOs = listOf(usernameJfo)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.missingRequiredColumnsInPartialEntity(
-                partialEntityName = USERNAME_TYPE_NAME.toString(),
-                missingColumnNames = listOf("ageColumn")
-            )
-        )
+            """,
+            additionalSources = listOf(usernameSource)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.missingRequiredColumnsInPartialEntity(
+                        partialEntityName = USERNAME_TYPE_NAME.toString(),
+                        missingColumnNames = listOf("ageColumn")
+                    )
+                )
+            }
+        }
     }
 
     @Test
     fun targetEntityColumnDefaultValue() {
-        val petNameJfo = """
+        val petNameSource = Source.java(
+            "foo.bar.PetName",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -632,8 +666,11 @@
                 @ColumnInfo(name = "name")
                 String string;
             }
-        """.toJFO("foo.bar.PetName")
-        val petJfo = """
+            """
+        )
+        val petSource = Source.java(
+            "foo.bar.Pet",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -645,20 +682,23 @@
                 @ColumnInfo(defaultValue = "0")
                 int age;
             }
-        """.toJFO("foo.bar.Pet")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = Pet.class)
                 abstract public long foo(PetName petName);
-                """,
-            additionalJFOs = listOf(petNameJfo, petJfo)
+            """,
+            additionalSources = listOf(petNameSource, petSource)
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityMissingPrimaryKey() {
-        val petNameJfo = """
+        val petNameSource = Source.java(
+            "foo.bar.PetName",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -666,8 +706,11 @@
                 @ColumnInfo(name = "name")
                 String string;
             }
-        """.toJFO("foo.bar.PetName")
-        val petJfo = """
+            """
+        )
+        val petSource = Source.java(
+            "foo.bar.Pet",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -677,25 +720,31 @@
                 int petId;
                 String name;
             }
-        """.toJFO("foo.bar.Pet")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = Pet.class)
                 abstract public long foo(PetName petName);
-                """,
-            additionalJFOs = listOf(petNameJfo, petJfo)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.missingPrimaryKeysInPartialEntityForInsert(
-                partialEntityName = "foo.bar.PetName",
-                primaryKeyNames = listOf("petId")
-            )
-        )
+            """,
+            additionalSources = listOf(petNameSource, petSource)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.missingPrimaryKeysInPartialEntityForInsert(
+                        partialEntityName = "foo.bar.PetName",
+                        primaryKeyNames = listOf("petId")
+                    )
+                )
+            }
+        }
     }
 
     @Test
     fun targetEntityAutoGeneratedPrimaryKey() {
-        val petNameJfo = """
+        val petNameSource = Source.java(
+            "foo.bar.PetName",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -703,8 +752,11 @@
                 @ColumnInfo(name = "name")
                 String string;
             }
-        """.toJFO("foo.bar.PetName")
-        val petJfo = """
+            """
+        )
+        val petSource = Source.java(
+            "foo.bar.Pet",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -714,20 +766,23 @@
                 int petId;
                 String name;
             }
-        """.toJFO("foo.bar.Pet")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = Pet.class)
                 abstract public long foo(PetName petName);
-                """,
-            additionalJFOs = listOf(petNameJfo, petJfo)
+            """,
+            additionalSources = listOf(petNameSource, petSource)
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityExtraColumn() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -736,22 +791,28 @@
                 String name;
                 long extraField;
             }
-        """.toJFO("foo.bar.Username")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public long foo(Username username);
-                """,
-            additionalJFOs = listOf(usernameJfo)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.cannotFindAsEntityField("foo.bar.User")
-        )
+            """,
+            additionalSources = listOf(usernameSource)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.cannotFindAsEntityField("foo.bar.User")
+                )
+            }
+        }
     }
 
     @Test
     fun targetEntityExtraColumnIgnored() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -763,20 +824,23 @@
                 @Ignore
                 long extraField;
             }
-        """.toJFO("foo.bar.Username")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public long foo(Username username);
-                """,
-            additionalJFOs = listOf(usernameJfo)
+            """,
+            additionalSources = listOf(usernameSource)
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityWithEmbedded() {
-        val usernameJfo = """
+        val usernameSource = Source.java(
+            "foo.bar.Username",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -787,8 +851,11 @@
                 @ColumnInfo(name = "ageColumn")
                 int age;
             }
-        """.toJFO("foo.bar.Username")
-        val fullnameJfo = """
+            """
+        )
+        val fullnameSource = Source.java(
+            "foo.bar.Fullname",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -797,20 +864,23 @@
                 String firstName;
                 String lastName;
             }
-        """.toJFO("foo.bar.Fullname")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public long foo(Username username);
-                """,
-            additionalJFOs = listOf(usernameJfo, fullnameJfo)
+            """,
+            additionalSources = listOf(usernameSource, fullnameSource)
         ) { _, _ ->
-        }.compilesWithoutError()
+        }
     }
 
     @Test
     fun targetEntityWithRelation() {
-        val userPetsJfo = """
+        val userPetsSource = Source.java(
+            "foo.bar.UserPets",
+            """
             package foo.bar;
             import androidx.room.*;
             import java.util.List;
@@ -820,8 +890,11 @@
                 @Relation(parentColumn = "uid", entityColumn = "ownerId")
                 List<Pet> pets;
             }
-        """.toJFO("foo.bar.UserPets")
-        val petJfo = """
+            """
+        )
+        val petSource = Source.java(
+            "foo.bar.Pet",
+            """
             package foo.bar;
             import androidx.room.*;
 
@@ -831,59 +904,59 @@
                 int petId;
                 int ownerId;
             }
-        """.toJFO("foo.bar.Pet")
+            """
+        )
         singleInsertMethod(
             """
                 @Insert(entity = User.class)
                 abstract public long foo(UserPets userPets);
                 """,
-            additionalJFOs = listOf(userPetsJfo, petJfo)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_RELATION_IN_PARTIAL_ENTITY)
+            additionalSources = listOf(userPetsSource, petSource)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining(
+                    ProcessorErrors.INVALID_RELATION_IN_PARTIAL_ENTITY
+                )
+            }
+        }
     }
 
     fun singleInsertMethod(
         vararg input: String,
-        additionalJFOs: List<JavaFileObject> = emptyList(),
-        handler: (InsertionMethod, TestInvocation) -> Unit
-    ): CompileTester {
-        return assertAbout(JavaSourcesSubjectFactory.javaSources())
-            .that(
-                listOf(
-                    JavaFileObjects.forSourceString(
-                        "foo.bar.MyClass",
-                        DAO_PREFIX + input.joinToString("\n") + DAO_SUFFIX
-                    ),
-                    COMMON.USER, COMMON.BOOK, COMMON.NOT_AN_ENTITY, COMMON.RX2_COMPLETABLE,
-                    COMMON.RX2_MAYBE, COMMON.RX2_SINGLE, COMMON.RX3_COMPLETABLE,
-                    COMMON.RX3_MAYBE, COMMON.RX3_SINGLE
-                ) + additionalJFOs
+        additionalSources: List<Source> = emptyList(),
+        handler: (InsertionMethod, XTestInvocation) -> Unit
+    ) {
+        val inputSource = Source.java(
+            "foo.bar.MyClass",
+            DAO_PREFIX + input.joinToString("\n") + DAO_SUFFIX
+        )
+        val commonSources = listOf(
+            COMMON.USER, COMMON.BOOK, COMMON.NOT_AN_ENTITY, COMMON.RX2_COMPLETABLE,
+            COMMON.RX2_MAYBE, COMMON.RX2_SINGLE, COMMON.RX3_COMPLETABLE,
+            COMMON.RX3_MAYBE, COMMON.RX3_SINGLE
+        ).toSources()
+
+        runProcessorTest(
+            sources = commonSources + additionalSources + inputSource
+        ) { invocation ->
+            val (owner, methods) = invocation.roundEnv
+                .getElementsAnnotatedWith(Dao::class.qualifiedName!!)
+                .filterIsInstance<XTypeElement>()
+                .map {
+                    Pair(
+                        it,
+                        it.getAllMethods().filter {
+                            it.hasAnnotation(Insert::class)
+                        }
+                    )
+                }.first { it.second.isNotEmpty() }
+            val processor = InsertionMethodProcessor(
+                baseContext = invocation.context,
+                containing = owner.type,
+                executableElement = methods.first()
             )
-            .processedWith(
-                TestProcessor.builder()
-                    .forAnnotations(Insert::class, Dao::class)
-                    .nextRunHandler { invocation ->
-                        val (owner, methods) = invocation.roundEnv
-                            .getElementsAnnotatedWith(Dao::class.qualifiedName!!)
-                            .filterIsInstance<XTypeElement>()
-                            .map {
-                                Pair(
-                                    it,
-                                    it.getAllMethods().filter {
-                                        it.hasAnnotation(Insert::class)
-                                    }
-                                )
-                            }.first { it.second.isNotEmpty() }
-                        val processor = InsertionMethodProcessor(
-                            baseContext = invocation.context,
-                            containing = owner.type,
-                            executableElement = methods.first()
-                        )
-                        val processed = processor.process()
-                        handler(processed, invocation)
-                        true
-                    }
-                    .build()
-            )
+            val processed = processor.process()
+            handler(processed, invocation)
+        }
     }
 }