1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import android.arch.persistence.room.ColumnInfo 18import android.arch.persistence.room.Embedded 19import android.arch.persistence.room.Entity 20import android.arch.persistence.room.PrimaryKey 21import android.arch.persistence.room.Query 22import android.arch.persistence.room.Relation 23import android.arch.persistence.room.ext.LifecyclesTypeNames 24import android.arch.persistence.room.ext.PagingTypeNames 25import android.arch.persistence.room.ext.ReactiveStreamsTypeNames 26import android.arch.persistence.room.ext.RoomRxJava2TypeNames 27import android.arch.persistence.room.ext.RxJava2TypeNames 28import android.arch.persistence.room.processor.EntityProcessor 29import android.arch.persistence.room.solver.CodeGenScope 30import android.arch.persistence.room.testing.TestInvocation 31import android.arch.persistence.room.testing.TestProcessor 32import android.arch.persistence.room.verifier.DatabaseVerifier 33import android.arch.persistence.room.writer.ClassWriter 34import com.google.auto.common.MoreElements 35import com.google.common.truth.Truth 36import com.google.testing.compile.CompileTester 37import com.google.testing.compile.JavaFileObjects 38import com.google.testing.compile.JavaSourcesSubjectFactory 39import com.squareup.javapoet.ClassName 40import org.mockito.Mockito 41import org.mockito.Mockito.doReturn 42import org.mockito.Mockito.mock 43import java.io.File 44import javax.lang.model.element.Element 45import javax.lang.model.type.TypeKind 46import javax.lang.model.type.TypeMirror 47import javax.tools.JavaFileObject 48 49object COMMON { 50 val USER by lazy { 51 loadJavaCode("common/input/User.java", "foo.bar.User") 52 } 53 val USER_TYPE_NAME by lazy { 54 ClassName.get("foo.bar", "User") 55 } 56 val BOOK by lazy { 57 loadJavaCode("common/input/Book.java", "foo.bar.Book") 58 } 59 val NOT_AN_ENTITY by lazy { 60 loadJavaCode("common/input/NotAnEntity.java", "foo.bar.NotAnEntity") 61 } 62 63 val NOT_AN_ENTITY_TYPE_NAME by lazy { 64 ClassName.get("foo.bar", "NotAnEntity") 65 } 66 67 val MULTI_PKEY_ENTITY by lazy { 68 loadJavaCode("common/input/MultiPKeyEntity.java", "MultiPKeyEntity") 69 } 70 val LIVE_DATA by lazy { 71 loadJavaCode("common/input/LiveData.java", LifecyclesTypeNames.LIVE_DATA.toString()) 72 } 73 val COMPUTABLE_LIVE_DATA by lazy { 74 loadJavaCode("common/input/ComputableLiveData.java", 75 LifecyclesTypeNames.COMPUTABLE_LIVE_DATA.toString()) 76 } 77 val PUBLISHER by lazy { 78 loadJavaCode("common/input/reactivestreams/Publisher.java", 79 ReactiveStreamsTypeNames.PUBLISHER.toString()) 80 } 81 val FLOWABLE by lazy { 82 loadJavaCode("common/input/rxjava2/Flowable.java", RxJava2TypeNames.FLOWABLE.toString()) 83 } 84 85 val RX2_ROOM by lazy { 86 loadJavaCode("common/input/Rx2Room.java", RoomRxJava2TypeNames.RX_ROOM.toString()) 87 } 88 89 val LIVE_PAGED_LIST_PROVIDER by lazy { 90 loadJavaCode("common/input/LivePagedListProvider.java", 91 PagingTypeNames.LIVE_PAGED_LIST_PROVIDER.toString()) 92 } 93} 94fun testCodeGenScope(): CodeGenScope { 95 return CodeGenScope(Mockito.mock(ClassWriter::class.java)) 96} 97 98fun simpleRun(vararg jfos : JavaFileObject, f: (TestInvocation) -> Unit): CompileTester { 99 return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources()) 100 .that(jfos.toList() + JavaFileObjects.forSourceString("foo.bar.MyClass", 101 """ 102 package foo.bar; 103 abstract public class MyClass { 104 @android.arch.persistence.room.Query("foo") 105 abstract public void setFoo(String foo); 106 } 107 """)) 108 .processedWith(TestProcessor.builder() 109 .nextRunHandler { 110 f(it) 111 true 112 } 113 .forAnnotations(Query::class, PrimaryKey::class, Embedded::class, 114 ColumnInfo::class, Relation::class, Entity::class) 115 .build()) 116} 117 118fun loadJavaCode(fileName : String, qName : String) : JavaFileObject { 119 val contents = File("src/test/data/$fileName").readText(Charsets.UTF_8) 120 return JavaFileObjects.forSourceString(qName, contents) 121} 122 123fun createVerifierFromEntities(invocation: TestInvocation) : DatabaseVerifier { 124 val entities = invocation.roundEnv.getElementsAnnotatedWith(Entity::class.java).map { 125 EntityProcessor(invocation.context, MoreElements.asType(it)).process() 126 } 127 return DatabaseVerifier.create(invocation.context, Mockito.mock(Element::class.java), 128 entities)!! 129} 130 131/** 132 * Create mocks of [Element] and [TypeMirror] so that they can be used for instantiating a fake 133 * [android.arch.persistence.room.vo.Field]. 134 */ 135fun mockElementAndType(): Pair<Element, TypeMirror> { 136 val element = mock(Element::class.java) 137 val type = mock(TypeMirror::class.java) 138 doReturn(TypeKind.DECLARED).`when`(type).kind 139 doReturn(type).`when`(element).asType() 140 return element to type 141} 142