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
24 import org.apache.juneau.*;
25 import org.apache.juneau.commons.reflect.*;
26 import org.junit.jupiter.api.*;
27
28 class AppliedOnClassAnnotationObject_Test extends TestBase {
29
30 private static final String CNAME = AppliedOnClassAnnotationObject_Test.class.getName();
31
32
33
34
35
36 @Target({ ElementType.TYPE })
37 @Retention(RetentionPolicy.RUNTIME)
38 public @interface TA {
39 String[] on() default {};
40
41 Class<?>[] onClass() default {};
42
43 String value() default "";
44 }
45
46
47
48
49 public static class T extends AppliedOnClassAnnotationObject implements TA {
50
51 private final String value;
52
53 public static class Builder extends AppliedAnnotationObject.BuilderT {
54 String value = "";
55
56 public Builder() {
57 super(TA.class);
58 }
59
60 public Builder value(String value) {
61 this.value = value;
62 return this;
63 }
64
65 @Override
66 public Builder on(String...value) {
67 super.on(value);
68 return this;
69 }
70
71 @Override
72 public Builder on(Class<?>...value) {
73 super.on(value);
74 return this;
75 }
76
77 @Override
78 public Builder on(ClassInfo...value) {
79 super.on(value);
80 return this;
81 }
82
83 @Override
84 public Builder onClass(Class<?>...value) {
85 super.onClass(value);
86 return this;
87 }
88
89 @Override
90 public Builder onClass(ClassInfo...value) {
91 super.onClass(value);
92 return this;
93 }
94
95 public TA build() {
96 return new T(this);
97 }
98 }
99
100 public static Builder create() {
101 return new Builder();
102 }
103
104 public T(Builder b) {
105 super(b);
106 value = b.value;
107 }
108
109 @Override
110 public String value() {
111 return value;
112 }
113 }
114
115
116
117
118
119 public static class TC1 {}
120
121 public static class TC2 {}
122
123 public static class TC3 {}
124
125
126
127
128
129 @Test
130 void a01_basic_noOnClass() {
131 var a = T.create().build();
132 assertList(a.onClass());
133 }
134
135 @Test
136 void a02_basic_singleClass() {
137 var a = T.create().onClass(TC1.class).build();
138
139 assertList(a.onClass(), TC1.class);
140 }
141
142 @Test
143 void a03_basic_multipleClasses() {
144 var a = T.create().onClass(TC1.class, TC2.class).build();
145
146 assertList(a.onClass(), TC1.class, TC2.class);
147 }
148
149 @Test
150 void a04_basic_withValue() {
151 var a = T.create().onClass(TC1.class).value("test").build();
152
153 assertList(a.onClass(), TC1.class);
154 assertEquals("test", a.value());
155 }
156
157 @Test
158 void a05_basic_annotationType() {
159 var a = T.create().build();
160 assertEquals(TA.class, a.annotationType());
161 }
162
163
164
165
166
167 @Test
168 void b01_onVsOnClass_onClassOnly() {
169 var a = T.create().onClass(TC1.class, TC2.class).build();
170
171
172 assertList(a.onClass(), TC1.class, TC2.class);
173
174
175 assertList(a.on());
176 }
177
178 @Test
179 void b02_onVsOnClass_onOnly() {
180 var a = T.create().on("com.example.Class1", "com.example.Class2").build();
181
182
183 assertList(a.on(), "com.example.Class1", "com.example.Class2");
184
185
186 assertList(a.onClass());
187 }
188
189 @Test
190 void b03_onVsOnClass_both() {
191 var a = T.create().on("com.example.Class1").onClass(TC1.class).build();
192
193
194 assertList(a.on(), "com.example.Class1");
195 assertList(a.onClass(), TC1.class);
196 }
197
198 @Test
199 void b04_onVsOnClass_onWithClassConversion() {
200 var a = T.create().on(TC1.class, TC2.class).build();
201
202
203 assertList(a.on(), CNAME + "$TC1", CNAME + "$TC2");
204
205
206 assertList(a.onClass());
207 }
208
209
210
211
212
213 @Test
214 void c01_classInfo_onClassInfo() {
215 var ci1 = ClassInfo.of(TC1.class);
216 var ci2 = ClassInfo.of(TC2.class);
217
218 var a = T.create().onClass(ci1, ci2).build();
219
220 assertList(a.onClass(), TC1.class, TC2.class);
221 }
222
223 @Test
224 void c02_classInfo_onClassInfo_mixed() {
225 var ci = ClassInfo.of(TC1.class);
226
227 var a = T.create().onClass(ci).onClass(TC2.class).build();
228
229 assertList(a.onClass(), TC1.class, TC2.class);
230 }
231
232
233
234
235
236 @Test
237 void d01_equality_sameOnClass() {
238 var a1 = T.create().onClass(TC1.class, TC2.class).value("test").build();
239
240 var a2 = T.create().onClass(TC1.class, TC2.class).value("test").build();
241
242 assertEquals(a1, a2);
243 assertEquals(a1.hashCode(), a2.hashCode());
244 }
245
246 @Test
247 void d02_equality_differentOnClass() {
248 var a1 = T.create().onClass(TC1.class).build();
249
250 var a2 = T.create().onClass(TC2.class).build();
251
252 assertNotEquals(a1, a2);
253 }
254
255 @Test
256 void d03_equality_differentOrder() {
257 var a1 = T.create().onClass(TC1.class, TC2.class).build();
258
259 var a2 = T.create().onClass(TC2.class, TC1.class).build();
260
261 assertNotEquals(a1, a2);
262 }
263
264 @Test
265 void d04_equality_withDeclaredAnnotation() {
266 @TA(onClass = { TC1.class, TC2.class }, value = "test")
267 class TestClass {}
268
269 var declared = TestClass.class.getAnnotation(TA.class);
270 var programmatic = T.create().onClass(TC1.class, TC2.class).value("test").build();
271
272 assertEquals(declared, programmatic);
273 assertEquals(declared.hashCode(), programmatic.hashCode());
274 }
275
276 @Test
277 void d05_hashCode_consistency() {
278 var a = T.create().onClass(TC1.class).value("test").build();
279
280 var hash1 = a.hashCode();
281 var hash2 = a.hashCode();
282 assertEquals(hash1, hash2, "hashCode should be consistent");
283 }
284
285
286
287
288
289 @Test
290 void e01_toMap_withOnClass() {
291 var a = T.create().onClass(TC1.class, TC2.class).value("test").build();
292 var map = ((T)a).propertyMap();
293
294 assertBean(map, "value,on,onClass", "test,[],[TC1,TC2]");
295 }
296
297 @Test
298 void e02_toMap_withBoth() {
299 var a = T.create().on("com.example.Class1").onClass(TC1.class).value("test").build();
300 var map = ((T)a).propertyMap();
301
302 assertBean(map, "value,on,onClass", "test,[com.example.Class1],[TC1]");
303 }
304
305 @Test
306 void e03_toMap_empty() {
307 var a = T.create().build();
308 var map = ((T)a).propertyMap();
309
310 assertBean(map, "value,on,onClass", ",[],[]");
311 }
312
313
314
315
316
317 @Test
318 void f01_toString_notNull() {
319 var a = T.create().build();
320 var str = a.toString();
321 assertNotNull(str);
322 assertFalse(str.isEmpty());
323 }
324
325 @Test
326 void f02_toString_containsValues() {
327 var a = T.create().onClass(TC1.class).value("test").build();
328
329 assertContainsAll(a.toString(), "test", "onClass");
330 }
331
332
333
334
335
336 @Test
337 void g01_builder_fluentApi() {
338 var a = T.create().onClass(TC1.class).value("test").onClass(TC2.class).build();
339
340 assertList(a.onClass(), TC1.class, TC2.class);
341 assertEquals("test", a.value());
342 }
343
344 @Test
345 void g02_builder_multipleBuilds() {
346 var builder = T.create().onClass(TC1.class).value("test");
347
348 var a1 = builder.build();
349 var a2 = builder.build();
350
351
352 assertNotSame(a1, a2);
353 assertEquals(a1, a2);
354 }
355
356 @Test
357 void g03_builder_chaining() {
358 var a = T.create().onClass(TC1.class).on("com.example.Class1").value("test").onClass(TC2.class).build();
359
360 assertList(a.onClass(), TC1.class, TC2.class);
361 assertList(a.on(), "com.example.Class1");
362 assertEquals("test", a.value());
363 }
364
365
366
367
368
369 @Test
370 void h01_edgeCase_emptyOnClass() {
371 var a = T.create().onClass(new Class<?>[0]).build();
372
373 assertList(a.onClass());
374 }
375
376 @Test
377 void h02_edgeCase_arrayEquality() {
378 var a1 = T.create().onClass(TC1.class, TC2.class, TC3.class).build();
379
380 var a2 = T.create().onClass(new Class<?>[] { TC1.class, TC2.class, TC3.class }).build();
381
382 assertEquals(a1, a2);
383 }
384
385 @Test
386 void h03_edgeCase_equality_differentType() {
387 var a = T.create().build();
388 var other = new Object();
389
390 assertNotEquals(a, other);
391 }
392
393 @Test
394 void h04_edgeCase_equality_null() {
395 var a = T.create().build();
396 assertNotEquals(a, null);
397 }
398
399
400
401
402
403 @Test
404 void i01_null_classInArray() {
405 assertThrows(IllegalArgumentException.class, () -> T.create().onClass((Class<?>)null).build());
406 }
407
408 @Test
409 void i02_null_classInfoInArray() {
410 assertThrows(IllegalArgumentException.class, () -> T.create().onClass((ClassInfo)null).build());
411 }
412
413 @Test
414 void i03_null_builder() {
415 assertThrows(IllegalArgumentException.class, () -> new T(null));
416 }
417 }