Review request for type annotation reflection test
Charlie Wang
charlie.wang at oracle.com
Tue May 21 14:29:12 PDT 2013
OK, thanks.
I will create a TestUtil.java (as attached file). Extract the common
part and put them in it. And Add comments on data provider.
I'm on a very tight schedule, so this time I just send out two of the
updated files (attached files) for review so I can get a quick response.
If it is OK, I will use it as a template on other tests.
Please take a look and send me your comments as soon as possible.
Thanks,
Charlie
On 2013/5/22 2:24, Alex Buckley wrote:
> Please keep one source file per tested API method, because it is easy
> to navigate. The problem is the body of the test() method in each
> source file. It should call utility methods to inspect annotations,
> rather that repeating more or less the same 'for' loops as every other
> test() method.
>
> As for data providers, I believe they are a TestNG thing. Please add
> comments to each source file to describe what the data provider
> represents.
>
> Finally, when you make a "little update", you should give a short
> description of what has changed. If you don't, someone who looked at
> the previous version has no idea what changed and will have to look at
> everything again.
>
> Alex
>
> On 5/21/2013 3:10 AM, Charlie Wang wrote:
>> Yes, that make sense. What do you think if I combine the tests? It would
>> then have 1 unified data provider and test method, thus solve the 2
>> problems.
>>
>> Regards,
>> Charlie
>> On 2013/5/21 14:56, Werner Dietl wrote:
>>> I agree with Alex's first two comments. The code duplication for the
>>> test logic and all the different annotation types seems hard to
>>> maintain and update.
>>>
>>> cu, WMD.
>>>
>>> On Mon, May 20, 2013 at 7:56 PM, Charlie Wang
>>> <charlie.wang at oracle.com> wrote:
>>>> Hi,
>>>> Here's the latest one with a little update:
>>>> http://cr.openjdk.java.net/~ssides/8013497/webrev.03/
>>>> Please provide comments as soon as possible now that due date is
>>>> approaching.
>>>>
>>>>
>>>> Regards,
>>>> Charlie
>>>>
>>>>
>>>>
>>>> On 2013/5/19 14:10, Charlie Wang wrote:
>>>>
>>>> Hi,
>>>> Here's test for core reflection support of type-annotations
>>>> JDK-8013497.
>>>> Please take a look.
>>>>
>>>> http://cr.openjdk.java.net/~ssides/8013497/webrev.02/
>>>>
>>>>
>>>> Regards,
>>>> Charlie
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
-------------- next part --------------
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedArrayType;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.AnnotatedTypeVariable;
import java.lang.reflect.AnnotatedWildcardType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.NoInjection;
import org.testng.annotations.Test;
public class TestUtil {
// check annotation
public static void validateAnno(Annotation[] annotations
, Object[] annotationCheck) throws Exception{
for (int i = 0; i < annotations.length; i++) {
Annotation anno = annotations[i];
assertEquals(anno.annotationType(), annotationCheck[i * 2]);
Object value = "";
try {
Method valueMethod = anno.annotationType().getMethod("value"
, new Class[]{});
value = valueMethod.invoke(anno, new Object[]{});
} catch (NoSuchMethodException e) {
//expected exception for TypeAnno3
}
if (annotationCheck[i * 2 + 1] instanceof String) {
assertEquals(value, annotationCheck[i * 2 + 1]);
} else {
//for repeated anno
Annotation[] av = (Annotation[]) value;
Object[] ac = (Object[]) annotationCheck[i * 2 + 1];
assertEquals(av.length, ac.length / 2);
for (int j = 0; j < av.length; j++) {
assertEquals(av[j].annotationType(), ac[j * 2]);
Method vm = av[j].annotationType().getMethod("value"
, new Class[]{});
Object v = vm.invoke(av[j], new Object[]{});
assertEquals(v, ac[j * 2 + 1]);
}
}
}
}
// vlidate AnnotatedArrayType
public static void validateArrayAT(AnnotatedType at, Object[][] annotationCheck)
throws Exception {
for (int i = 0; i < annotationCheck.length; i++) {
Annotation[] annos = at.getAnnotations();
assertEquals(annos.length, annotationCheck[i].length / 2);
for (int j = 0; j < annotationCheck[i].length; j+=2) {
Method valueMethod = annos[j / 2].annotationType().getMethod(
"value", new Class[]{});
Object value = valueMethod.invoke(annos[j / 2], new Object[]{});
if (value instanceof String) {
assertEquals(annos[j / 2].annotationType()
, annotationCheck[i][j]);
assertEquals(value, annotationCheck[i][j + 1]);
} else {
Annotation[] av = (Annotation[]) value;
Object[] ac = (Object[]) annotationCheck[i][j + 1];
assertEquals(av.length, ac.length / 2);
for (int k = 0; k < av.length; k++) {
assertEquals(av[k].annotationType(), ac[k * 2]);
Method vm = av[k].annotationType().getMethod(
"value", new Class[]{});
Object v = vm.invoke(av[k], new Object[]{});
assertEquals(v, ac[k * 2 + 1]);
}
}
}
if (at instanceof AnnotatedArrayType) {
at = ((AnnotatedArrayType) at)
.getAnnotatedGenericComponentType();
}
}
}
// check AnnotatedType type and value
public static void validateAT(AnnotatedType at, Object[] annotationCheck)
throws Exception{
Annotation[] annotations = at.getAnnotations();
assertEquals(annotations.length, annotationCheck.length / 2);
validateAnno(annotations, annotationCheck);
}
// check multiple AnnotatedType type and value
public static void validateMultipleAT(AnnotatedType[] as
, Object[][] annotationCheck) throws Exception{
assertEquals(as.length, annotationCheck.length);
for (int i = 0; i < as.length; i++) {
validateAT(as[i], (Object[]) annotationCheck[i]);
}
}
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TypeAnno1Container.class)
@interface TypeAnno1 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TypeAnno2Container.class)
@interface TypeAnno2 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TypeAnno3Container.class)
@interface TypeAnno3 {
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno4 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno5 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno6 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno7 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno8 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno9 {
String value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno1Container {
TypeAnno1[] value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno2Container {
TypeAnno2[] value();
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeAnno3Container {
TypeAnno3[] value();
}
-------------- next part --------------
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test @summary test for Class.getAnnotatedInterfaces()
* @bug 8013497
* @(#) GetAnnotatedInterfacesTest.java
* @build TestUtil
* @run testng GetAnnotatedInterfacesTest
*/
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class GetAnnotatedInterfacesTest {
@Test(dataProvider = "annotationsData")
public void test(Class c, Object[][] annotationCheck) throws Exception {
AnnotatedType[] as = c.getAnnotatedInterfaces();
assertEquals(as.length, annotationCheck.length);
TestUtil.validateMultipleAT(as, annotationCheck);
}
@DataProvider
public Object[][] annotationsData() {
// first item of every row represents the class to invoke
// getannotatedInterfaces() on (e.g. Object.class.getannotatedInterfaces())
// , second one represents the result
return new Object[][]{
// invoke getannotatedInterfaces() on Object.class, should get empty
// array
{Object.class, new Object[][]{}},
{int.class, new Object[][]{}},
{void.class, new Object[][]{}},
{AnnotationTypeTest01.class, new Object[][]{}},
{AnnotationTypeTest02.class, new Object[][]{}},
{AnnotationTypeTest03.class, new Object[][]{{new Object[]{}}}},
{AnnotationTypeTest04.class, new Object[][]{{new Object[]{}}}},
{AnnotationTypeTest05.class, new Object[][]{
{TypeAnno1.class, "TypeAnno1"}}},
{int[].class, new Object[][]{{}, {}}},
{AnnotationTypeTest06.class, new Object[][]{
{TypeAnno1.class, "TypeAnno1", TypeAnno2.class, "TypeAnno2"}}},
{AnnotationTypeTest07.class, new Object[][]{
{TypeAnno1.class, "TypeAnno1"},
{TypeAnno2.class, "TypeAnno2"}}},
{AnnotationTypeTest08.class, new Object[][]{
{TypeAnno1.class, "TypeAnno1", TypeAnno3.class, ""}}},
{AnnotationTypeTest09.class, new Object[][]{
{TypeAnno1.class, "TypeAnno1", TypeAnno2Container.class
, new Object[]{TypeAnno2.class, "TypeAnno21"
, TypeAnno2.class, "TypeAnno22"}}}}
};
}
}
interface Interface1 {
}
interface Interface2 {
}
class Object1 {
}
class Object2 {
}
class AnnotationTypeTest01 {
}
class AnnotationTypeTest02 extends Object1 {
}
class AnnotationTypeTest03 implements Interface1 {
}
class AnnotationTypeTest04 extends Object1 implements Interface1 {
}
interface AnnotationTypeTest05 extends @TypeAnno1("TypeAnno1") Interface1 {
}
interface AnnotationTypeTest06 extends
@TypeAnno1("TypeAnno1")
@TypeAnno2("TypeAnno2")
Interface1 {
}
class AnnotationTypeTest07 implements
@TypeAnno1("TypeAnno1")
Interface1 , @TypeAnno2("TypeAnno2")
Interface2 {
}
class AnnotationTypeTest08 implements
@TypeAnno1("TypeAnno1")
@TypeAnno3
Interface1 {
}
class AnnotationTypeTest09 implements
@TypeAnno1("TypeAnno1")
@TypeAnno2("TypeAnno21")
@TypeAnno2("TypeAnno22")
Interface1 {
}
More information about the type-annotations-dev
mailing list