blob: f5a04c4a2389c06195af11a03b1fc2d9569a9049 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.room.ext
import box
import com.google.common.truth.Truth.assertThat
import com.google.testing.compile.JavaFileObjects
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import simpleRun
import javax.lang.model.element.ExecutableElement
@RunWith(JUnit4::class)
class ElementExtTest {
@Test
fun methodsInClass() {
val parentCode = JavaFileObjects.forSourceLines(
"foo.bar.Parent", """
package foo.bar;
public class Parent {
public Parent() {}
private void parentPrivate() {}
public void parentPublic() {}
public void overridden() {}
private static void parentStaticPrivate() {}
public static void parentStaticPublic() {}
}
""".trimIndent()
)
val childCode = JavaFileObjects.forSourceLines(
"foo.bar.Child", """
package foo.bar;
public class Child extends Parent {
public Child() {}
private void childPrivate() {}
public void childPublic() {}
public void overridden() {}
private static void childStaticPrivate() {}
public static void childStaticPublic() {}
}
""".trimIndent()
)
simpleRun(
jfos = *arrayOf(parentCode, childCode)
) {
val parent = it.processingEnv.requireTypeElement("foo.bar.Parent")
val child = it.processingEnv.requireTypeElement("foo.bar.Child")
val objectMethods = it.processingEnv.requireTypeElement("java.lang.Object")
.getAllMethods(it.processingEnv).map {
it.simpleName.toString()
} - "registerNatives"
val parentMethods = listOf(
"parentPrivate", "parentPublic", "parentStaticPrivate",
"parentStaticPublic", "overridden"
)
val childMethods = listOf(
"childPrivate", "childPublic", "childStaticPrivate",
"childStaticPublic", "overridden"
)
assertThat(parent.getDeclaredMethods()).containsExactlyElementsIn(parentMethods)
assertThat(parent.getAllMethods(it.processingEnv))
.containsExactlyElementsIn(parentMethods + objectMethods)
assertThat(parent.getAllNonPrivateInstanceMethods(it.processingEnv))
.containsExactlyElementsIn(
parentMethods + objectMethods -
listOf("parentPrivate", "parentStaticPrivate", "parentStaticPublic")
)
assertThat(child.getDeclaredMethods()).containsExactlyElementsIn(
childMethods
)
assertThat(child.getAllMethods(it.processingEnv)).containsExactlyElementsIn(
childMethods + parentMethods + objectMethods -
listOf("parentPrivate", "parentStaticPrivate", "overridden") +
"overridden" // add 1 overridden back
)
assertThat(child.getAllNonPrivateInstanceMethods(it.processingEnv))
.containsExactlyElementsIn(
childMethods + parentMethods + objectMethods -
listOf(
"parentPrivate", "parentStaticPrivate", "parentStaticPublic",
"childPrivate", "childStaticPrivate", "childStaticPublic",
"overridden"
) + "overridden" // add 1 overridden back
)
assertThat(child.getConstructors()).containsExactly("<init>")
assertThat(parent.getConstructors()).containsExactly("<init>")
}.compilesWithoutError()
}
@Test
fun methodsInInterface() {
val parentCode = JavaFileObjects.forSourceLines(
"foo.bar.Parent", """
package foo.bar;
public interface Parent {
public void parentPublic();
public void overridden();
private static void parentStaticPrivate() {}
public static void parentStaticPublic() {}
}
""".trimIndent()
)
val childCode = JavaFileObjects.forSourceLines(
"foo.bar.Child", """
package foo.bar;
public interface Child extends Parent {
public void childPublic();
public void overridden();
private static void childStaticPrivate() {}
public static void childStaticPublic() {}
}
""".trimIndent()
)
simpleRun(
jfos = *arrayOf(parentCode, childCode)
) {
val parent = it.processingEnv.requireTypeElement("foo.bar.Parent")
val child = it.processingEnv.requireTypeElement("foo.bar.Child")
val objectMethods = it.processingEnv.requireTypeElement("java.lang.Object")
.getAllMethods(it.processingEnv).map {
it.simpleName.toString()
} - listOf("registerNatives", "clone", "finalize")
val parentMethods = listOf(
"parentPublic", "parentStaticPrivate", "parentStaticPublic", "overridden"
)
val childMethods = listOf(
"childPublic", "childStaticPrivate", "childStaticPublic", "overridden"
)
assertThat(parent.getDeclaredMethods())
.containsExactlyElementsIn(parentMethods)
assertThat(parent.getAllMethods(it.processingEnv))
.containsExactlyElementsIn(parentMethods + objectMethods)
assertThat(parent.getAllNonPrivateInstanceMethods(it.processingEnv))
.containsExactly("parentPublic", "overridden")
assertThat(child.getDeclaredMethods())
.containsExactlyElementsIn(childMethods)
assertThat(child.getAllMethods(it.processingEnv)).containsExactlyElementsIn(
childMethods + parentMethods + objectMethods -
listOf("parentStaticPrivate", "parentStaticPublic", "overridden") +
"overridden" // add 1 overridden back
)
assertThat(child.getAllNonPrivateInstanceMethods(it.processingEnv))
.containsExactly(
"childPublic", "parentPublic", "overridden"
)
assertThat(child.getConstructors()).isEmpty()
assertThat(parent.getConstructors()).isEmpty()
}.compilesWithoutError()
}
@Test
fun types() {
val testCode = JavaFileObjects.forSourceLines(
"foo.bar.Baz", """
package foo.bar;
public class Baz {
public int field;
public int method() {
return 3;
}
}
""".trimIndent()
)
simpleRun(
jfos = *arrayOf(testCode)
) {
val element = it.processingEnv.requireTypeElement("foo.bar.Baz")
val field = element.getAllFieldsIncludingPrivateSupers(it.processingEnv)
.first {
it.simpleName.toString() == "field"
}
val method = element.getDeclaredMethods()
.first {
it.simpleName.toString() == "method"
}
assertThat(field.type.typeName()).isEqualTo(TypeName.INT)
assertThat(method.returnType.typeName()).isEqualTo(TypeName.INT)
assertThat(element.type.typeName()).isEqualTo(ClassName.get("foo.bar", "Baz"))
}.compilesWithoutError()
}
@Test
fun primitiveTypes() {
// check that we can also find primitive types from the common API
val primitiveTypeNames = listOf(
TypeName.BOOLEAN,
TypeName.BYTE,
TypeName.SHORT,
TypeName.INT,
TypeName.LONG,
TypeName.CHAR,
TypeName.FLOAT,
TypeName.DOUBLE
)
simpleRun { invocation ->
val processingEnv = invocation.processingEnv
primitiveTypeNames.forEach { primitiveTypeName ->
val typeMirror = processingEnv.requireTypeMirror(primitiveTypeName)
assertThat(typeMirror.kind.isPrimitive).isTrue()
assertThat(typeMirror.typeName()).isEqualTo(primitiveTypeName)
assertThat(
typeMirror.box(invocation.typeUtils).typeName()
).isEqualTo(primitiveTypeName.box())
}
}.compilesWithoutError()
}
private fun assertThat(executables: Iterable<ExecutableElement>) = assertThat(
executables.map { it.simpleName.toString() }
)
}