-
Notifications
You must be signed in to change notification settings - Fork 728
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate model factory methods (#450)
* Generate model factory methods * [modelfactory] Add explicit getId() method to ModelProperties * [modelfactory] Convert ModelProperties to Kotlin * [modelfactory] Replace getDrawable with getDrawableRes * [modelfactory] ProcessorTestUtils: remove unnecessary Kotlin interop annotations * [modelfactory] Support attribute groups if they don't have multiple attributes of a supported type * [modelfactory] Add error message * [modelfactory] Misc * [modelfactory] Convert ModelProperties back to Java to fix uploadArchives issue * [modelfactory] Fix CharSequence/String type checks * [modelfactory] Add support for lists of Epoxy models * [modelfactory] Fix support for "legacy" models (non @ModelView) * [modelfactory] Add Kotlin view test * [modelfactory] Address PR feedback
- Loading branch information
1 parent
8cdd359
commit ed916a0
Showing
44 changed files
with
4,713 additions
and
469 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import org.gradle.internal.jvm.Jvm | ||
|
||
apply plugin: 'com.android.library' | ||
apply from: 'build.workaround-missing-resource.gradle' | ||
apply plugin: 'kotlin-android' | ||
apply plugin: 'kotlin-kapt' | ||
|
||
android { | ||
compileSdkVersion rootProject.COMPILE_SDK_VERSION | ||
|
||
defaultConfig { | ||
minSdkVersion rootProject.MIN_SDK_VERSION | ||
targetSdkVersion rootProject.TARGET_SDK_VERSION | ||
} | ||
} | ||
|
||
configurations.all { strategy -> | ||
strategy.resolutionStrategy.force rootProject.deps.junit, rootProject.deps.robolectric, | ||
rootProject.deps.mockito | ||
} | ||
|
||
dependencies { | ||
compile project(':epoxy-adapter') | ||
compile rootProject.deps.paris | ||
|
||
testCompile project(':epoxy-adapter') | ||
// Need to include the processor directly since we create an instance of it in code for testing | ||
testCompile project(':epoxy-processor') | ||
testCompile project(':epoxy-processortest') | ||
testCompile rootProject.deps.googleTestingCompile | ||
testCompile rootProject.deps.junit | ||
testCompile rootProject.deps.kotlin | ||
// Need to include the processor directly since we create an instance of it in code for testing | ||
testCompile rootProject.deps.parisProcessor | ||
testCompile rootProject.deps.robolectric | ||
testCompile files(getRuntimeJar()) | ||
testCompile files(Jvm.current().getToolsJar()) | ||
|
||
kaptTest project(':epoxy-processor') | ||
} | ||
|
||
// Javadoc isn't working well with Kotlin :( | ||
tasks.withType(Javadoc).all { enabled = false } | ||
|
||
static def getRuntimeJar() { | ||
try { | ||
final File javaBase = new File(System.getProperty("java.home")).getCanonicalFile() | ||
File runtimeJar = new File(javaBase, "lib/rt.jar") | ||
if (runtimeJar.exists()) { | ||
return runtimeJar | ||
} | ||
runtimeJar = new File(javaBase, "jre/lib/rt.jar") | ||
return runtimeJar.exists() ? runtimeJar : null | ||
} catch (IOException e) { | ||
throw new RuntimeException(e) | ||
} | ||
} | ||
|
||
apply from: rootProject.file('gradle/gradle-maven-push.gradle') |
23 changes: 23 additions & 0 deletions
23
epoxy-modelfactory/build.workaround-missing-resource.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Source - https://github.com/nenick/AndroidStudioAndRobolectric/blob/master/app/build.workaround-missing-resource.gradle | ||
// Workaround for missing test resources when running unit tests within android studio. | ||
// This copies the test resources next to the test classes for each variant. | ||
// Tracked at https://github.com/nenick/AndroidStudioAndRobolectric/issues/7 | ||
// Original solution comes from https://code.google.com/p/android/issues/detail?id=136013#c10 | ||
// See also https://code.google.com/p/android/issues/detail?id=64887 | ||
gradle.projectsEvaluated { | ||
// Base path which is recognized by android studio. | ||
def testClassesPath = "${buildDir}/intermediates/classes/test/" | ||
// Copy must be done for each variant. | ||
def variants = android.libraryVariants.collect() | ||
|
||
variants.each { variant -> | ||
def variationName = variant.name.capitalize() | ||
def variationPath = variant.buildType.name | ||
|
||
// Specific copy task for each variant | ||
def copyTestResourcesTask = project.tasks.create("copyTest${variationName}Resources", Copy) | ||
copyTestResourcesTask.from("${projectDir}/src/test/resources") | ||
copyTestResourcesTask.into("${testClassesPath}/${variationPath}") | ||
copyTestResourcesTask.execute() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
POM_NAME=Epoxy Model Factory | ||
POM_ARTIFACT_ID=epoxy-modelfactory | ||
POM_PACKAGING=jar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<manifest package="com.airbnb.epoxymodelfactory" | ||
xmlns:android="http://schemas.android.com/apk/res/android" /> |
45 changes: 45 additions & 0 deletions
45
epoxy-modelfactory/src/main/java/com/airbnb/epoxy/ModelProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.airbnb.epoxy; | ||
|
||
import android.support.annotation.DrawableRes; | ||
import android.support.annotation.NonNull; | ||
import android.support.annotation.Nullable; | ||
import android.view.View.OnClickListener; | ||
|
||
import com.airbnb.paris.styles.Style; | ||
|
||
import java.util.List; | ||
|
||
public interface ModelProperties { | ||
|
||
@NonNull | ||
String getId(); | ||
|
||
boolean has(@NonNull String propertyName); | ||
|
||
boolean getBoolean(@NonNull String propertyName); | ||
|
||
double getDouble(@NonNull String propertyName); | ||
|
||
@DrawableRes | ||
int getDrawableRes(@NonNull String propertyName); | ||
|
||
@NonNull | ||
List<? extends EpoxyModel<?>> getEpoxyModelList(@NonNull String propertyName); | ||
|
||
int getInt(@NonNull String propertyName); | ||
|
||
@NonNull | ||
OnClickListener getOnClickListener(@NonNull String propertyName); | ||
|
||
@NonNull | ||
String getString(@NonNull String propertyName); | ||
|
||
@NonNull | ||
List<String> getStringList(@NonNull String propertyName); | ||
|
||
/** | ||
* @return Null to apply the default style. | ||
*/ | ||
@Nullable | ||
Style getStyle(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<resources> | ||
<string name="app_name">Epoxy Model Factory</string> | ||
</resources> |
122 changes: 122 additions & 0 deletions
122
epoxy-modelfactory/src/test/java/com/airbnb/epoxy/FromModelPropertiesKotlinTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package com.airbnb.epoxy | ||
|
||
import android.view.View | ||
import com.airbnb.epoxymodelfactory.R | ||
import com.airbnb.paris.styles.Style | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertFalse | ||
import org.junit.Test | ||
|
||
/** | ||
* Asserts that using from(ModelProperties) to create a model applies the property values correctly | ||
*/ | ||
class FromModelPropertiesKotlinTest { | ||
|
||
@Test | ||
fun getId() { | ||
val model = TestModelPropertiesKotlinViewModel_.from(TestModelProperties(id = "100")) | ||
assertFalse(model.hasDefaultId()) | ||
} | ||
|
||
@Test | ||
fun getBoolean() { | ||
val model = TestModelPropertiesKotlinViewModel_.from(TestModelProperties(booleanValue = true)) | ||
assertEquals(true, model.booleanValue()) | ||
} | ||
|
||
@Test | ||
fun getDouble() { | ||
val model = TestModelPropertiesKotlinViewModel_.from(TestModelProperties(doubleValue = 42.0)) | ||
assertEquals(42.0, model.doubleValue(), 0.0) | ||
} | ||
|
||
@Test | ||
fun getDrawableRes() { | ||
val drawableRes = R.drawable.abc_ic_star_black_48dp | ||
val model = | ||
TestModelPropertiesKotlinViewModel_.from(TestModelProperties(drawableRes = drawableRes)) | ||
assertEquals(drawableRes, model.drawableRes()) | ||
} | ||
|
||
@Test | ||
fun getEpoxyModelList() { | ||
val epoxyModelList = emptyList<EpoxyModel<*>>() | ||
val model = | ||
TestModelPropertiesKotlinViewModel_.from(TestModelProperties(epoxyModelList = epoxyModelList)) | ||
assertEquals(epoxyModelList, model.epoxyModelList()) | ||
} | ||
|
||
@Test | ||
fun getInt() { | ||
val model = TestModelPropertiesKotlinViewModel_.from(TestModelProperties(intValue = 51)) | ||
assertEquals(51, model.intValue()) | ||
} | ||
|
||
@Test | ||
fun getOnClickListener() { | ||
val clickListener = View.OnClickListener { } | ||
val model = | ||
TestModelPropertiesKotlinViewModel_.from(TestModelProperties(onClickListener = clickListener)) | ||
assertEquals(clickListener, model.onClickListener()) | ||
} | ||
|
||
@Test | ||
fun getString() { | ||
val model = | ||
TestModelPropertiesKotlinViewModel_.from(TestModelProperties(stringValue = "ModelFactory")) | ||
assertEquals("ModelFactory", model.stringValue()) | ||
} | ||
|
||
@Test | ||
fun getStringList() { | ||
val stringList = listOf("Model", "Factory") | ||
val model = TestModelPropertiesKotlinViewModel_.from(TestModelProperties(stringList = stringList)) | ||
assertEquals(stringList, model.stringList()) | ||
} | ||
|
||
class TestModelProperties( | ||
private val id: String = "", | ||
private val booleanValue: Boolean? = null, | ||
private val doubleValue: Double? = null, | ||
private val drawableRes: Int? = null, | ||
private val epoxyModelList: List<EpoxyModel<*>>? = null, | ||
private val intValue: Int? = null, | ||
private val onClickListener: View.OnClickListener? = null, | ||
private val stringValue: String? = null, | ||
private val stringList: List<String>? = null, | ||
private val styleValue: Style? = null | ||
) : ModelProperties { | ||
override fun getId() = id | ||
|
||
override fun has(propertyName: String): Boolean { | ||
return mapOf( | ||
"booleanValue" to booleanValue, | ||
"doubleValue" to doubleValue, | ||
"drawableRes" to drawableRes, | ||
"epoxyModelList" to epoxyModelList, | ||
"intValue" to intValue, | ||
"onClickListener" to onClickListener, | ||
"stringList" to stringList, | ||
"stringValue" to stringValue | ||
)[propertyName] != null | ||
} | ||
|
||
override fun getBoolean(propertyName: String) = booleanValue!! | ||
|
||
override fun getDouble(propertyName: String) = doubleValue!! | ||
|
||
override fun getDrawableRes(propertyName: String) = drawableRes!! | ||
|
||
override fun getEpoxyModelList(propertyName: String) = epoxyModelList!! | ||
|
||
override fun getInt(propertyName: String) = intValue!! | ||
|
||
override fun getOnClickListener(propertyName: String) = onClickListener!! | ||
|
||
override fun getString(propertyName: String) = stringValue!! | ||
|
||
override fun getStringList(propertyName: String) = stringList!! | ||
|
||
override fun getStyle() = styleValue | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
epoxy-modelfactory/src/test/java/com/airbnb/epoxy/FromModelPropertiesTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package com.airbnb.epoxy | ||
|
||
import android.view.View | ||
import com.airbnb.epoxymodelfactory.R | ||
import com.airbnb.paris.styles.Style | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertFalse | ||
import org.junit.Test | ||
|
||
/** | ||
* Asserts that using from(ModelProperties) to create a model applies the property values correctly | ||
*/ | ||
class FromModelPropertiesTest { | ||
|
||
@Test | ||
fun getId() { | ||
val model = TestModelPropertiesViewModel_.from(TestModelProperties(id = "100")) | ||
assertFalse(model.hasDefaultId()) | ||
} | ||
|
||
@Test | ||
fun getBoolean() { | ||
val model = TestModelPropertiesViewModel_.from(TestModelProperties(booleanValue = true)) | ||
assertEquals(true, model.booleanValue()) | ||
} | ||
|
||
@Test | ||
fun getDouble() { | ||
val model = TestModelPropertiesViewModel_.from(TestModelProperties(doubleValue = 42.0)) | ||
assertEquals(42.0, model.doubleValue(), 0.0) | ||
} | ||
|
||
@Test | ||
fun getDrawableRes() { | ||
val drawableRes = R.drawable.abc_ic_star_black_48dp | ||
val model = | ||
TestModelPropertiesViewModel_.from(TestModelProperties(drawableRes = drawableRes)) | ||
assertEquals(drawableRes, model.drawableRes()) | ||
} | ||
|
||
@Test | ||
fun getEpoxyModelList() { | ||
val epoxyModelList = emptyList<EpoxyModel<*>>() | ||
val model = | ||
TestModelPropertiesViewModel_.from(TestModelProperties(epoxyModelList = epoxyModelList)) | ||
assertEquals(epoxyModelList, model.epoxyModelList()) | ||
} | ||
|
||
@Test | ||
fun getInt() { | ||
val model = TestModelPropertiesViewModel_.from(TestModelProperties(intValue = 51)) | ||
assertEquals(51, model.intValue()) | ||
} | ||
|
||
@Test | ||
fun getOnClickListener() { | ||
val clickListener = View.OnClickListener { } | ||
val model = | ||
TestModelPropertiesViewModel_.from(TestModelProperties(onClickListener = clickListener)) | ||
assertEquals(clickListener, model.onClickListener()) | ||
} | ||
|
||
@Test | ||
fun getString() { | ||
val model = | ||
TestModelPropertiesViewModel_.from(TestModelProperties(stringValue = "ModelFactory")) | ||
assertEquals("ModelFactory", model.stringValue()) | ||
} | ||
|
||
@Test | ||
fun getStringList() { | ||
val stringList = listOf("Model", "Factory") | ||
val model = TestModelPropertiesViewModel_.from(TestModelProperties(stringList = stringList)) | ||
assertEquals(stringList, model.stringList()) | ||
} | ||
|
||
class TestModelProperties( | ||
private val id: String = "", | ||
private val booleanValue: Boolean? = null, | ||
private val doubleValue: Double? = null, | ||
private val drawableRes: Int? = null, | ||
private val epoxyModelList: List<EpoxyModel<*>>? = null, | ||
private val intValue: Int? = null, | ||
private val onClickListener: View.OnClickListener? = null, | ||
private val stringValue: String? = null, | ||
private val stringList: List<String>? = null, | ||
private val styleValue: Style? = null | ||
) : ModelProperties { | ||
override fun getId() = id | ||
|
||
override fun has(propertyName: String): Boolean { | ||
return mapOf( | ||
"booleanValue" to booleanValue, | ||
"doubleValue" to doubleValue, | ||
"drawableRes" to drawableRes, | ||
"epoxyModelList" to epoxyModelList, | ||
"intValue" to intValue, | ||
"onClickListener" to onClickListener, | ||
"stringList" to stringList, | ||
"stringValue" to stringValue | ||
)[propertyName] != null | ||
} | ||
|
||
override fun getBoolean(propertyName: String) = booleanValue!! | ||
|
||
override fun getDouble(propertyName: String) = doubleValue!! | ||
|
||
override fun getDrawableRes(propertyName: String) = drawableRes!! | ||
|
||
override fun getEpoxyModelList(propertyName: String) = epoxyModelList!! | ||
|
||
override fun getInt(propertyName: String) = intValue!! | ||
|
||
override fun getOnClickListener(propertyName: String) = onClickListener!! | ||
|
||
override fun getString(propertyName: String) = stringValue!! | ||
|
||
override fun getStringList(propertyName: String) = stringList!! | ||
|
||
override fun getStyle() = styleValue | ||
} | ||
} |
Oops, something went wrong.