/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jboss.errai.codegen.test;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.List;
import java.util.Set;
import org.jboss.errai.codegen.builder.ClassStructureBuilder;
import org.jboss.errai.codegen.builder.impl.ClassBuilder;
import org.junit.Test;
/**
* Tests the generation of annotations.
*
* @author Johannes Barop <jb@barop.de>
*/
public class AnnotationTest extends AbstractCodegenTest {
@Test
public void testSingleBoolean() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.BooleanAnnotation;\n" +
"@BooleanAnnotation(arrayValue = false, value = false)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructBooleanAnnotation(false));
assertEquals(expected, cls);
}
@Test
public void testMultiBoolean() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.BooleanAnnotation;\n" +
"@BooleanAnnotation(arrayValue = {true, false, true}, value = true)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructBooleanAnnotation(true, false, true));
assertEquals(expected, cls);
}
@Test
public void testSingleByte() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.ByteAnnotation;\n" +
"@ByteAnnotation(arrayValue = 1, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructByteAnnotation(new byte[]{1}));
assertEquals(expected, cls);
}
@Test
public void testMultiByte() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.ByteAnnotation;\n" +
"@ByteAnnotation(arrayValue = {1, 2, 3}, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructByteAnnotation(new byte[]{1, 2, 3}));
assertEquals(expected, cls);
}
@Test
public void testSingleChar() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.CharAnnotation;\n" +
"@CharAnnotation(arrayValue = 'a', value = 'a')\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructCharAnnotation('a'));
assertEquals(expected, cls);
}
@Test
public void testMultiChar() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.CharAnnotation;\n" +
"@CharAnnotation(arrayValue = {'a', 'b', 'c'}, value = 'a')\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructCharAnnotation('a', 'b', 'c'));
assertEquals(expected, cls);
}
@Test
public void testSingleShort() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.ShortAnnotation;\n" +
"@ShortAnnotation(arrayValue = 1, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructShortAnnotation(new short[]{1}));
assertEquals(expected, cls);
}
@Test
public void testMultiShort() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.ShortAnnotation;\n" +
"@ShortAnnotation(arrayValue = {1, 2, 3}, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructShortAnnotation(new short[]{1, 2, 3}));
assertEquals(expected, cls);
}
@Test
public void testSingleInt() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.IntAnnotation;\n" +
"@IntAnnotation(arrayValue = 1, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructIntAnnotation(1));
assertEquals(expected, cls);
}
@Test
public void testMultiInt() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.IntAnnotation;\n" +
"@IntAnnotation(arrayValue = {1, 2, 3}, value = 1)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructIntAnnotation(1, 2, 3));
assertEquals(expected, cls);
}
@Test
public void testSingleLong() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.LongAnnotation;\n" +
"@LongAnnotation(arrayValue = 1L, value = 1L)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructLongAnnotation(1l));
assertEquals(expected, cls);
}
@Test
public void testMultiLong() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.LongAnnotation;\n" +
"@LongAnnotation(arrayValue = {1L, 2L, 3L}, value = 1L)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructLongAnnotation(1l, 2l, 3l));
assertEquals(expected, cls);
}
@Test
public void testSingleFloat() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.FloatAnnotation;\n" +
"@FloatAnnotation(arrayValue = 1.1f, value = 1.1f)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructFloatAnnotation(1.1f));
assertEquals(expected, cls);
}
@Test
public void testMultiFloat() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.FloatAnnotation;\n" +
"@FloatAnnotation(arrayValue = {1.1f, 2.22f, 3.333f}, value = 1.1f)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructFloatAnnotation(1.1f, 2.22f, 3.333f));
assertEquals(expected, cls);
}
@Test
public void testSingleDouble() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.DoubleAnnotation;\n" +
"@DoubleAnnotation(arrayValue = 1.1d, value = 1.1d)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructDoubleAnnotation(1.1));
assertEquals(expected, cls);
}
@Test
public void testMultiDouble() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.DoubleAnnotation;\n" +
"@DoubleAnnotation(arrayValue = {1.1d, 2.22d, 3.333d}, value = 1.1d)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructDoubleAnnotation(1.1, 2.22, 3.333));
assertEquals(expected, cls);
}
@Test
public void testSingleString() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.StringAnnotation;\n" +
"@StringAnnotation(arrayValue = \"Hello World\", value = \"Hello World\")\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructStringAnnotation("Hello World"));
assertEquals(expected, cls);
}
@Test
public void testMultiString() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.StringAnnotation;\n" +
"@StringAnnotation(arrayValue = {\"Hang\", \"to\", \"your\", \"helmet\"}, value = \"Hang\")\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructStringAnnotation("Hang", "to", "your", "helmet"));
assertEquals(expected, cls);
}
@Test
public void testSingleClass() {
String expected = "" +
"import java.util.Set;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.ClassAnnotation;\n" +
"@ClassAnnotation(arrayValue = Set.class, value = Set.class)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructClassAnnotation(Set.class));
assertEquals(expected, cls);
}
@Test
public void testMultiClass() {
String expected = "" +
"import java.util.List;\n" +
"import java.util.Set;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.ClassAnnotation;\n" +
"@ClassAnnotation(arrayValue = {Set.class, List.class}, value = Set.class)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructClassAnnotation(Set.class, List.class));
assertEquals(expected, cls);
}
@Test
public void testSingleEnum() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.EnumAnnotation;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.SimpleEnum;\n" +
"@EnumAnnotation(arrayValue = SimpleEnum.YES, value = SimpleEnum.YES)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructEnumAnnotation(SimpleEnum.YES));
assertEquals(expected, cls);
}
@Test
public void testMultiEnum() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.EnumAnnotation;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.SimpleEnum;\n" +
"@EnumAnnotation(arrayValue = {SimpleEnum.YES, SimpleEnum.NO, SimpleEnum.YES}, value = SimpleEnum.YES)\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructEnumAnnotation(SimpleEnum.YES, SimpleEnum.NO, SimpleEnum.YES));
assertEquals(expected, cls);
}
@Test
public void testSingleAnnotation() {
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.AnnotationAnnotation;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.BooleanAnnotation;\n" +
"@AnnotationAnnotation(arrayValue = \n" +
" @BooleanAnnotation(arrayValue = {true, false}, value = true),\n" +
" value = @BooleanAnnotation(arrayValue = {true, false}, value = true))\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructAnnotationAnnotation(constructBooleanAnnotation(true, false)));
assertEquals(expected, cls);
}
@Test
public void testMultiAnnotation() {
// XXX:
// FIXME: The PrettyPrinter output in nested annotations is different
String expected = "" +
"import org.jboss.errai.codegen.test.AnnotationTest.AnnotationAnnotation;\n" +
"import org.jboss.errai.codegen.test.AnnotationTest.BooleanAnnotation;\n" +
"@AnnotationAnnotation(arrayValue = {\n" +
" @BooleanAnnotation(arrayValue = { true, false }, value = true),\n" + /* XXX */
" @BooleanAnnotation(arrayValue = { true, true}, value = true)},\n" + /* XXX */
" value = @BooleanAnnotation(arrayValue = {true, false}, value = true))\n" +
"public class FooBar {}";
String cls = constructTypeWithAnnotation(constructAnnotationAnnotation(constructBooleanAnnotation(true, false), constructBooleanAnnotation(true, true)));
assertEquals(expected, cls);
}
private static String constructTypeWithAnnotation(Annotation... annotations) {
ClassStructureBuilder<?> builder = ClassBuilder.define("FooBar").publicScope().body();
for (Annotation annotation : annotations) {
builder.getClassDefinition().addAnnotation(annotation);
}
return builder.toJavaString();
}
private enum SimpleEnum {
YES, NO
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface BooleanAnnotation {
boolean value();
boolean[] arrayValue();
}
private static BooleanAnnotation constructBooleanAnnotation(final boolean... values) {
return new BooleanAnnotation() {
@Override
public boolean value() {
return values[0];
}
@Override
public boolean[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return BooleanAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface ByteAnnotation {
byte value();
byte[] arrayValue();
}
private static ByteAnnotation constructByteAnnotation(final byte... values) {
return new ByteAnnotation() {
@Override
public byte value() {
return values[0];
}
@Override
public byte[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return ByteAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface CharAnnotation {
char value();
char[] arrayValue();
}
private static CharAnnotation constructCharAnnotation(final char... values) {
return new CharAnnotation() {
@Override
public char value() {
return values[0];
}
@Override
public char[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return CharAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface ShortAnnotation {
short value();
short[] arrayValue();
}
private static ShortAnnotation constructShortAnnotation(final short... values) {
return new ShortAnnotation() {
@Override
public short value() {
return values[0];
}
@Override
public short[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return ShortAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface IntAnnotation {
int value();
int[] arrayValue();
}
private static IntAnnotation constructIntAnnotation(final int... values) {
return new IntAnnotation() {
@Override
public int value() {
return values[0];
}
@Override
public int[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return IntAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface LongAnnotation {
long value();
long[] arrayValue();
}
private static LongAnnotation constructLongAnnotation(final long... values) {
return new LongAnnotation() {
@Override
public long value() {
return values[0];
}
@Override
public long[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return LongAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface FloatAnnotation {
float value();
float[] arrayValue();
}
private static FloatAnnotation constructFloatAnnotation(final float... values) {
return new FloatAnnotation() {
@Override
public float value() {
return values[0];
}
@Override
public float[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return FloatAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface DoubleAnnotation {
double value();
double[] arrayValue();
}
private static DoubleAnnotation constructDoubleAnnotation(final double... values) {
return new DoubleAnnotation() {
@Override
public double value() {
return values[0];
}
@Override
public double[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return DoubleAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface StringAnnotation {
String value();
String[] arrayValue();
}
private static StringAnnotation constructStringAnnotation(final String... values) {
return new StringAnnotation() {
@Override
public String value() {
return values[0];
}
@Override
public String[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return StringAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface ClassAnnotation {
Class<?> value();
Class<?>[] arrayValue();
}
private static ClassAnnotation constructClassAnnotation(final Class<?>... values) {
return new ClassAnnotation() {
@Override
public Class<?> value() {
return values[0];
}
@Override
public Class<?>[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return ClassAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface EnumAnnotation {
SimpleEnum value();
SimpleEnum[] arrayValue();
}
private static EnumAnnotation constructEnumAnnotation(final SimpleEnum... values) {
return new EnumAnnotation() {
@Override
public SimpleEnum value() {
return values[0];
}
@Override
public SimpleEnum[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return EnumAnnotation.class;
}
};
}
@Target(TYPE)
@Retention(RUNTIME)
private @interface AnnotationAnnotation {
BooleanAnnotation value();
BooleanAnnotation[] arrayValue();
}
private static AnnotationAnnotation constructAnnotationAnnotation(final BooleanAnnotation... values) {
return new AnnotationAnnotation() {
@Override
public BooleanAnnotation value() {
return values[0];
}
@Override
public BooleanAnnotation[] arrayValue() {
return values;
}
@Override
public Class<? extends Annotation> annotationType() {
return AnnotationAnnotation.class;
}
};
}
}