1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.util;
21
22 import com.sun.tools.javac.code.Attribute;
23 import org.grouplens.grapht.annotation.AnnotationBuilder;
24 import org.grouplens.grapht.reflect.internal.types.InterfaceA;
25 import org.junit.Assert;
26 import org.junit.Test;
27
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30
31
32 public class AnnotationBuilderTest {
33 @Test
34 public void testArrayCloned() {
35
36
37
38
39 double[] original = new double[] { 4.0 };
40 A3 built = new AnnotationBuilder<A3>(A3.class).set("otherValue", original).build();
41 double[] fromAnnot = built.otherValue();
42
43 original[0] = 5.0;
44 Assert.assertEquals(4.0, fromAnnot[0], 0.00001);
45
46 fromAnnot[0] = 6.0;
47 Assert.assertEquals(4.0, built.otherValue()[0], 0.00001);
48 }
49
50 @Test
51 public void testDefaultValue() {
52
53 A3 built = new AnnotationBuilder<A3>(A3.class).set("otherValue", new double[0]).build();
54
55 Assert.assertEquals("hello", built.value());
56 }
57
58 @Test(expected=IllegalArgumentException.class)
59 public void testUnknownAttribute() {
60
61
62 new AnnotationBuilder<A3>(A3.class).set("notPresent", 4).build();
63 }
64
65 @Test(expected=IllegalArgumentException.class)
66 public void testWrongSetter() {
67
68
69 new AnnotationBuilder<A2>(A2.class).set("value", 6.0).build();
70 }
71
72 @Test(expected=IllegalStateException.class)
73 public void testNoValueAssignedForRequiredAttribute() {
74
75 new AnnotationBuilder<A2>(A2.class).build();
76 }
77
78 @Test
79 public void testSetValues() {
80
81 Types t = new AnnotationBuilder<Types>(Types.class)
82 .set("v1", (byte) 1)
83 .set("v2", (short) 2)
84 .set("v3", 3)
85 .set("v4", 4L)
86 .set("v5", '5')
87 .set("v6", 6f)
88 .set("v7", 7.0)
89 .set("v8", "8")
90 .set("v9", new byte[] { 9 })
91 .set("v10", new short[] { 10 })
92 .set("v11", new int[] { 11 })
93 .set("v12", new long[] { 12 })
94 .set("v13", new char[] { 't' })
95 .set("v14", new float[] { 14f })
96 .set("v15", new double[] { 15.0 })
97 .set("v16", new String[] { "16" })
98 .set("v17", new AnnotationBuilder<A2>(A2.class).set("value", 17).build())
99 .set("v18", new A2[] { new AnnotationBuilder<A2>(A2.class).set("value", 18).build() })
100 .set("v19", true)
101 .set("v20", new boolean[]{true, false})
102 .set("v21", new AnnotationBuilder<A5>(A5.class).set("value", 0).build())
103 .set("v22", new AnnotationBuilder<A6>(A6.class).set("value", Class.class).build())
104 .build();
105
106 Assert.assertEquals((byte) 1, t.v1());
107 Assert.assertEquals((short) 2, t.v2());
108 Assert.assertEquals(3, t.v3());
109 Assert.assertEquals(4L, t.v4());
110 Assert.assertEquals('5', t.v5());
111 Assert.assertEquals(6f, t.v6(), 0.00001f);
112 Assert.assertEquals(7.0, t.v7(), 0.00001);
113 Assert.assertEquals("8", t.v8());
114
115 Assert.assertEquals(1, t.v9().length);
116 Assert.assertEquals((byte) 9, t.v9()[0]);
117
118 Assert.assertEquals(1, t.v10().length);
119 Assert.assertEquals((short) 10, t.v10()[0]);
120
121 Assert.assertEquals(1, t.v11().length);
122 Assert.assertEquals(11, t.v11()[0]);
123
124 Assert.assertEquals(1, t.v12().length);
125 Assert.assertEquals(12L, t.v12()[0]);
126
127 Assert.assertEquals(1, t.v13().length);
128 Assert.assertEquals('t', t.v13()[0]);
129
130 Assert.assertEquals(1, t.v14().length);
131 Assert.assertEquals(14f, t.v14()[0], 0.00001f);
132
133 Assert.assertEquals(1, t.v15().length);
134 Assert.assertEquals(15.0, t.v15()[0], 0.00001);
135
136 Assert.assertEquals(1, t.v16().length);
137 Assert.assertEquals("16", t.v16()[0]);
138
139 Assert.assertEquals(17, t.v17().value());
140
141 Assert.assertEquals(1, t.v18().length);
142 Assert.assertEquals(18, t.v18()[0].value());
143
144 Assert.assertTrue(t.v19());
145
146 Assert.assertEquals(2, t.v20().length);
147 Assert.assertTrue(t.v20()[0]);
148 Assert.assertFalse(t.v20()[1]);
149
150 Assert.assertEquals(RestrictionType.NONE, t.v21().type());
151
152 Assert.assertEquals(Class.class, t.v22().value());
153
154 }
155
156 @Test
157 public void testNoAttributes() {
158
159
160 A1 built = new AnnotationBuilder<A1>(A1.class).build();
161
162 Assert.assertEquals(A1.class, built.annotationType());
163 Assert.assertTrue(built.equals(jvmA1a1));
164 Assert.assertTrue(jvmA1a1.equals(built));
165 Assert.assertEquals(jvmA1a1.hashCode(), built.hashCode());
166 }
167
168 @Test
169 public void testSingleAttribute() {
170
171
172 A2 equal = new AnnotationBuilder<A2>(A2.class).set("value", 4).build();
173 A2 notEqual = new AnnotationBuilder<A2>(A2.class).set("value", 0).build();
174
175 Assert.assertEquals(A2.class, equal.annotationType());
176 Assert.assertEquals(A2.class, notEqual.annotationType());
177 Assert.assertTrue(equal.equals(jvmA2a1));
178 Assert.assertTrue(jvmA2a1.equals(equal));
179 Assert.assertEquals(jvmA2a1.hashCode(), equal.hashCode());
180
181 Assert.assertFalse(notEqual.equals(jvmA2a1));
182 Assert.assertFalse(jvmA2a1.equals(notEqual));
183 Assert.assertFalse(jvmA2a1.hashCode() == notEqual.hashCode());
184 }
185
186 @Test
187 public void testMultipleAttribute() {
188
189
190 A3 equal = new AnnotationBuilder<A3>(A3.class).set("value", "world")
191 .set("otherValue", new double[] { 1.0, 2.0 })
192 .build();
193 A3 notEqual = new AnnotationBuilder<A3>(A3.class).set("value", "hoopla")
194 .set("otherValue", new double[] { 1.0, 2.0 })
195 .build();
196
197 Assert.assertEquals(A3.class, equal.annotationType());
198 Assert.assertEquals(A3.class, notEqual.annotationType());
199 Assert.assertTrue(equal.equals(jvmA3a1));
200 Assert.assertTrue(jvmA3a1.equals(equal));
201 Assert.assertEquals(jvmA3a1.hashCode(), equal.hashCode());
202
203 Assert.assertFalse(notEqual.equals(jvmA3a1));
204 Assert.assertFalse(jvmA3a1.equals(notEqual));
205 Assert.assertFalse(jvmA3a1.hashCode() == notEqual.hashCode());
206 }
207
208 @Test
209 public void testAnnotationArrayAttribute() {
210
211
212 A4 equal = new AnnotationBuilder<A4>(A4.class).set("arrays", new A3[] {
213 new AnnotationBuilder<A3>(A3.class).set("otherValue", new double[] { 0.5 }).build(),
214 new AnnotationBuilder<A3>(A3.class).set("otherValue", new double[] { 0.0 })
215 .set("value", "george").build()
216 }).build();
217 A4 notEqual = new AnnotationBuilder<A4>(A4.class).set("arrays", new A3[] {
218 new AnnotationBuilder<A3>(A3.class).set("otherValue", new double[] { 0.4, 0.2 }).build(),
219 new AnnotationBuilder<A3>(A3.class).set("otherValue", new double[] { 0.0, 2.3 })
220 .set("value", "bob").build()
221 }).build();
222
223 Assert.assertEquals(A4.class, equal.annotationType());
224 Assert.assertEquals(A4.class, notEqual.annotationType());
225 Assert.assertTrue(equal.equals(jvmA4a1));
226 Assert.assertTrue(jvmA4a1.equals(equal));
227 Assert.assertEquals(jvmA4a1.hashCode(), equal.hashCode());
228
229 Assert.assertFalse(notEqual.equals(jvmA4a1));
230 Assert.assertFalse(jvmA4a1.equals(notEqual));
231 Assert.assertFalse(jvmA4a1.hashCode() == notEqual.hashCode());
232 }
233
234 private static final A1 jvmA1a1;
235 private static final A2 jvmA2a1;
236 private static final A3 jvmA3a1;
237 private static final A4 jvmA4a1;
238
239 static {
240 try {
241 jvmA1a1 = AP.class.
242 getMethod("a1").getAnnotation(A1.class);
243 jvmA2a1 = AP.class.getMethod("a1").getAnnotation(A2.class);
244 jvmA3a1 = AP.class.getMethod("a1").getAnnotation(A3.class);
245 jvmA4a1 = AP.class.getMethod("a1").getAnnotation(A4.class);
246 } catch(Exception e) {
247 throw new RuntimeException(e);
248 }
249 }
250
251 public static class AP {
252 @A1
253 @A2(4)
254 @A3(otherValue={ 1.0, 2.0 }, value="world")
255 @A4(arrays={ @A3(otherValue=0.5), @A3(otherValue=0.0, value="george") })
256 public void a1() { }
257 }
258
259 @Retention(RetentionPolicy.RUNTIME)
260 public static @interface A1 { }
261
262 @Retention(RetentionPolicy.RUNTIME)
263 public static @interface A2 {
264 int value();
265 }
266
267 @Retention(RetentionPolicy.RUNTIME)
268 public static @interface A3 {
269 double[] otherValue();
270 String value() default "hello";
271 }
272
273 @Retention(RetentionPolicy.RUNTIME)
274 public static @interface A4 {
275 A3[] arrays();
276 }
277
278 @Retention(RetentionPolicy.RUNTIME)
279 public static @interface A5 {
280 int value() default 0;
281 RestrictionType type() default RestrictionType.NONE;
282 }
283
284 public enum RestrictionType {
285 NONE, LENGTH, FRACTION_DIGIT
286 }
287
288 @Retention(RetentionPolicy.RUNTIME)
289 public static @interface A6 {
290 Class value() default Class.class;
291 }
292
293 @Retention(RetentionPolicy.RUNTIME)
294 public static @interface Types {
295 byte v1();
296 short v2();
297 int v3();
298 long v4();
299 char v5();
300 float v6();
301 double v7();
302 String v8();
303 byte[] v9();
304 short[] v10();
305 int[] v11();
306 long[] v12();
307 char[] v13();
308 float[] v14();
309 double[] v15();
310 String[] v16();
311 A2 v17();
312 A2[] v18();
313 boolean v19();
314 boolean[] v20();
315 A5 v21();
316 A6 v22();
317 }
318 }