Merge "Run EntityParser tests with KSP" into androidx-main
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
index 4c94140..4aea1fa 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationResultSubject.kt
@@ -109,6 +109,36 @@
     }
 
     /**
+     * Asserts free form output from the compilation output.
+     */
+    fun hasRawOutputContaining(expected: String) = chain {
+        val found = compilationResult.rawOutput().contains(expected)
+        if (!found) {
+            failWithActual(
+                simpleFact("Did not find $expected in the output.")
+            )
+        }
+    }
+
+    /**
+     * Checks the compilation didn't have any warnings.
+     */
+    fun hasNoWarnings() = hasDiagnosticCount(Diagnostic.Kind.WARNING, 0)
+
+    /**
+     * Check the compilation had [expected] number of error messages.
+     */
+    fun hasErrorCount(expected: Int) = hasDiagnosticCount(Diagnostic.Kind.ERROR, expected)
+
+    private fun hasDiagnosticCount(kind: Diagnostic.Kind, expected: Int) = chain {
+        val actual = compilationResult.diagnosticsOfKind(kind).size
+        if (actual != expected) {
+            failWithActual(
+                simpleFact("expected $expected $kind messages, found $actual")
+            )
+        }
+    }
+    /**
      * Asserts that compilation has a warning with the given text.
      *
      * @see hasError
@@ -375,6 +405,7 @@
     processor: SyntheticProcessor,
     successfulCompilation: Boolean,
     outputSourceDirs: List<File>,
+    private val rawOutput: String,
 ) : CompilationResult(
     testRunnerName = testRunner.name,
     processor = processor,
@@ -401,7 +432,5 @@
         }
     }
 
-    override fun rawOutput(): String {
-        return delegate.messages
-    }
+    override fun rawOutput() = rawOutput
 }
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/KotlinCompilationUtil.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/KotlinCompilationUtil.kt
index 5554597..df23b64 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/KotlinCompilationUtil.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/KotlinCompilationUtil.kt
@@ -18,6 +18,7 @@
 
 import com.tschuchort.compiletesting.KotlinCompilation
 import java.io.File
+import java.io.OutputStream
 
 /**
  * Helper class for Kotlin Compile Testing library to have common setup for room.
@@ -25,6 +26,7 @@
 internal object KotlinCompilationUtil {
     fun prepareCompilation(
         sources: List<Source>,
+        outputStream: OutputStream,
         classpaths: List<File> = emptyList()
     ): KotlinCompilation {
         val compilation = KotlinCompilation()
@@ -44,6 +46,7 @@
         compilation.inheritClassPath = true
         compilation.verbose = false
         compilation.classpaths += classpaths
+        compilation.messageOutputStream = outputStream
         return compilation
     }
 }
\ No newline at end of file
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
index b6ca3bc..cf24bd3 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/ProcessorTestExt.kt
@@ -24,6 +24,7 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import com.tschuchort.compiletesting.KotlinCompilation
+import java.io.ByteArrayOutputStream
 import java.io.File
 
 private fun runTests(
@@ -226,10 +227,14 @@
 fun compileFiles(
     sources: List<Source>
 ): File {
-    val compilation = KotlinCompilationUtil.prepareCompilation(sources = sources)
+    val outputStream = ByteArrayOutputStream()
+    val compilation = KotlinCompilationUtil.prepareCompilation(
+        sources = sources,
+        outputStream = outputStream
+    )
     val result = compilation.compile()
     check(result.exitCode == KotlinCompilation.ExitCode.OK) {
-        "compilation failed: ${result.messages}"
+        "compilation failed: ${outputStream.toString(Charsets.UTF_8)}"
     }
     return compilation.classesDir
 }
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KaptCompilationTestRunner.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KaptCompilationTestRunner.kt
index b4082c2..39426f3 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KaptCompilationTestRunner.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KaptCompilationTestRunner.kt
@@ -21,6 +21,7 @@
 import androidx.room.compiler.processing.util.KotlinCompilationUtil
 import androidx.room.compiler.processing.util.KotlinCompileTestingCompilationResult
 import com.tschuchort.compiletesting.KotlinCompilation
+import java.io.ByteArrayOutputStream
 
 internal object KaptCompilationTestRunner : CompilationTestRunner {
 
@@ -32,8 +33,10 @@
 
     override fun compile(params: TestCompilationParameters): CompilationResult {
         val syntheticJavacProcessor = SyntheticJavacProcessor(params.handlers)
+        val outputStream = ByteArrayOutputStream()
         val compilation = KotlinCompilationUtil.prepareCompilation(
             sources = params.sources,
+            outputStream = outputStream,
             classpaths = params.classpath
         )
         compilation.annotationProcessors = listOf(syntheticJavacProcessor)
@@ -43,7 +46,10 @@
             delegate = result,
             processor = syntheticJavacProcessor,
             successfulCompilation = result.exitCode == KotlinCompilation.ExitCode.OK,
-            outputSourceDirs = listOf(compilation.kaptSourceDir, compilation.kaptKotlinGeneratedDir)
+            outputSourceDirs = listOf(
+                compilation.kaptSourceDir, compilation.kaptKotlinGeneratedDir
+            ),
+            rawOutput = outputStream.toString(Charsets.UTF_8),
         )
     }
 }
\ No newline at end of file
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
index 85916fa..a927d56c 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/runner/KspCompilationTestRunner.kt
@@ -26,6 +26,7 @@
 import com.tschuchort.compiletesting.SourceFile
 import com.tschuchort.compiletesting.kspSourcesDir
 import com.tschuchort.compiletesting.symbolProcessors
+import java.io.ByteArrayOutputStream
 import java.io.File
 import javax.tools.Diagnostic
 
@@ -48,9 +49,11 @@
         }
         val syntheticKspProcessor = SyntheticKspProcessor(params.handlers)
 
+        val combinedOutputStream = ByteArrayOutputStream()
         val kspCompilation = KotlinCompilationUtil.prepareCompilation(
-            sources,
-            params.classpath
+            sources = sources,
+            outputStream = combinedOutputStream,
+            classpaths = params.classpath
         )
         kspCompilation.symbolProcessors = listOf(syntheticKspProcessor)
         kspCompilation.compile()
@@ -61,8 +64,9 @@
 
         // after ksp, compile without ksp with KSP's output as input
         val finalCompilation = KotlinCompilationUtil.prepareCompilation(
-            sources,
-            params.classpath
+            sources = sources,
+            outputStream = combinedOutputStream,
+            classpaths = params.classpath,
         )
         // build source files from generated code
         finalCompilation.sources += kspCompilation.kspJavaSourceDir.collectSourceFiles() +
@@ -81,7 +85,8 @@
             outputSourceDirs = listOf(
                 kspCompilation.kspJavaSourceDir,
                 kspCompilation.kspKotlinSourceDir
-            )
+            ),
+            rawOutput = combinedOutputStream.toString(Charsets.UTF_8),
         )
     }
 
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index 69e88a0..4b4842f 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -66,12 +66,7 @@
     }
 
     override val qualifiedName: String by lazy {
-        val pkgName = declaration.getNormalizedPackageName()
-        if (pkgName.isBlank()) {
-            declaration.simpleName.asString()
-        } else {
-            "$pkgName.${declaration.simpleName.asString()}"
-        }
+        (declaration.qualifiedName ?: declaration.simpleName).asString()
     }
 
     override val type: KspType by lazy {
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index f705a27..faded70 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -51,8 +51,18 @@
             class InFooBar
             """.trimIndent()
         )
+        val src3 = Source.java(
+            "foo.bar.Outer",
+            """
+            package foo.bar;
+            public class Outer {
+                public static class Nested {
+                }
+            }
+            """
+        )
         runProcessorTest(
-            sources = listOf(src1, src2)
+            sources = listOf(src1, src2, src3)
         ) { invocation ->
             invocation.processingEnv.requireTypeElement("TopLevel").let {
                 assertThat(it.packageName).isEqualTo("")
@@ -66,6 +76,22 @@
                 assertThat(it.qualifiedName).isEqualTo("foo.bar.InFooBar")
                 assertThat(it.className).isEqualTo(ClassName.get("foo.bar", "InFooBar"))
             }
+            invocation.processingEnv.requireTypeElement("foo.bar.Outer").let {
+                assertThat(it.packageName).isEqualTo("foo.bar")
+                assertThat(it.name).isEqualTo("Outer")
+                assertThat(it.qualifiedName).isEqualTo("foo.bar.Outer")
+                assertThat(it.className).isEqualTo(
+                    ClassName.get("foo.bar", "Outer")
+                )
+            }
+            invocation.processingEnv.requireTypeElement("foo.bar.Outer.Nested").let {
+                assertThat(it.packageName).isEqualTo("foo.bar")
+                assertThat(it.name).isEqualTo("Nested")
+                assertThat(it.qualifiedName).isEqualTo("foo.bar.Outer.Nested")
+                assertThat(it.className).isEqualTo(
+                    ClassName.get("foo.bar", "Outer", "Nested")
+                )
+            }
             if (invocation.isKsp) {
                 // these are KSP specific tests, typenames are tested elsewhere
                 invocation.processingEnv.requireTypeElement("java.lang.Integer").let {
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
index fe29b71..efc5e84 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
@@ -108,8 +108,8 @@
                     context.logger.w(
                         Warning.INDEX_FROM_PARENT_FIELD_IS_DROPPED,
                         ProcessorErrors.droppedSuperClassFieldIndex(
-                            it.columnName, element.toString(),
-                            it.element.enclosingTypeElement.toString()
+                            it.columnName, element.qualifiedName,
+                            it.element.enclosingTypeElement.qualifiedName
                         )
                     )
                     null
@@ -236,7 +236,7 @@
             if (parentAnnotation == null) {
                 context.logger.e(
                     element,
-                    ProcessorErrors.foreignKeyNotAnEntity(parentElement.toString())
+                    ProcessorErrors.foreignKeyNotAnEntity(parentElement.qualifiedName)
                 )
                 return@map null
             }
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/BaseEntityParserTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/BaseEntityParserTest.kt
index 105bebb6..c442c6f 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/BaseEntityParserTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/BaseEntityParserTest.kt
@@ -16,17 +16,12 @@
 
 package androidx.room.processor
 
-import androidx.annotation.NonNull
-import androidx.room.Embedded
-import androidx.room.testing.TestInvocation
-import androidx.room.testing.TestProcessor
+import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.XTestInvocation
+import androidx.room.compiler.processing.util.runProcessorTest
+import androidx.room.testing.context
 import androidx.room.vo.Entity
-import com.google.common.truth.Truth
-import com.google.testing.compile.CompileTester
-import com.google.testing.compile.JavaFileObjects
-import com.google.testing.compile.JavaSourcesSubjectFactory
 import java.io.File
-import javax.tools.JavaFileObject
 
 abstract class BaseEntityParserTest {
     companion object {
@@ -45,10 +40,10 @@
         input: String,
         attributes: Map<String, String> = mapOf(),
         baseClass: String = "",
-        jfos: List<JavaFileObject> = emptyList(),
-        classpathFiles: Set<File> = emptySet(),
-        handler: (Entity, TestInvocation) -> Unit
-    ): CompileTester {
+        sources: List<Source> = emptyList(),
+        classpathFiles: List<File> = emptyList(),
+        handler: (Entity, XTestInvocation) -> Unit
+    ) {
         val attributesReplacement: String
         if (attributes.isEmpty()) {
             attributesReplacement = ""
@@ -63,45 +58,26 @@
         } else {
             baseClassReplacement = " extends $baseClass"
         }
-        return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
-            .that(
-                jfos + JavaFileObjects.forSourceString(
-                    "foo.bar.MyEntity",
-                    ENTITY_PREFIX.format(attributesReplacement, baseClassReplacement) +
-                        input + ENTITY_SUFFIX
-                )
-            )
-            .apply {
-                if (classpathFiles.isNotEmpty()) {
-                    withClasspath(classpathFiles)
+        runProcessorTest(
+            sources = sources + Source.java(
+                qName = "foo.bar.MyEntity",
+                code = ENTITY_PREFIX.format(attributesReplacement, baseClassReplacement) +
+                    input + ENTITY_SUFFIX
+            ),
+            classpath = classpathFiles
+        ) { invocation ->
+            val entity = invocation.roundEnv
+                .getTypeElementsAnnotatedWith(
+                    androidx.room.Entity::class.java
+                ).first {
+                    it.qualifiedName == "foo.bar.MyEntity"
                 }
-            }
-            .processedWith(
-                TestProcessor.builder()
-                    .forAnnotations(
-                        java.lang.SuppressWarnings::class,
-                        androidx.room.Entity::class,
-                        androidx.room.PrimaryKey::class,
-                        androidx.room.Ignore::class,
-                        Embedded::class,
-                        androidx.room.ColumnInfo::class,
-                        NonNull::class
-                    )
-                    .nextRunHandler { invocation ->
-                        val entity = invocation.roundEnv
-                            .getTypeElementsAnnotatedWith(
-                                androidx.room.Entity::class.java
-                            )
-                            .first { it.toString() == "foo.bar.MyEntity" }
-                        val parser = TableEntityProcessor(
-                            invocation.context,
-                            entity
-                        )
-                        val parsedQuery = parser.process()
-                        handler(parsedQuery, invocation)
-                        true
-                    }
-                    .build()
+            val parser = TableEntityProcessor(
+                invocation.context,
+                entity
             )
+            val parsedQuery = parser.process()
+            handler(parsedQuery, invocation)
+        }
     }
 }
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
index 753a1d7..62a20cd 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/EntityNameMatchingVariationsTest.kt
@@ -61,7 +61,7 @@
                 public void $setterName(int id) { this.$fieldName = id; }
             """
         ) { entity, invocation ->
-            assertThat(entity.type.toString(), `is`("foo.bar.MyEntity"))
+            assertThat(entity.type.typeName.toString(), `is`("foo.bar.MyEntity"))
             assertThat(entity.fields.size, `is`(1))
             val field = entity.fields.first()
             val intType = invocation.processingEnv.requireType(TypeName.INT)
@@ -79,6 +79,6 @@
             )
             assertThat(field.setter, `is`(FieldSetter(setterName, intType, CallType.METHOD)))
             assertThat(field.getter, `is`(FieldGetter(getterName, intType, CallType.METHOD)))
-        }.compilesWithoutError()
+        }
     }
 }
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
index bc6a765..9277733 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/TableEntityProcessorTest.kt
@@ -17,6 +17,7 @@
 package androidx.room.processor
 
 import COMMON
+import androidx.room.compiler.processing.util.Source
 import androidx.room.parser.SQLTypeAffinity
 import androidx.room.processor.ProcessorErrors.RELATION_IN_ENTITY
 import androidx.room.vo.CallType
@@ -27,7 +28,7 @@
 import androidx.room.vo.Index
 import androidx.room.vo.Pojo
 import androidx.room.vo.columnNames
-import com.google.testing.compile.JavaFileObjects
+import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.TypeName
 import compileLibrarySource
@@ -37,6 +38,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import toSources
 
 @RunWith(JUnit4::class)
 class TableEntityProcessorTest : BaseEntityParserTest() {
@@ -50,7 +52,7 @@
                 public void setId(int id) { this.id = id; }
             """
         ) { entity, invocation ->
-            assertThat(entity.type.toString(), `is`("foo.bar.MyEntity"))
+            assertThat(entity.type.typeName.toString(), `is`("foo.bar.MyEntity"))
             assertThat(entity.fields.size, `is`(1))
             val field = entity.fields.first()
             val intType = invocation.processingEnv.requireType(TypeName.INT)
@@ -69,7 +71,7 @@
             assertThat(field.setter, `is`(FieldSetter("setId", intType, CallType.METHOD)))
             assertThat(field.getter, `is`(FieldGetter("getId", intType, CallType.METHOD)))
             assertThat(entity.primaryKey.fields, `is`(Fields(field)))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -80,9 +82,11 @@
                 private int id;
                 public void setId(int id) {this.id = id;}
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD)
+            }
+        }
     }
 
     @Test
@@ -101,13 +105,16 @@
         singleEntity(
             "",
             baseClass = "test.library.MissingGetterEntity",
-            classpathFiles = libraryClasspath
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining(
-                ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD +
-                    " - id in test.library.MissingGetterEntity"
-            )
+            classpathFiles = libraryClasspath.toList()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD)
+                hasRawOutputContaining(
+                    ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD +
+                        " - id in test.library.MissingGetterEntity"
+                )
+            }
+        }
     }
 
     @Test
@@ -119,9 +126,11 @@
                 public float getId() {return 0f;}
                 public void setId(int id) {this.id = id;}
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD)
+            }
+        }
     }
 
     @Test
@@ -133,9 +142,11 @@
                 public int getId() {return id;}
                 public void setId(float id) {}
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD)
+            }
+        }
     }
 
     @Test
@@ -147,8 +158,9 @@
                 public int getId() {return id;}
                 public void setId(Integer id) {}
                 """
-        ) { _, _ -> }
-            .compilesWithoutError()
+        ) { entity, _ ->
+            assertThat(entity.fields.columnNames).contains("id")
+        }
     }
 
     @Test
@@ -160,8 +172,9 @@
                 public Integer getId() {return id;}
                 public void setId(int id) {}
                 """
-        ) { _, _ -> }
-            .compilesWithoutError()
+        ) { entity, _ ->
+            assertThat(entity.fields.columnNames).contains("id")
+        }
     }
 
     @Test
@@ -181,15 +194,17 @@
                 cursorValueReader.typeMirror().typeName,
                 `is`(invocation.processingEnv.requireType(TypeName.INT).typeName)
             )
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.mismatchedSetter(
-                    fieldName = "id",
-                    ownerType = ClassName.bestGuess("foo.bar.MyEntity"),
-                    setterType = TypeName.INT,
-                    fieldType = TypeName.INT.box()
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.mismatchedSetter(
+                        fieldName = "id",
+                        ownerType = ClassName.bestGuess("foo.bar.MyEntity"),
+                        setterType = TypeName.INT,
+                        fieldType = TypeName.INT.box()
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
@@ -209,7 +224,7 @@
                 statementBinder.typeMirror().typeName,
                 `is`(invocation.processingEnv.requireType(TypeName.INT).typeName)
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -220,9 +235,11 @@
                 private int id;
                 public int getId(){ return id; }
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_SETTER_FOR_FIELD)
+            }
+        }
     }
 
     @Test
@@ -235,9 +252,11 @@
                 public int getId(){ return id; }
                 public int id(){ return id; }
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining("getId, id")
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining("getId, id")
+            }
+        }
     }
 
     @Test
@@ -252,7 +271,7 @@
                 """
         ) { entity, _ ->
             assertThat(entity.fields.first().getter.name, `is`("getId"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -267,7 +286,7 @@
                 """
         ) { entity, _ ->
             assertThat(entity.fields.first().getter.name, `is`("getId"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -282,7 +301,7 @@
         ) { entity, _ ->
             assertThat(entity.fields.first().getter.name, `is`("id"))
             assertThat(entity.fields.first().getter.callType, `is`(CallType.FIELD))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -295,9 +314,11 @@
                 public void id(int id) {}
                 public int getId(){ return id; }
                 """
-        ) { _, _ -> }
-            .failsToCompile()
-            .withErrorContaining("setId, id")
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasErrorContaining("setId, id")
+            }
+        }
     }
 
     @Test
@@ -312,7 +333,7 @@
                 """
         ) { entity, _ ->
             assertThat(entity.fields.first().setter.name, `is`("setId"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -327,7 +348,7 @@
                 """
         ) { entity, _ ->
             assertThat(entity.fields.first().setter.name, `is`("setId"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -342,7 +363,7 @@
         ) { entity, _ ->
             assertThat(entity.fields.first().setter.name, `is`("id"))
             assertThat(entity.fields.first().setter.callType, `is`(CallType.FIELD))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -357,7 +378,7 @@
         ) { entity, _ ->
             assertThat(entity.fields.first().setter.name, `is`("setId"))
             assertThat(entity.fields.first().getter.name, `is`("getId"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -370,7 +391,7 @@
             hashMapOf(Pair("tableName", "\"foo_table\""))
         ) { entity, _ ->
             assertThat(entity.tableName, `is`("foo_table"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -381,8 +402,11 @@
                 int x;
                 """,
             hashMapOf(Pair("tableName", "\" \""))
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.ENTITY_TABLE_NAME_CANNOT_BE_EMPTY)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.ENTITY_TABLE_NAME_CANNOT_BE_EMPTY)
+            }
+        }
     }
 
     @Test
@@ -390,9 +414,11 @@
         singleEntity(
             """
                 """
-        ) { _, _ ->
-        }.failsToCompile()
-            .withErrorContaining(ProcessorErrors.MISSING_PRIMARY_KEY)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.MISSING_PRIMARY_KEY)
+            }
+        }
     }
 
     @Test
@@ -402,8 +428,11 @@
                 @PrimaryKey
                 public java.util.Date myDate;
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.CANNOT_FIND_COLUMN_TYPE_ADAPTER)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_FIND_COLUMN_TYPE_ADAPTER)
+            }
+        }
     }
 
     @Test
@@ -420,15 +449,16 @@
                     int y;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id")))
-        }.compilesWithoutError()
-            .withWarningCount(1)
-            .withWarningContaining(
-                ProcessorErrors.embeddedPrimaryKeyIsDropped(
-                    "foo.bar.MyEntity", "x"
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.embeddedPrimaryKeyIsDropped(
+                        "foo.bar.MyEntity", "x"
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
@@ -446,9 +476,12 @@
                     int y;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id")))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
@@ -463,7 +496,7 @@
             assertThat(field.name, `is`("name"))
             assertThat(field.columnName, `is`("name"))
             assertThat(field.nonNull, `is`(true))
-        }.compilesWithoutError()
+        }
     }
 
     private fun fieldsByName(entity: Pojo, vararg fieldNames: String): List<Field> {
@@ -495,7 +528,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -520,7 +553,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -548,7 +581,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -583,7 +616,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -611,7 +644,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -639,7 +672,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -668,7 +701,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -683,10 +716,11 @@
                 public String foo;
                 """,
             annotation
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.INDEX_COLUMNS_CANNOT_BE_EMPTY
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.INDEX_COLUMNS_CANNOT_BE_EMPTY)
+            }
+        }
     }
 
     @Test
@@ -701,10 +735,13 @@
                 public String foo;
                 """,
             annotation
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.indexColumnDoesNotExist("bar", listOf("id, foo"))
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.indexColumnDoesNotExist("bar", listOf("id, foo"))
+                )
+            }
+        }
     }
 
     @Test
@@ -720,17 +757,20 @@
                 public String foo;
                 """,
             annotation
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.duplicateIndexInEntity("index_MyEntity_foo")
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.duplicateIndexInEntity("index_MyEntity_foo")
+                )
+            }
+        }
     }
 
     @Test
     fun index_droppedParentFieldIndex() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 public class Base {
@@ -747,24 +787,26 @@
                 @PrimaryKey
                 public int id;
                 """,
-            baseClass = "foo.bar.Base", jfos = listOf(parent)
-        ) { entity, _ ->
+            baseClass = "foo.bar.Base", sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.droppedSuperClassFieldIndex(
-                    fieldName = "name",
-                    childEntity = "foo.bar.MyEntity",
-                    superEntity = "foo.bar.Base"
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.droppedSuperClassFieldIndex(
+                        fieldName = "name",
+                        childEntity = "foo.bar.MyEntity",
+                        superEntity = "foo.bar.Base"
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
     fun index_keptGrandParentEntityIndex() {
-        val grandParent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val grandParent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(indices = @Index({"name", "lastName"}))
@@ -775,9 +817,9 @@
                 }
                 """
         )
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Parent",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Parent",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
 
@@ -793,9 +835,8 @@
                 """,
             baseClass = "foo.bar.Parent",
             attributes = hashMapOf("inheritSuperIndices" to "true"),
-            jfos = listOf(parent, grandParent)
-        ) {
-            entity, _ ->
+            sources = listOf(parent, grandParent)
+        ) { entity, invocation ->
             assertThat(entity.indices.size, `is`(1))
             assertThat(
                 entity.indices.first(),
@@ -807,14 +848,17 @@
                     )
                 )
             )
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun index_keptParentEntityIndex() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(indices = @Index({"name", "lastName"}))
@@ -832,8 +876,8 @@
                 """,
             baseClass = "foo.bar.Base",
             attributes = hashMapOf("inheritSuperIndices" to "true"),
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.indices.size, `is`(1))
             assertThat(
                 entity.indices.first(),
@@ -845,14 +889,17 @@
                     )
                 )
             )
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun ignoredFields() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 public class Base {
@@ -869,18 +916,21 @@
                 """,
             baseClass = "foo.bar.Base",
             attributes = hashMapOf("ignoredColumns" to "{\"tmp1\", \"tmp2\"}"),
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.fields.size, `is`(2))
             assertThat(entity.fields.map(Field::name), hasItems("name", "id"))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun index_keptParentFieldIndex() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 public class Base {
@@ -899,8 +949,8 @@
                 """,
             baseClass = "foo.bar.Base",
             attributes = hashMapOf("inheritSuperIndices" to "true"),
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.indices.size, `is`(1))
             assertThat(
                 entity.indices.first(),
@@ -912,14 +962,17 @@
                     )
                 )
             )
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun index_droppedGrandParentEntityIndex() {
-        val grandParent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val grandParent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(indices = @Index({"name", "lastName"}))
@@ -930,9 +983,9 @@
                 }
                 """
         )
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Parent",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Parent",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
 
@@ -946,24 +999,25 @@
                 @PrimaryKey
                 public int id;
                 """,
-            baseClass = "foo.bar.Parent", jfos = listOf(parent, grandParent)
-        ) {
-            entity, _ ->
+            baseClass = "foo.bar.Parent", sources = listOf(parent, grandParent)
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.droppedSuperClassIndex(
-                    childEntity = "foo.bar.MyEntity",
-                    superEntity = "foo.bar.Base"
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.droppedSuperClassIndex(
+                        childEntity = "foo.bar.MyEntity",
+                        superEntity = "foo.bar.Base"
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
     fun index_droppedParentEntityIndex() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(indices = @Index({"name", "lastName"}))
@@ -979,16 +1033,18 @@
                 @PrimaryKey
                 public int id;
                 """,
-            baseClass = "foo.bar.Base", jfos = listOf(parent)
-        ) { entity, _ ->
+            baseClass = "foo.bar.Base", sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.droppedSuperClassIndex(
-                    childEntity = "foo.bar.MyEntity",
-                    superEntity = "foo.bar.Base"
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.droppedSuperClassIndex(
+                        childEntity = "foo.bar.MyEntity",
+                        superEntity = "foo.bar.Base"
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
@@ -1008,16 +1064,18 @@
                     public int a;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.droppedEmbeddedIndex(
-                    entityName = "foo.bar.MyEntity.Foo",
-                    fieldPath = "foo",
-                    grandParent = "foo.bar.MyEntity"
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.droppedEmbeddedIndex(
+                        entityName = "foo.bar.MyEntity.Foo",
+                        fieldPath = "foo",
+                        grandParent = "foo.bar.MyEntity"
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
@@ -1034,11 +1092,12 @@
                     public int a;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.CANNOT_USE_MORE_THAN_ONE_POJO_FIELD_ANNOTATION
-        )
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.CANNOT_USE_MORE_THAN_ONE_POJO_FIELD_ANNOTATION)
+            }
+        }
     }
 
     @Test
@@ -1054,12 +1113,14 @@
                     public int a;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.indices.isEmpty(), `is`(true))
-        }.compilesWithoutError()
-            .withWarningContaining(
-                ProcessorErrors.droppedEmbeddedFieldIndex("foo > a", "foo.bar.MyEntity")
-            )
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.droppedEmbeddedFieldIndex("foo > a", "foo.bar.MyEntity")
+                )
+            }
+        }
     }
 
     @Test
@@ -1087,7 +1148,7 @@
                     )
                 )
             )
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -1099,12 +1160,15 @@
                 public String foo;
                 """,
             attributes = mapOf("primaryKeys" to "\"id\"")
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.multiplePrimaryKeyAnnotations(
-                listOf("PrimaryKey[id]", "PrimaryKey[foo]")
-            )
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.multiplePrimaryKeyAnnotations(
+                        listOf("PrimaryKey[id]", "PrimaryKey[foo]")
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -1114,10 +1178,13 @@
                 public int id;
                 """,
             attributes = mapOf("primaryKeys" to "\"foo\"")
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.primaryKeyColumnDoesNotExist("foo", listOf("id"))
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.primaryKeyColumnDoesNotExist("foo", listOf("id"))
+                )
+            }
+        }
     }
 
     @Test
@@ -1129,21 +1196,23 @@
                 @PrimaryKey
                 int y;
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.isEmpty(), `is`(true))
-        }.failsToCompile()
-            .withErrorContaining(
-                ProcessorErrors.multiplePrimaryKeyAnnotations(
-                    listOf("PrimaryKey[x]", "PrimaryKey[y]")
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.multiplePrimaryKeyAnnotations(
+                        listOf("PrimaryKey[x]", "PrimaryKey[y]")
+                    )
                 )
-            )
+            }
+        }
     }
 
     @Test
     fun primaryKey_fromParentField() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 public class Base {
@@ -1158,17 +1227,20 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("baseId"))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun primaryKey_fromParentEntity() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(primaryKeys = "baseId")
@@ -1183,17 +1255,20 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("baseId"))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun primaryKey_overrideFromParentField() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 public class Base {
@@ -1209,21 +1284,22 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.size, `is`(1))
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
             assertThat(entity.primaryKey.autoGenerateId, `is`(false))
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[baseId] is overridden by PrimaryKey[id]"
-        )
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[baseId] is overridden by PrimaryKey[id]")
+            }
+        }
     }
 
     @Test
     fun primaryKey_overrideFromParentEntityViaField() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(primaryKeys = "baseId")
@@ -1239,20 +1315,21 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.size, `is`(1))
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[baseId] is overridden by PrimaryKey[id]"
-        )
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[baseId] is overridden by PrimaryKey[id]")
+            }
+        }
     }
 
     @Test
     fun primaryKey_overrideFromParentEntityViaEntity() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
                 @Entity(primaryKeys = "baseId")
@@ -1267,15 +1344,16 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent),
+            sources = listOf(parent),
             attributes = mapOf("primaryKeys" to "\"id\"")
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.size, `is`(1))
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
             assertThat(entity.primaryKey.autoGenerateId, `is`(false))
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[baseId] is overridden by PrimaryKey[id]"
-        )
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[baseId] is overridden by PrimaryKey[id]")
+            }
+        }
     }
 
     @Test
@@ -1290,7 +1368,7 @@
                 assertThat(entity.primaryKey.fields.size, `is`(1))
                 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
                 assertThat(entity.primaryKey.autoGenerateId, `is`(true))
-            }.compilesWithoutError()
+            }
         }
     }
 
@@ -1306,7 +1384,7 @@
                 assertThat(entity.primaryKey.fields.size, `is`(1))
                 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
                 assertThat(entity.primaryKey.autoGenerateId, `is`(false))
-            }.compilesWithoutError()
+            }
         }
     }
 
@@ -1318,13 +1396,14 @@
                 @PrimaryKey(autoGenerate = true)
                 public $type id;
                 """
-            ) { entity, _ ->
+            ) { entity, invocation ->
                 assertThat(entity.primaryKey.fields.size, `is`(1))
                 assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
                 assertThat(entity.primaryKey.autoGenerateId, `is`(true))
-            }.failsToCompile().withErrorContaining(
-                ProcessorErrors.AUTO_INCREMENTED_PRIMARY_KEY_IS_NOT_INT
-            )
+                invocation.assertCompilationResult {
+                    hasError(ProcessorErrors.AUTO_INCREMENTED_PRIMARY_KEY_IS_NOT_INT)
+                }
+            }
         }
     }
 
@@ -1344,16 +1423,19 @@
                     public int b;
                 }
                 """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.columnNames, `is`(listOf("bar_a", "bar_b")))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun primaryKey_embeddedInherited() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1378,17 +1460,20 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.columnNames, `is`(listOf("bar_a", "bar_b")))
-        }.compilesWithoutError().withWarningCount(0)
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
     fun primaryKey_overrideViaEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
 
@@ -1413,19 +1498,20 @@
                 }
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.columnNames, `is`(listOf("bar_a", "bar_b")))
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[baseId] is overridden by PrimaryKey[foo > a, foo > b]"
-        )
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[baseId] is overridden by PrimaryKey[foo > a, foo > b]")
+            }
+        }
     }
 
     @Test
     fun primaryKey_overrideEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1451,12 +1537,13 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { entity, _ ->
+            sources = listOf(parent)
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.columnNames, `is`(listOf("id")))
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[foo > a, foo > b] is overridden by PrimaryKey[id]"
-        )
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[foo > a, foo > b] is overridden by PrimaryKey[id]")
+            }
+        }
     }
 
     @Test
@@ -1470,7 +1557,7 @@
         ) { entity, _ ->
             assertThat(entity.primaryKey.fields.size, `is`(1))
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -1480,10 +1567,13 @@
             @PrimaryKey
             public String id;
             """
-        ) { entity, _ ->
+        ) { entity, invocation ->
             assertThat(entity.primaryKey.fields.size, `is`(1))
             assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("id"))
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("id"))
+            }
+        }
     }
 
     @Test
@@ -1495,9 +1585,12 @@
             @PrimaryKey
             public String anotherId;
             """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("id"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("anotherId"))
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("id"))
+                hasError(ProcessorErrors.primaryKeyNull("anotherId"))
+            }
+        }
     }
 
     @Test
@@ -1510,8 +1603,13 @@
             @PrimaryKey
             public String anotherId;
             """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("anotherId"))
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.primaryKeyNull("anotherId")
+                )
+            }
+        }
     }
 
     @Test
@@ -1522,8 +1620,11 @@
                 public String foo;
                 """,
             attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+            }
+        }
     }
 
     @Test
@@ -1537,7 +1638,7 @@
             attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")
         ) { entity, _ ->
             assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id", "foo")))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -1555,8 +1656,11 @@
                     public int b;
                 }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+            }
+        }
     }
 
     @Test
@@ -1574,11 +1678,14 @@
                     public String b;
                 }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > b"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorCount(3)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > b"))
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasErrorCount(3)
+            }
+        }
     }
 
     @Test
@@ -1601,19 +1708,22 @@
                 }
             }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > b"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a > bb"))
-            .and().withErrorCount(4)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > b"))
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > a > bb"))
+                hasErrorCount(4)
+            }
+        }
     }
 
     @Test
     fun primaryKey_nullableEmbeddedInherited() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1637,19 +1747,22 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > b"))
-            .and().withErrorCount(3)
+            sources = listOf(parent)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > b"))
+                hasErrorCount(3)
+            }
+        }
     }
 
     @Test
     fun primaryKey_nullableOverrideViaEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.room.*;
 
@@ -1673,22 +1786,23 @@
                 }
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > b"))
-            .and().withNoteContaining(
-                "PrimaryKey[baseId] is overridden by PrimaryKey[foo > a, foo > b]"
-            )
-            .and().withErrorCount(3)
+            sources = listOf(parent)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > b"))
+                hasNote("PrimaryKey[baseId] is overridden by PrimaryKey[foo > a, foo > b]")
+                hasErrorCount(3)
+            }
+        }
     }
 
     @Test
     fun primaryKey_nullableOverrideEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1713,22 +1827,23 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > b"))
-            .and().withNoteContaining(
-                "PrimaryKey[foo > a, foo > b] is overridden by PrimaryKey[id]"
-            )
-            .and().withErrorCount(3)
+            sources = listOf(parent)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > b"))
+                hasNote("PrimaryKey[foo > a, foo > b] is overridden by PrimaryKey[id]")
+                hasErrorCount(3)
+            }
+        }
     }
 
     @Test
     fun primaryKey_integerOverrideEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1752,18 +1867,19 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { _, _ ->
-        }.compilesWithoutError().withNoteContaining(
-            "PrimaryKey[foo > a] is overridden by PrimaryKey[id]"
-        )
+            sources = listOf(parent)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasNote("PrimaryKey[foo > a] is overridden by PrimaryKey[id]")
+            }
+        }
     }
 
     @Test
     fun primaryKey_singleStringPrimaryKeyOverrideEmbedded() {
-        val parent = JavaFileObjects.forSourceLines(
-            "foo.bar.Base",
-            """
+        val parent = Source.java(
+            qName = "foo.bar.Base",
+            code = """
                 package foo.bar;
                 import androidx.annotation.NonNull;
                 import androidx.room.*;
@@ -1787,14 +1903,15 @@
                 public int id;
                 """,
             baseClass = "foo.bar.Base",
-            jfos = listOf(parent)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
-            .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
-            .and().withNoteContaining(
-                "PrimaryKey[foo > a] is overridden by PrimaryKey[id]"
-            )
-            .and().withErrorCount(2)
+            sources = listOf(parent)
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.primaryKeyNull("foo"))
+                hasError(ProcessorErrors.primaryKeyNull("foo > a"))
+                hasNote("PrimaryKey[foo > a] is overridden by PrimaryKey[id]")
+                hasErrorCount(2)
+            }
+        }
     }
 
     @Test
@@ -1806,9 +1923,12 @@
                 @Relation(parentColumn = "id", entityColumn = "uid")
                 java.util.List<User> users;
                 """,
-            jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(RELATION_IN_ENTITY)
+            sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(RELATION_IN_ENTITY)
+            }
+        }
     }
 
     @Test
@@ -1828,9 +1948,12 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_FOREIGN_KEY_ACTION)
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.INVALID_FOREIGN_KEY_ACTION)
+            }
+        }
     }
 
     @Test
@@ -1849,9 +1972,13 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining("cannot find symbol")
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                compilationDidFail()
+                hasRawOutputContaining("cannot find symbol")
+            }
+        }
     }
 
     @Test
@@ -1870,13 +1997,16 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.NOT_AN_ENTITY)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.foreignKeyNotAnEntity(
-                COMMON.NOT_AN_ENTITY_TYPE_NAME.toString()
-            )
-        )
+            attributes = annotation, sources = listOf(COMMON.NOT_AN_ENTITY).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.foreignKeyNotAnEntity(
+                        COMMON.NOT_AN_ENTITY_TYPE_NAME.toString()
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -1895,13 +2025,16 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.foreignKeyChildColumnDoesNotExist(
-                "namex", listOf("id", "name")
-            )
-        )
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.foreignKeyChildColumnDoesNotExist(
+                        "namex", listOf("id", "name")
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -1920,13 +2053,16 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.foreignKeyColumnNumberMismatch(
-                listOf("name", "id"), listOf("lastName")
-            )
-        )
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.foreignKeyColumnNumberMismatch(
+                        listOf("name", "id"), listOf("lastName")
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -1945,9 +2081,12 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.FOREIGN_KEY_EMPTY_CHILD_COLUMN_LIST)
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.FOREIGN_KEY_EMPTY_CHILD_COLUMN_LIST)
+            }
+        }
     }
 
     @Test
@@ -1966,9 +2105,12 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.FOREIGN_KEY_EMPTY_PARENT_COLUMN_LIST)
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.FOREIGN_KEY_EMPTY_PARENT_COLUMN_LIST)
+            }
+        }
     }
 
     @Test
@@ -1990,7 +2132,7 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
         ) { entity, _ ->
             assertThat(entity.foreignKeys.size, `is`(1))
             val fKey = entity.foreignKeys.first()
@@ -2000,7 +2142,7 @@
             assertThat(fKey.childFields.size, `is`(1))
             val field = fKey.childFields.first()
             assertThat(field.name, `is`("name"))
-        }.compilesWithoutError()
+        }
     }
 
     @Test
@@ -2023,9 +2165,12 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.compilesWithoutWarnings()
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
@@ -2049,10 +2194,13 @@
                 String name;
                 String lName;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { entity, _ ->
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, invocation ->
             assertThat(entity.indices.size, `is`(1))
-        }.compilesWithoutWarnings()
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
@@ -2076,10 +2224,13 @@
                 String name;
                 String lName;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { entity, _ ->
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, invocation ->
             assertThat(entity.indices.size, `is`(1))
-        }.compilesWithoutWarnings()
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
@@ -2101,12 +2252,13 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { entity, _ ->
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, invocation ->
             assertThat(entity.indices, `is`(emptyList()))
-        }.compilesWithoutError().withWarningContaining(
-            ProcessorErrors.foreignKeyMissingIndexInChildColumn("name")
-        )
+            invocation.assertCompilationResult {
+                hasWarning(ProcessorErrors.foreignKeyMissingIndexInChildColumn("name"))
+            }
+        }
     }
 
     @Test
@@ -2126,12 +2278,20 @@
                 String name;
                 String lName;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { entity, _ ->
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, invocation ->
             assertThat(entity.indices, `is`(emptyList()))
-        }.compilesWithoutError().withWarningContaining(
-            ProcessorErrors.foreignKeyMissingIndexInChildColumns(listOf("lName", "name"))
-        )
+            invocation.assertCompilationResult {
+                hasWarning(
+                    ProcessorErrors.foreignKeyMissingIndexInChildColumns(
+                        listOf(
+                            "lName",
+                            "name"
+                        )
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -2153,10 +2313,13 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { entity, _ ->
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, invocation ->
             assertThat(entity.indices, `is`(emptyList()))
-        }.compilesWithoutWarnings()
+            invocation.assertCompilationResult {
+                hasNoWarnings()
+            }
+        }
     }
 
     @Test
@@ -2166,12 +2329,15 @@
                 @Embedded
                 MyEntity myEntity;
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
-                "foo.bar.MyEntity -> foo.bar.MyEntity"
-            )
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
+                        "foo.bar.MyEntity -> foo.bar.MyEntity"
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -2188,12 +2354,15 @@
                     List<MyEntity> myEntity;
                 }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
-                "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
-            )
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
+                        "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -2208,12 +2377,15 @@
                     MyEntity myEntity;
                 }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
-                "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
-            )
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
+                        "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -2229,12 +2401,15 @@
                     MyEntity myEntity;
                 }
                 """
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(
-            ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
-                "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
-            )
-        )
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(
+                    ProcessorErrors.RECURSIVE_REFERENCE_DETECTED.format(
+                        "foo.bar.MyEntity -> foo.bar.MyEntity.A -> foo.bar.MyEntity"
+                    )
+                )
+            }
+        }
     }
 
     @Test
@@ -2246,9 +2421,10 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.compilesWithoutError()
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { entity, _ ->
+            assertThat(entity.tableName).isEqualTo("foo bar")
+        }
     }
 
     @Test
@@ -2260,9 +2436,12 @@
                 int id;
                 String name;
                 """,
-            attributes = annotation, jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_TABLE_NAME)
+            attributes = annotation, sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.INVALID_TABLE_NAME)
+            }
+        }
     }
 
     @Test
@@ -2274,8 +2453,11 @@
                 @ColumnInfo(name = "\"foo bar\"")
                 String name;
                 """,
-            jfos = listOf(COMMON.USER)
-        ) { _, _ ->
-        }.failsToCompile().withErrorContaining(ProcessorErrors.INVALID_COLUMN_NAME)
+            sources = listOf(COMMON.USER).toSources()
+        ) { _, invocation ->
+            invocation.assertCompilationResult {
+                hasError(ProcessorErrors.INVALID_COLUMN_NAME)
+            }
+        }
     }
 }
diff --git a/room/compiler/src/test/kotlin/androidx/room/writer/EntityCursorConverterWriterTest.kt b/room/compiler/src/test/kotlin/androidx/room/writer/EntityCursorConverterWriterTest.kt
index 51a2f59..4be3b84 100644
--- a/room/compiler/src/test/kotlin/androidx/room/writer/EntityCursorConverterWriterTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/writer/EntityCursorConverterWriterTest.kt
@@ -16,9 +16,9 @@
 
 package androidx.room.writer
 
+import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.XTestInvocation
 import androidx.room.processor.BaseEntityParserTest
-import com.google.testing.compile.CompileTester
-import com.google.testing.compile.JavaFileObjects
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.TypeSpec
 import org.junit.Test
@@ -89,24 +89,29 @@
         )
     }
 
-    fun generateAndMatch(
+    private fun generateAndMatch(
         input: String,
         output: String,
         attributes: Map<String, String> = mapOf()
     ) {
-        generate(input, attributes)
-            .compilesWithoutError()
-            .and()
-            .generatesSources(
-                JavaFileObjects.forSourceString(
-                    "foo.bar.MyEntity_CursorConverter",
-                    listOf(OUT_PREFIX, output, OUT_SUFFIX).joinToString("\n")
+        generate(input, attributes) {
+            it.assertCompilationResult {
+                generatedSource(
+                    Source.java(
+                        qName = "foo.bar.MyContainerClass",
+                        code = listOf(OUT_PREFIX, output, OUT_SUFFIX).joinToString("\n")
+                    )
                 )
-            )
+            }
+        }
     }
 
-    fun generate(input: String, attributes: Map<String, String> = mapOf()): CompileTester {
-        return singleEntity(input, attributes) { entity, invocation ->
+    private fun generate(
+        input: String,
+        attributes: Map<String, String> = mapOf(),
+        handler: (XTestInvocation) -> Unit
+    ) {
+        singleEntity(input, attributes) { entity, invocation ->
             val className = ClassName.get("foo.bar", "MyContainerClass")
             val writer = object : ClassWriter(className) {
                 override fun createTypeSpecBuilder(): TypeSpec.Builder {
@@ -117,6 +122,7 @@
                 }
             }
             writer.write(invocation.processingEnv)
+            handler(invocation)
         }
     }
 }