--- /dev/null 2016-07-05 21:07:33.975190056 -0700 +++ new/test/java/lang/annotation/AnnotationToStringTest.java 2016-08-01 13:41:55.750048543 -0700 @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2016, 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 + * @bug 8162817 + * @summary Test of toString on normal annotations + */ + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; + +/** + * The expected string values are stored in @ExpectedString + * annotations. The essence of the test is comparting the toString() + * result of annotations to ExpectedString.value(). + */ +public class AnnotationToStringTest { + public static void main(String... args) throws Exception { + int failures = 0; + + failures += classyTest(); + failures += arrayAnnotationTest(); + + if (failures > 0) + throw new RuntimeException(failures + " failures"); + } + + private static int check(String expected, String actual) { + if (!expected.equals(actual)) { + System.err.printf("ERROR: Expected ''%s'';%ngot ''%s''.\n", + expected, actual); + return 1; + } else + return 0; + } + + private static int classyTest() { + int failures = 0; + for (Field f : AnnotationHost.class.getFields()) { + Annotation a = f.getAnnotation(Classy.class); + System.out.println(a); + failures += check(f.getAnnotation(ExpectedString.class).value(), + a.toString()); + } + return failures; + } + + static class AnnotationHost { + @ExpectedString( + "@Classy(value=Obj.class)") + @Classy(value=Obj.class) + public int f0; + + @ExpectedString( + "@Classy(value=Obj[].class)") + @Classy(value=Obj[].class) + public int f1; + + @ExpectedString( + "@Classy(value=Obj[][].class)") + @Classy(value=Obj[][].class) + public int f2; + + @ExpectedString( + "@Classy(value=Obj[][][].class)") + @Classy(value=Obj[][][].class) + public int f3; + + @ExpectedString( + "@Classy(value=int.class)") + @Classy(value=int.class) + public int f4; + + @ExpectedString( + "@Classy(value=int[][][].class)") + @Classy(value=int[][][].class) + public int f5; + } + + /** + * Each field should have two annotations, the first being + * @ExpectedString and the second the annotation under test. + */ + private static int arrayAnnotationTest() { + int failures = 0; + for (Field f : ArrayAnnotationHost.class.getFields()) { + Annotation[] annotations = f.getAnnotations(); + System.out.println(annotations[1]); + failures += check(((ExpectedString)annotations[0]).value(), + annotations[1].toString()); + } + return failures; + } + + static class ArrayAnnotationHost { + @ExpectedString( + "@BooleanArray(value={true, false, true})") + @BooleanArray(value={true, false, true}) + public boolean[] f0; + + @ExpectedString( + "@FloatArray(value={3.0f, 4.0f, 0.0f/0.0f, -1.0f/0.0f, 1.0f/0.0f})") + @FloatArray(value={3.0f, 4.0f, Float.NaN, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}) + public float[] f1; + + @ExpectedString( + "@DoubleArray(value={1.0, 2.0, 0.0/0.0, 1.0/0.0, -1.0/0.0})") + @DoubleArray(value={1.0, 2.0, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,}) + public double[] f2; + + @ExpectedString( + "@ByteArray(value={10, 11, 12})") + @ByteArray(value={10, 11, 12}) + public byte[] f3; + + @ExpectedString( + "@ShortArray(value={0, 4, 5})") + @ShortArray(value={0, 4, 5}) + public short[] f4; + + @ExpectedString( + "@CharArray(value={'a', 'b', 'c', '\\''})") + @CharArray(value={'a', 'b', 'c', '\''}) + public char[] f5; + + @ExpectedString( + "@IntArray(value={1})") + @IntArray(value={1}) + public int[] f6; + + @ExpectedString( + "@LongArray(value={-2147483647, 2147483648L, 9223372036854775807L})") + @LongArray(value={-Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE}) + public long[] f7; + + @ExpectedString( + "@StringArray(value={\"A\", \"B\", \"C\", \"\\\"Quote\\\"\"})") + @StringArray(value={"A", "B", "C", "\"Quote\""}) + public String[] f8; + + @ExpectedString( + "@ClassArray(value={int.class, Obj[].class})") + @ClassArray(value={int.class, Obj[].class}) + public Class[] f9; + + @ExpectedString( + "@EnumArray(value={SOURCE})") + @EnumArray(value={RetentionPolicy.SOURCE}) + public RetentionPolicy[] f10; + } +} + +// ------------ Supporting types ------------ + +class Obj {} + +@Retention(RetentionPolicy.RUNTIME) +@interface ExpectedString { + String value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface Classy { + Class value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface BooleanArray { + boolean[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface FloatArray { + float[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface DoubleArray { + double[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface ByteArray { + byte[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface ShortArray { + short[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface CharArray { + char[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface IntArray { + int[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface LongArray { + long[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface ClassArray { + Class[] value() default {int.class, Obj[].class}; +} + +@Retention(RetentionPolicy.RUNTIME) +@interface StringArray { + String[] value(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface EnumArray { + RetentionPolicy[] value(); +}