1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.annotation;
18
19 import static org.apache.juneau.junit.bct.BctAssertions.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.lang.annotation.*;
23 import java.util.*;
24
25 import org.apache.juneau.*;
26 import org.junit.jupiter.api.*;
27
28 class AnnotationObject_Test extends TestBase {
29
30
31
32
33
34 @Target({ ElementType.TYPE, ElementType.METHOD })
35 @Retention(RetentionPolicy.RUNTIME)
36 public @interface TA {
37 String value() default "";
38
39 int number() default 0;
40
41 boolean flag() default false;
42
43 String[] array() default {};
44 }
45
46
47
48
49 public static class T extends AnnotationObject implements TA {
50
51 private final String value;
52 private final int number;
53 private final boolean flag;
54 private final String[] array;
55
56 public static class Builder extends AnnotationObject.Builder {
57 String value = "";
58 int number = 0;
59 boolean flag = false;
60 String[] array = {};
61
62 public Builder() {
63 super(TA.class);
64 }
65
66 public Builder value(String _value) {
67 value = _value;
68 return this;
69 }
70
71 public Builder number(int value) {
72 number = value;
73 return this;
74 }
75
76 public Builder flag(boolean value) {
77 flag = value;
78 return this;
79 }
80
81 public Builder array(String...value) {
82 array = value;
83 return this;
84 }
85
86 public TA build() {
87 return new T(this);
88 }
89 }
90
91 public static Builder create() {
92 return new Builder();
93 }
94
95 public T(Builder b) {
96 super(b);
97 value = b.value;
98 number = b.number;
99 flag = b.flag;
100 array = Arrays.copyOf(b.array, b.array.length);
101 }
102
103 @Override
104 public String value() {
105 return value;
106 }
107
108 @Override
109 public int number() {
110 return number;
111 }
112
113 @Override
114 public boolean flag() {
115 return flag;
116 }
117
118 @Override
119 public String[] array() {
120 return array;
121 }
122 }
123
124
125
126
127
128 @Test
129 void a01_basic_defaultValues() {
130 var a = T.create().build();
131 assertBean(a, "value,number,flag,array", ",0,false,[]");
132 }
133
134 @Test
135 void a02_basic_customValues() {
136 var a = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
137 assertBean(a, "value,number,flag,array", "a,1,true,[b1,b2]");
138 }
139
140 @Test
141 void a03_basic_annotationType() {
142 var a = T.create().build();
143 assertEquals(TA.class, a.annotationType());
144 }
145
146
147
148
149
150 @Test
151 void b01_equality_identical() {
152 var a1 = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
153
154 var a2 = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
155
156 assertEquals(a1, a2);
157 assertEquals(a1.hashCode(), a2.hashCode());
158 }
159
160 @Test
161 void b02_equality_different() {
162 var a1 = T.create().value("a1").build();
163
164 var a2 = T.create().value("a2").build();
165
166 assertNotEquals(a1, a2);
167 }
168
169 @Test
170 void b03_equality_withDeclaredAnnotation() {
171 @TA(value = "a", number = 1, flag = true, array = { "b1", "b2" })
172 class B {}
173
174 var declared = B.class.getAnnotation(TA.class);
175 var programmatic = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
176
177 assertEquals(declared, programmatic);
178 assertEquals(declared.hashCode(), programmatic.hashCode());
179 }
180
181 @Test
182 void b04_hashCode_consistency() {
183 var a = T.create().value("a").number(1).build();
184
185 var hash1 = a.hashCode();
186 var hash2 = a.hashCode();
187 assertEquals(hash1, hash2, "hashCode should be consistent");
188 }
189
190 @Test
191 void b05_hashCode_notNegativeOne() {
192 var a = T.create().build();
193 assertNotEquals(-1, a.hashCode());
194 }
195
196
197
198
199
200 @Test
201 void c01_toMap_defaultValues() {
202 var a = T.create().build();
203 assertBean(((T)a).propertyMap(), "value,number,flag,array", ",0,false,[]");
204 }
205
206 @Test
207 void c02_toMap_customValues() {
208 var a = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
209
210 assertBean(((T)a).propertyMap(), "value,number,flag,array", "a,1,true,[b1,b2]");
211 }
212
213 @Test
214 void c03_toMap_keySorted() {
215 var a = T.create().build();
216 var map = ((T)a).propertyMap();
217
218
219 assertList(map.keySet(), "array", "flag", "number", "value");
220 }
221
222
223
224
225
226 @Test
227 void d01_toString_notNull() {
228 var a = T.create().build();
229 var str = a.toString();
230 assertNotNull(str);
231 assertFalse(str.isEmpty());
232 }
233
234 @Test
235 void d02_toString_containsValues() {
236 var a = T.create().value("a").number(1).build();
237
238 assertContainsAll(a.toString(), "a", "1");
239 }
240
241
242
243
244
245 @Test
246 void e01_constructor_nullAnnotationType() {
247 assertThrows(IllegalArgumentException.class, () -> new AnnotationObject.Builder(null));
248 }
249
250
251
252
253
254 @Test
255 void f01_builder_fluentApi() {
256 var a = T.create().value("a").number(1).flag(true).array("b1", "b2").build();
257
258 assertBean(a, "value,number,flag,array", "a,1,true,[b1,b2]");
259 }
260
261 @Test
262 void f02_builder_multipleBuilds() {
263 var builder = T.create().value("a").number(1);
264
265 var a1 = builder.build();
266 var a2 = builder.build();
267
268
269 assertNotSame(a1, a2);
270 assertEquals(a1, a2);
271 }
272
273 @Test
274 void f03_builder_getAnnotationType() {
275 var builder = T.create();
276 assertEquals(TA.class, builder.getAnnotationType());
277 }
278
279
280
281
282
283 @Test
284 void g01_arrayEquality_emptyVsNull() {
285
286 var a1 = T.create().array().build();
287
288 var a2 = T.create().array(new String[0]).build();
289
290 assertEquals(a1, a2);
291 }
292
293 @Test
294 void g02_arrayEquality_deepEquals() {
295
296 var a1 = T.create().array("a", "b", "c").build();
297
298 var a2 = T.create().array(new String[] { "a", "b", "c" }).build();
299
300 assertEquals(a1, a2);
301 }
302
303 @Test
304 void g03_arrayEquality_differentOrder() {
305
306 var a1 = T.create().array("a", "b", "c").build();
307
308 var a2 = T.create().array("c", "b", "a").build();
309
310 assertNotEquals(a1, a2);
311 }
312
313 @Test
314 void g04_equality_differentType() {
315 var a = T.create().build();
316 var other = new Object();
317
318 assertNotEquals(a, other);
319 }
320
321 @Test
322 void g05_equality_null() {
323 var a = T.create().build();
324 assertNotEquals(a, null);
325 }
326
327
328
329
330
331 @Test
332 void h01_nullBuilder_throwsException() {
333 assertThrows(IllegalArgumentException.class, () -> new T(null));
334 }
335 }