Skip to content

Commit efb739f

Browse files
authored
Merge pull request #20227 from wordpress-mobile/kapt_processing_tests
`:libs:processors` annotation processing unit test
2 parents 2440e07 + 305cf90 commit efb739f

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

libs/processors/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ dependencies {
1414
kapt "com.google.auto.service:auto-service:$googleAutoServiceVersion"
1515
implementation "com.squareup:kotlinpoet:$squareupKotlinPoetVersion"
1616

17+
testImplementation "com.github.tschuchortdev:kotlin-compile-testing:1.5.0"
1718
testImplementation "junit:junit:$junitVersion"
1819
testImplementation "org.assertj:assertj-core:$assertjVersion"
20+
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$gradle.ext.kotlinVersion"
1921
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package org.wordpress.android.processor
2+
3+
import com.tschuchort.compiletesting.KotlinCompilation
4+
import com.tschuchort.compiletesting.SourceFile
5+
import org.assertj.core.api.Assertions.assertThat
6+
import org.jetbrains.kotlin.utils.addToStdlib.cast
7+
import org.junit.Test
8+
9+
class RemoteConfigProcessorTest {
10+
@Test
11+
fun `given a class with features annotation, when compiling, generate expected configuration check`() {
12+
// when
13+
val result = compile(listOf(featureA))
14+
15+
// then
16+
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
17+
assertThat(result.classLoader.loadClass("org.wordpress.android.util.config.RemoteFeatureConfigCheck"))
18+
.hasDeclaredMethods("checkRemoteFields")
19+
}
20+
21+
@Test
22+
fun `given a class with remote field annotation, when compiling, generate expected config defaults class`() {
23+
// given
24+
val remoteFieldA = SourceFile.kotlin(
25+
"RemoteField.kt", """
26+
import org.wordpress.android.annotation.RemoteFieldDefaultGenerater
27+
import org.wordpress.android.util.config.AppConfig
28+
29+
@RemoteFieldDefaultGenerater(remoteField = "remoteField", defaultValue = "default")
30+
class RemoteFieldA
31+
"""
32+
)
33+
34+
// when
35+
val result = compile(
36+
listOf(
37+
remoteFieldA,
38+
featureA, /* adding a feature, as without it, annotation processor won't start */
39+
)
40+
)
41+
42+
// then
43+
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
44+
val remoteFieldConfigDefaultsClass =
45+
result.classLoader.loadClass("org.wordpress.android.util.config.RemoteFieldConfigDefaults")
46+
val remoteFieldConfigDefaultsObject = remoteFieldConfigDefaultsClass.kotlin.objectInstance
47+
48+
assertThat(
49+
remoteFieldConfigDefaultsClass.getDeclaredField("remoteFieldConfigDefaults")
50+
.apply { isAccessible = true }
51+
.get(remoteFieldConfigDefaultsObject)
52+
.cast<Map<String, Any>>()
53+
).containsEntry("remoteField", "default")
54+
}
55+
56+
@Test
57+
fun `given class with feature and experiment annotation, when compiling, generate config defaults class`() {
58+
// given
59+
val experiment = SourceFile.kotlin(
60+
"Experiment.kt", """
61+
import org.wordpress.android.annotation.Experiment
62+
import org.wordpress.android.util.config.AppConfig
63+
64+
@Experiment("experimentFeature", "defaultVariant")
65+
class Experiment
66+
"""
67+
)
68+
69+
// when
70+
val result = compile(listOf(featureA, experiment))
71+
72+
// then
73+
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
74+
val remoteFieldConfigDefaultsClass =
75+
result.classLoader.loadClass("org.wordpress.android.util.config.RemoteFeatureConfigDefaults")
76+
val remoteFieldConfigDefaultsObject = remoteFieldConfigDefaultsClass.kotlin.objectInstance
77+
78+
assertThat(
79+
remoteFieldConfigDefaultsClass.getDeclaredField("remoteFeatureConfigDefaults")
80+
.apply { isAccessible = true }
81+
.get(remoteFieldConfigDefaultsObject)
82+
.cast<Map<String, Any>>()
83+
).containsExactlyInAnyOrderEntriesOf(
84+
mapOf(
85+
"experimentFeature" to "defaultVariant",
86+
"remoteField" to "false"
87+
)
88+
)
89+
}
90+
91+
@Test
92+
fun `given class with feature in development annotation, when compiling, generate expected list of classes`() {
93+
// given
94+
val experiment = SourceFile.kotlin(
95+
"Experiment.kt", """
96+
import org.wordpress.android.annotation.FeatureInDevelopment
97+
import org.wordpress.android.util.config.AppConfig
98+
99+
@FeatureInDevelopment
100+
class DevFeature
101+
"""
102+
)
103+
104+
// when
105+
val result = compile(
106+
listOf(
107+
experiment,
108+
featureA, /* adding a feature, as without it, annotation processor won't start */
109+
)
110+
)
111+
112+
// then
113+
114+
val featuresInDevelopmentClass =
115+
result.classLoader.loadClass("org.wordpress.android.util.config.FeaturesInDevelopment")
116+
val featuresInDevelopmentObject = featuresInDevelopmentClass.kotlin.objectInstance
117+
assertThat(
118+
featuresInDevelopmentClass.getDeclaredField("featuresInDevelopment")
119+
.apply { isAccessible = true }
120+
.get(featuresInDevelopmentObject)
121+
.cast<List<String>>()
122+
).containsOnly("DevFeature")
123+
}
124+
125+
private fun compile(src: List<SourceFile>) = KotlinCompilation().apply {
126+
sources = src + fakeAppConfig
127+
annotationProcessors = listOf(RemoteConfigProcessor())
128+
inheritClassPath = true
129+
messageOutputStream = System.out
130+
}.compile()
131+
132+
// Fake AppConfig is needed, as it's a class that is expected to be present in the classpath. Originally, this class
133+
// is placed in `WordPress` module.
134+
private val fakeAppConfig = SourceFile.kotlin(
135+
"AppConfig.kt", """
136+
package org.wordpress.android.util.config
137+
138+
class AppConfig
139+
"""
140+
)
141+
142+
private val featureA = SourceFile.kotlin(
143+
"Feature.kt", """
144+
import org.wordpress.android.annotation.Feature
145+
import org.wordpress.android.util.config.AppConfig
146+
147+
@Feature("remoteField", false)
148+
class FeatureA(appConfig: AppConfig, val remoteField: String ="foo")
149+
"""
150+
)
151+
}

0 commit comments

Comments
 (0)