12259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar/* 22259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Copyright (C) 2016 The Android Open Source Project 32259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * 42259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 52259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * you may not use this file except in compliance with the License. 62259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * You may obtain a copy of the License at 72259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * 82259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 92259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * 102259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Unless required by applicable law or agreed to in writing, software 112259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 122259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * See the License for the specific language governing permissions and 142259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * limitations under the License. 152259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar */ 162259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.persistence.room.solver 182259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 193c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport COMMON 2064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Entity 2164db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.L 2264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.LifecyclesTypeNames 239fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.ext.PagingTypeNames 2464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.ReactiveStreamsTypeNames 2564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.RoomTypeNames.STRING_UTIL 2664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.RxJava2TypeNames 2764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.T 281676c28584028f8427475745d7a779607af67ecbYigit Boyarimport android.arch.persistence.room.parser.SQLTypeAffinity 2964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.processor.Context 3064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.processor.ProcessorErrors 3124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.arch.persistence.room.solver.binderprovider.DataSourceQueryResultBinderProvider 329fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.solver.binderprovider.FlowableQueryResultBinderProvider 339fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.solver.binderprovider.LiveDataQueryResultBinderProvider 3424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.arch.persistence.room.solver.binderprovider.LivePagedListQueryResultBinderProvider 3564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.solver.types.CompositeAdapter 3664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.solver.types.TypeConverter 3764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.testing.TestInvocation 3864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.testing.TestProcessor 39ef346ae131affbba6345e00d833103acc5743c8aChris Craikimport android.arch.paging.DataSource 40abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyarimport android.arch.paging.TiledDataSource 413c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport com.google.auto.common.MoreTypes 422259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.common.truth.Truth 432259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.CompileTester 442259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.JavaFileObjects 452259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.JavaSourcesSubjectFactory 46aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.`is` 47aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.instanceOf 48aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.notNullValue 49fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyarimport org.hamcrest.CoreMatchers.nullValue 502259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.hamcrest.MatcherAssert.assertThat 512259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.Test 522259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.runner.RunWith 532259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.runners.JUnit4 543c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport simpleRun 55645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyarimport testCodeGenScope 562259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport javax.annotation.processing.ProcessingEnvironment 572259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport javax.lang.model.type.TypeKind 582259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 592259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") 602259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar@RunWith(JUnit4::class) 612259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarclass TypeAdapterStoreTest { 622259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar companion object { 632259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun tmp(index: Int) = CodeGenScope._tmpVar(index) 642259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 652259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 662259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Test 672259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun testDirect() { 682259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar singleRun { invocation -> 697a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar val store = TypeAdapterStore.create(Context(invocation.processingEnv)) 702259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar val primitiveType = invocation.processingEnv.typeUtils.getPrimitiveType(TypeKind.INT) 71275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val adapter = store.findColumnTypeAdapter(primitiveType, null) 722259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, notNullValue()) 732259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar }.compilesWithoutError() 742259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 752259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 762259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Test 772259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun testVia1TypeAdapter() { 782259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar singleRun { invocation -> 797a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar val store = TypeAdapterStore.create(Context(invocation.processingEnv)) 802259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar val booleanType = invocation.processingEnv.typeUtils 812259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .getPrimitiveType(TypeKind.BOOLEAN) 82275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val adapter = store.findColumnTypeAdapter(booleanType, null) 832259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, notNullValue()) 842259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, instanceOf(CompositeAdapter::class.java)) 85645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar val bindScope = testCodeGenScope() 86efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope) 872259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(bindScope.generate().trim(), `is`(""" 882259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar final int ${tmp(0)}; 892259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ${tmp(0)} = fooVar ? 1 : 0; 902259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar stmt.bindLong(41, ${tmp(0)}); 912259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """.trimIndent())) 922259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 93645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar val cursorScope = testCodeGenScope() 94efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar adapter.readFromCursor("res", "curs", "7", cursorScope) 952259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(cursorScope.generate().trim(), `is`(""" 962259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar final int ${tmp(0)}; 972259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ${tmp(0)} = curs.getInt(7); 982259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar res = ${tmp(0)} != 0; 992259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """.trimIndent())) 1002259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar }.compilesWithoutError() 1012259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 1022259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 1032259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Test 1042259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun testVia2TypeAdapters() { 1052259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar singleRun { invocation -> 1067a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar val store = TypeAdapterStore.create(Context(invocation.processingEnv), 107fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar pointTypeConverters(invocation.processingEnv)) 1082259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar val pointType = invocation.processingEnv.elementUtils 1092259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .getTypeElement("foo.bar.Point").asType() 110275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val adapter = store.findColumnTypeAdapter(pointType, null) 1112259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, notNullValue()) 1122259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, instanceOf(CompositeAdapter::class.java)) 1132259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 114645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar val bindScope = testCodeGenScope() 115efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope) 1162259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(bindScope.generate().trim(), `is`(""" 1178e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar final int ${tmp(0)}; 1188e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar final boolean ${tmp(1)}; 1198e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar ${tmp(1)} = foo.bar.Point.toBoolean(fooVar); 1208e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar ${tmp(0)} = ${tmp(1)} ? 1 : 0; 1218e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar stmt.bindLong(41, ${tmp(0)}); 1222259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """.trimIndent())) 1232259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 124645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar val cursorScope = testCodeGenScope() 125efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar adapter.readFromCursor("res", "curs", "11", cursorScope).toString() 1262259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(cursorScope.generate().trim(), `is`(""" 1272259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar final int ${tmp(0)}; 1282259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ${tmp(0)} = curs.getInt(11); 1292259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar final boolean ${tmp(1)}; 1302259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ${tmp(1)} = ${tmp(0)} != 0; 1312259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar res = foo.bar.Point.fromBoolean(${tmp(1)}); 1322259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """.trimIndent())) 1332259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar }.compilesWithoutError() 1342259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 1352259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 1362259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Test 1371676c28584028f8427475745d7a779607af67ecbYigit Boyar fun testDate() { 1381676c28584028f8427475745d7a779607af67ecbYigit Boyar singleRun { (processingEnv) -> 1391676c28584028f8427475745d7a779607af67ecbYigit Boyar val store = TypeAdapterStore.create(Context(processingEnv), 1401676c28584028f8427475745d7a779607af67ecbYigit Boyar dateTypeConverters(processingEnv)) 1411676c28584028f8427475745d7a779607af67ecbYigit Boyar val tDate = processingEnv.elementUtils.getTypeElement("java.util.Date").asType() 1421676c28584028f8427475745d7a779607af67ecbYigit Boyar val adapter = store.findCursorValueReader(tDate, SQLTypeAffinity.INTEGER) 1431676c28584028f8427475745d7a779607af67ecbYigit Boyar assertThat(adapter, notNullValue()) 1441676c28584028f8427475745d7a779607af67ecbYigit Boyar assertThat(adapter?.typeMirror(), `is`(tDate)) 1451676c28584028f8427475745d7a779607af67ecbYigit Boyar val bindScope = testCodeGenScope() 1461676c28584028f8427475745d7a779607af67ecbYigit Boyar adapter!!.readFromCursor("outDate", "curs", "0", bindScope) 1471676c28584028f8427475745d7a779607af67ecbYigit Boyar assertThat(bindScope.generate().trim(), `is`(""" 1481676c28584028f8427475745d7a779607af67ecbYigit Boyar final java.lang.Long _tmp; 1491676c28584028f8427475745d7a779607af67ecbYigit Boyar if (curs.isNull(0)) { 1501676c28584028f8427475745d7a779607af67ecbYigit Boyar _tmp = null; 1511676c28584028f8427475745d7a779607af67ecbYigit Boyar } else { 1521676c28584028f8427475745d7a779607af67ecbYigit Boyar _tmp = curs.getLong(0); 1531676c28584028f8427475745d7a779607af67ecbYigit Boyar } 1541676c28584028f8427475745d7a779607af67ecbYigit Boyar // convert Long to Date; 1551676c28584028f8427475745d7a779607af67ecbYigit Boyar """.trimIndent())) 1561676c28584028f8427475745d7a779607af67ecbYigit Boyar }.compilesWithoutError() 1571676c28584028f8427475745d7a779607af67ecbYigit Boyar } 1581676c28584028f8427475745d7a779607af67ecbYigit Boyar 1591676c28584028f8427475745d7a779607af67ecbYigit Boyar @Test 1602259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun testIntList() { 1612259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar singleRun { invocation -> 162fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val binders = createIntListToStringBinders(invocation) 1637a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar val store = TypeAdapterStore.create(Context(invocation.processingEnv), binders[0], 164fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar binders[1]) 165fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 166275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val adapter = store.findColumnTypeAdapter(binders[0].from, null) 1672259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(adapter, notNullValue()) 1682259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 169645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar val bindScope = testCodeGenScope() 170efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope) 1712259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar assertThat(bindScope.generate().trim(), `is`(""" 17264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar final java.lang.String ${tmp(0)}; 17364db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar ${tmp(0)} = android.arch.persistence.room.util.StringUtil.joinIntoString(fooVar); 17464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar if (${tmp(0)} == null) { 17564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar stmt.bindNull(41); 17664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar } else { 17764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar stmt.bindString(41, ${tmp(0)}); 17864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar } 17964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar """.trimIndent())) 180fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 181fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val converter = store.findTypeConverter(binders[0].from, 182fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar invocation.context.COMMON_TYPES.STRING) 183fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(converter, notNullValue()) 184fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(store.reverse(converter!!), `is`(binders[1])) 185fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 1862259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar }.compilesWithoutError() 1872259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 1882259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 189fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar @Test 190fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar fun testOneWayConversion() { 191fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar singleRun { invocation -> 192fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val binders = createIntListToStringBinders(invocation) 1937a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar val store = TypeAdapterStore.create(Context(invocation.processingEnv), binders[0]) 194275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val adapter = store.findColumnTypeAdapter(binders[0].from, null) 195fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(adapter, nullValue()) 196fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 197275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val stmtBinder = store.findStatementValueBinder(binders[0].from, null) 198fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(stmtBinder, notNullValue()) 199fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 200fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val converter = store.findTypeConverter(binders[0].from, 201fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar invocation.context.COMMON_TYPES.STRING) 202fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(converter, notNullValue()) 203fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar assertThat(store.reverse(converter!!), nullValue()) 204fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 205fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 206fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 2073c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar @Test 2083c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar fun testMissingRxRoom() { 2093c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE)) { invocation -> 2103c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar val publisherElement = invocation.processingEnv.elementUtils 2113c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar .getTypeElement(ReactiveStreamsTypeNames.PUBLISHER.toString()) 2123c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar assertThat(publisherElement, notNullValue()) 2139fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik assertThat(FlowableQueryResultBinderProvider(invocation.context).matches( 2143c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar MoreTypes.asDeclared(publisherElement.asType())), `is`(true)) 2153c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar }.failsToCompile().withErrorContaining(ProcessorErrors.MISSING_ROOM_RXJAVA2_ARTIFACT) 2163c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar } 2173c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar 2183c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar @Test 2193c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar fun testFindPublisher() { 2203c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE, COMMON.RX2_ROOM)) { 2213c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar invocation -> 2223c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar val publisher = invocation.processingEnv.elementUtils 2233c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar .getTypeElement(ReactiveStreamsTypeNames.PUBLISHER.toString()) 2243c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar assertThat(publisher, notNullValue()) 2259fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik assertThat(FlowableQueryResultBinderProvider(invocation.context).matches( 2263c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar MoreTypes.asDeclared(publisher.asType())), `is`(true)) 2273c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar }.compilesWithoutError() 2283c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar } 2293c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar 2303c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar @Test 2313c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar fun testFindFlowable() { 2323c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE, COMMON.RX2_ROOM)) { 2333c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar invocation -> 2343c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar val flowable = invocation.processingEnv.elementUtils 2353c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar .getTypeElement(RxJava2TypeNames.FLOWABLE.toString()) 2363c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar assertThat(flowable, notNullValue()) 2379fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik assertThat(FlowableQueryResultBinderProvider(invocation.context).matches( 2383c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar MoreTypes.asDeclared(flowable.asType())), `is`(true)) 2393c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar }.compilesWithoutError() 2403c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar } 2413c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar 2423c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar @Test 2433c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar fun testFindLiveData() { 2443c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar simpleRun(jfos = *arrayOf(COMMON.COMPUTABLE_LIVE_DATA, COMMON.LIVE_DATA)) { 2453c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar invocation -> 2463c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar val liveData = invocation.processingEnv.elementUtils 2473c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar .getTypeElement(LifecyclesTypeNames.LIVE_DATA.toString()) 2483c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar assertThat(liveData, notNullValue()) 2499fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik assertThat(LiveDataQueryResultBinderProvider(invocation.context).matches( 2503c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar MoreTypes.asDeclared(liveData.asType())), `is`(true)) 2513c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar }.compilesWithoutError() 2523c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar } 2533c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar 2549fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik @Test 255abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar fun findDataSource() { 2569fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik simpleRun { 2579fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik invocation -> 25824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik val dataSource = invocation.processingEnv.elementUtils 25924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik .getTypeElement(DataSource::class.java.canonicalName) 26024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik assertThat(dataSource, notNullValue()) 26124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik assertThat(DataSourceQueryResultBinderProvider(invocation.context).matches( 262abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar MoreTypes.asDeclared(dataSource.asType())), `is`(true)) 263abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar }.failsToCompile().withErrorContaining(ProcessorErrors.PAGING_SPECIFY_DATA_SOURCE_TYPE) 264abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar } 265abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar 266abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar @Test 267abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar fun findTiledDataSource() { 268abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar simpleRun { 269abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar invocation -> 270abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar val dataSource = invocation.processingEnv.elementUtils 271abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar .getTypeElement(TiledDataSource::class.java.canonicalName) 272abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar assertThat(dataSource, notNullValue()) 273abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar assertThat(DataSourceQueryResultBinderProvider(invocation.context).matches( 27424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik MoreTypes.asDeclared(dataSource.asType())), `is`(true)) 2759fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik }.compilesWithoutError() 2769fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik } 2779fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik 2789fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik @Test 27924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik fun findPagedListProvider() { 28024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik simpleRun(jfos = COMMON.LIVE_PAGED_LIST_PROVIDER) { 2819fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik invocation -> 28224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik val pagedListProvider = invocation.processingEnv.elementUtils 28324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik .getTypeElement(PagingTypeNames.LIVE_PAGED_LIST_PROVIDER.toString()) 28424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik assertThat(pagedListProvider, notNullValue()) 28524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik assertThat(LivePagedListQueryResultBinderProvider(invocation.context).matches( 28624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik MoreTypes.asDeclared(pagedListProvider.asType())), `is`(true)) 2879fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik }.compilesWithoutError() 2889fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik } 2899fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik 290fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar private fun createIntListToStringBinders(invocation: TestInvocation): List<TypeConverter> { 291fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val intType = invocation.processingEnv.elementUtils 292fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar .getTypeElement(Integer::class.java.canonicalName) 293fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar .asType() 294fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val listType = invocation.processingEnv.elementUtils 295fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar .getTypeElement(java.util.List::class.java.canonicalName) 296fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val listOfInts = invocation.processingEnv.typeUtils.getDeclaredType(listType, intType) 297fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 298fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val intListConverter = object : TypeConverter(listOfInts, 299fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar invocation.context.COMMON_TYPES.STRING) { 300fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar override fun convert(inputVarName: String, outputVarName: String, 301fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope: CodeGenScope) { 302fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope.builder().apply { 303fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar addStatement("$L = $T.joinIntoString($L)", outputVarName, STRING_UTIL, 304fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar inputVarName) 305fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 306fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 307fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 308fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 309fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val stringToIntListConverter = object : TypeConverter( 310fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar invocation.context.COMMON_TYPES.STRING, listOfInts) { 311fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar override fun convert(inputVarName: String, outputVarName: String, 312fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope: CodeGenScope) { 313fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope.builder().apply { 314fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar addStatement("$L = $T.splitToIntList($L)", outputVarName, STRING_UTIL, 315fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar inputVarName) 316fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 317fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 318fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 319fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar return listOf(intListConverter, stringToIntListConverter) 320fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 321fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar 3222259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar fun singleRun(handler: (TestInvocation) -> Unit): CompileTester { 3232259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources()) 3242259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .that(listOf(JavaFileObjects.forSourceString("foo.bar.DummyClass", 3252259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """ 3262259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar package foo.bar; 32764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar import android.arch.persistence.room.*; 3282259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Entity 3292259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public class DummyClass {} 3302259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """ 3312259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ), JavaFileObjects.forSourceString("foo.bar.Point", 3322259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """ 3332259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar package foo.bar; 33464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar import android.arch.persistence.room.*; 3352259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar @Entity 3362259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public class Point { 3372259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public int x, y; 3382259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public Point(int x, int y) { 3392259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar this.x = x; 3402259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar this.y = y; 3412259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3422259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public static Point fromBoolean(boolean val) { 3432259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar return val ? new Point(1, 1) : new Point(0, 0); 3442259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3452259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar public static boolean toBoolean(Point point) { 3462259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar return point.x > 0; 3472259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3482259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3492259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar """ 3502259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar ))) 3512259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .processedWith(TestProcessor.builder() 3522259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .forAnnotations(Entity::class) 3532259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .nextRunHandler { invocation -> 3542259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar handler(invocation) 3552259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar true 3562259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3572259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar .build()) 3582259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3592259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 360fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar fun pointTypeConverters(env: ProcessingEnvironment): List<TypeConverter> { 361fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val tPoint = env.elementUtils.getTypeElement("foo.bar.Point").asType() 362fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar val tBoolean = env.typeUtils.getPrimitiveType(TypeKind.BOOLEAN) 363fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar return listOf( 364fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar object : TypeConverter(tPoint, tBoolean) { 365fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar override fun convert(inputVarName: String, outputVarName: String, 366fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope: CodeGenScope) { 367fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope.builder().apply { 368fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar addStatement("$L = $T.toBoolean($L)", outputVarName, from, inputVarName) 369fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 370fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 3712259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar 372fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar }, 373fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar object : TypeConverter(tBoolean, tPoint) { 374fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar override fun convert(inputVarName: String, outputVarName: String, 375fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope: CodeGenScope) { 376fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar scope.builder().apply { 377fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar addStatement("$L = $T.fromBoolean($L)", outputVarName, tPoint, 378fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar inputVarName) 379fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 380fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 381fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar } 382fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar ) 3832259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar } 3841676c28584028f8427475745d7a779607af67ecbYigit Boyar 3851676c28584028f8427475745d7a779607af67ecbYigit Boyar fun dateTypeConverters(env: ProcessingEnvironment): List<TypeConverter> { 3861676c28584028f8427475745d7a779607af67ecbYigit Boyar val tDate = env.elementUtils.getTypeElement("java.util.Date").asType() 3871676c28584028f8427475745d7a779607af67ecbYigit Boyar val tLong = env.elementUtils.getTypeElement("java.lang.Long").asType() 3881676c28584028f8427475745d7a779607af67ecbYigit Boyar return listOf( 3891676c28584028f8427475745d7a779607af67ecbYigit Boyar object : TypeConverter(tDate, tLong) { 3901676c28584028f8427475745d7a779607af67ecbYigit Boyar override fun convert(inputVarName: String, outputVarName: String, 3911676c28584028f8427475745d7a779607af67ecbYigit Boyar scope: CodeGenScope) { 3921676c28584028f8427475745d7a779607af67ecbYigit Boyar scope.builder().apply { 3931676c28584028f8427475745d7a779607af67ecbYigit Boyar addStatement("// convert Date to Long") 3941676c28584028f8427475745d7a779607af67ecbYigit Boyar } 3951676c28584028f8427475745d7a779607af67ecbYigit Boyar } 3961676c28584028f8427475745d7a779607af67ecbYigit Boyar 3971676c28584028f8427475745d7a779607af67ecbYigit Boyar }, 3981676c28584028f8427475745d7a779607af67ecbYigit Boyar object : TypeConverter(tLong, tDate) { 3991676c28584028f8427475745d7a779607af67ecbYigit Boyar override fun convert(inputVarName: String, outputVarName: String, 4001676c28584028f8427475745d7a779607af67ecbYigit Boyar scope: CodeGenScope) { 4011676c28584028f8427475745d7a779607af67ecbYigit Boyar scope.builder().apply { 4021676c28584028f8427475745d7a779607af67ecbYigit Boyar addStatement("// convert Long to Date") 4031676c28584028f8427475745d7a779607af67ecbYigit Boyar } 4041676c28584028f8427475745d7a779607af67ecbYigit Boyar } 4051676c28584028f8427475745d7a779607af67ecbYigit Boyar } 4061676c28584028f8427475745d7a779607af67ecbYigit Boyar ) 4071676c28584028f8427475745d7a779607af67ecbYigit Boyar } 4082259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar} 409