20
20
import java .lang .annotation .Repeatable ;
21
21
import java .lang .annotation .Retention ;
22
22
import java .lang .annotation .RetentionPolicy ;
23
+ import java .util .Arrays ;
23
24
25
+ import org .junit .jupiter .api .Nested ;
24
26
import org .junit .jupiter .api .Test ;
25
27
26
28
import static org .assertj .core .api .Assertions .assertThat ;
31
33
* Tests for {@link RepeatableContainers}.
32
34
*
33
35
* @author Phillip Webb
36
+ * @author Sam Brannen
34
37
*/
35
38
class RepeatableContainersTests {
36
39
37
- @ Test
38
- void standardRepeatablesWhenNonRepeatableReturnsNull () {
39
- Object [] values = findRepeatedAnnotationValues (
40
- RepeatableContainers .standardRepeatables (), WithNonRepeatable .class ,
41
- NonRepeatable .class );
42
- assertThat (values ).isNull ();
43
- }
40
+ @ Nested
41
+ class StandardRepeatableContainersTests {
44
42
45
- @ Test
46
- void standardRepeatablesWhenSingleReturnsNull () {
47
- Object [] values = findRepeatedAnnotationValues (
48
- RepeatableContainers .standardRepeatables (),
49
- WithSingleStandardRepeatable .class , StandardRepeatable .class );
50
- assertThat (values ).isNull ();
51
- }
43
+ @ Test
44
+ void standardRepeatablesWhenNonRepeatableReturnsNull () {
45
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .standardRepeatables (),
46
+ NonRepeatableTestCase .class , NonRepeatable .class );
47
+ assertThat (values ).isNull ();
48
+ }
52
49
53
- @ Test
54
- void standardRepeatablesWhenContainerReturnsRepeats () {
55
- Object [] values = findRepeatedAnnotationValues (
56
- RepeatableContainers .standardRepeatables (), WithStandardRepeatables .class ,
57
- StandardContainer .class );
58
- assertThat (values ).containsExactly ("a" , "b" );
59
- }
50
+ @ Test
51
+ void standardRepeatablesWhenSingleReturnsNull () {
52
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .standardRepeatables (),
53
+ SingleStandardRepeatableTestCase .class , StandardRepeatable .class );
54
+ assertThat (values ).isNull ();
55
+ }
60
56
61
- @ Test
62
- void standardRepeatablesWhenContainerButNotRepeatableReturnsNull () {
63
- Object [] values = findRepeatedAnnotationValues (
64
- RepeatableContainers .standardRepeatables (), WithExplicitRepeatables .class ,
65
- ExplicitContainer .class );
66
- assertThat (values ).isNull ();
67
- }
57
+ @ Test
58
+ void standardRepeatablesWhenContainerButNotRepeatableReturnsNull () {
59
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .standardRepeatables (),
60
+ ExplicitRepeatablesTestCase .class , ExplicitContainer .class );
61
+ assertThat (values ).isNull ();
62
+ }
68
63
69
- @ Test
70
- void ofExplicitWhenNonRepeatableReturnsNull () {
71
- Object [] values = findRepeatedAnnotationValues (
72
- RepeatableContainers .of (ExplicitRepeatable .class ,
73
- ExplicitContainer .class ),
74
- WithNonRepeatable .class , NonRepeatable .class );
75
- assertThat (values ).isNull ();
64
+ @ Test
65
+ void standardRepeatablesWhenContainerReturnsRepeats () {
66
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .standardRepeatables (),
67
+ StandardRepeatablesTestCase .class , StandardContainer .class );
68
+ assertThat (values ).containsExactly ("a" , "b" );
69
+ }
76
70
}
77
71
78
- @ Test
79
- void ofExplicitWhenStandardRepeatableContainerReturnsNull () {
80
- Object [] values = findRepeatedAnnotationValues (
81
- RepeatableContainers .of (ExplicitRepeatable .class ,
82
- ExplicitContainer .class ),
83
- WithStandardRepeatables .class , StandardContainer .class );
84
- assertThat (values ).isNull ();
85
- }
72
+ @ Nested
73
+ class ExplicitRepeatableContainerTests {
86
74
87
- @ Test
88
- void ofExplicitWhenContainerReturnsRepeats () {
89
- Object [] values = findRepeatedAnnotationValues (
90
- RepeatableContainers .of (ExplicitRepeatable .class ,
91
- ExplicitContainer .class ),
92
- WithExplicitRepeatables .class , ExplicitContainer .class );
93
- assertThat (values ).containsExactly ("a" , "b" );
94
- }
75
+ @ Test
76
+ void ofExplicitWhenNonRepeatableReturnsNull () {
77
+ Object [] values = findRepeatedAnnotationValues (
78
+ RepeatableContainers .of (ExplicitRepeatable .class , ExplicitContainer .class ),
79
+ NonRepeatableTestCase .class , NonRepeatable .class );
80
+ assertThat (values ).isNull ();
81
+ }
95
82
96
- @ Test
97
- void ofExplicitWhenHasNoValueThrowsException () {
98
- assertThatExceptionOfType (AnnotationConfigurationException .class ).isThrownBy (() ->
99
- RepeatableContainers .of (ExplicitRepeatable .class , InvalidNoValue .class ))
100
- .withMessageContaining ("Invalid declaration of container type ["
101
- + InvalidNoValue .class .getName ()
102
- + "] for repeatable annotation ["
103
- + ExplicitRepeatable .class .getName () + "]" );
104
- }
83
+ @ Test
84
+ void ofExplicitWhenStandardRepeatableContainerReturnsNull () {
85
+ Object [] values = findRepeatedAnnotationValues (
86
+ RepeatableContainers .of (ExplicitRepeatable .class , ExplicitContainer .class ),
87
+ StandardRepeatablesTestCase .class , StandardContainer .class );
88
+ assertThat (values ).isNull ();
89
+ }
105
90
106
- @ Test
107
- void ofExplicitWhenValueIsNotArrayThrowsException () {
108
- assertThatExceptionOfType (AnnotationConfigurationException .class ).isThrownBy (() ->
109
- RepeatableContainers .of (ExplicitRepeatable .class , InvalidNotArray .class ))
110
- .withMessage ("Container type ["
111
- + InvalidNotArray .class .getName ()
112
- + "] must declare a 'value' attribute for an array of type ["
113
- + ExplicitRepeatable .class .getName () + "]" );
114
- }
91
+ @ Test
92
+ void ofExplicitWhenContainerReturnsRepeats () {
93
+ Object [] values = findRepeatedAnnotationValues (
94
+ RepeatableContainers .of (ExplicitRepeatable .class , ExplicitContainer .class ),
95
+ ExplicitRepeatablesTestCase .class , ExplicitContainer .class );
96
+ assertThat (values ).containsExactly ("a" , "b" );
97
+ }
115
98
116
- @ Test
117
- void ofExplicitWhenValueIsArrayOfWrongTypeThrowsException () {
118
- assertThatExceptionOfType (AnnotationConfigurationException .class ).isThrownBy (() ->
119
- RepeatableContainers .of (ExplicitRepeatable .class , InvalidWrongArrayType .class ))
120
- .withMessage ("Container type ["
121
- + InvalidWrongArrayType .class .getName ()
122
- + "] must declare a 'value' attribute for an array of type ["
123
- + ExplicitRepeatable .class .getName () + "]" );
124
- }
99
+ @ Test
100
+ void ofExplicitWhenContainerIsNullDeducesContainer () {
101
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .of (StandardRepeatable .class , null ),
102
+ StandardRepeatablesTestCase .class , StandardContainer .class );
103
+ assertThat (values ).containsExactly ("a" , "b" );
104
+ }
125
105
126
- @ Test
127
- void ofExplicitWhenAnnotationIsNullThrowsException () {
128
- assertThatIllegalArgumentException ().isThrownBy (() ->
129
- RepeatableContainers .of (null , null ))
130
- .withMessage ("Repeatable must not be null" );
131
- }
106
+ @ Test
107
+ void ofExplicitWhenHasNoValueThrowsException () {
108
+ assertThatExceptionOfType (AnnotationConfigurationException .class )
109
+ .isThrownBy (() -> RepeatableContainers .of (ExplicitRepeatable .class , InvalidNoValue .class ))
110
+ .withMessageContaining ("Invalid declaration of container type [%s] for repeatable annotation [%s]" ,
111
+ InvalidNoValue .class .getName (), ExplicitRepeatable .class .getName ());
112
+ }
132
113
133
- @ Test
134
- void ofExplicitWhenContainerIsNullDeducesContainer () {
135
- Object [] values = findRepeatedAnnotationValues (
136
- RepeatableContainers .of (StandardRepeatable .class , null ),
137
- WithStandardRepeatables .class , StandardContainer .class );
138
- assertThat (values ).containsExactly ("a" , "b" );
139
- }
114
+ @ Test
115
+ void ofExplicitWhenValueIsNotArrayThrowsException () {
116
+ assertThatExceptionOfType (AnnotationConfigurationException .class )
117
+ .isThrownBy (() -> RepeatableContainers .of (ExplicitRepeatable .class , InvalidNotArray .class ))
118
+ .withMessage ("Container type [%s] must declare a 'value' attribute for an array of type [%s]" ,
119
+ InvalidNotArray .class .getName (), ExplicitRepeatable .class .getName ());
120
+ }
121
+
122
+ @ Test
123
+ void ofExplicitWhenValueIsArrayOfWrongTypeThrowsException () {
124
+ assertThatExceptionOfType (AnnotationConfigurationException .class )
125
+ .isThrownBy (() -> RepeatableContainers .of (ExplicitRepeatable .class , InvalidWrongArrayType .class ))
126
+ .withMessage ("Container type [%s] must declare a 'value' attribute for an array of type [%s]" ,
127
+ InvalidWrongArrayType .class .getName (), ExplicitRepeatable .class .getName ());
128
+ }
129
+
130
+ @ Test
131
+ void ofExplicitWhenAnnotationIsNullThrowsException () {
132
+ assertThatIllegalArgumentException ()
133
+ .isThrownBy (() -> RepeatableContainers .of (null , null ))
134
+ .withMessage ("Repeatable must not be null" );
135
+ }
136
+
137
+ @ Test
138
+ void ofExplicitWhenContainerIsNullAndNotRepeatableThrowsException () {
139
+ assertThatIllegalArgumentException ()
140
+ .isThrownBy (() -> RepeatableContainers .of (ExplicitRepeatable .class , null ))
141
+ .withMessage ("Annotation type must be a repeatable annotation: failed to resolve container type for %s" ,
142
+ ExplicitRepeatable .class .getName ());
143
+ }
140
144
141
- @ Test
142
- void ofExplicitWhenContainerIsNullAndNotRepeatableThrowsException () {
143
- assertThatIllegalArgumentException ().isThrownBy (() ->
144
- RepeatableContainers .of (ExplicitRepeatable .class , null ))
145
- .withMessage ("Annotation type must be a repeatable annotation: " +
146
- "failed to resolve container type for " +
147
- ExplicitRepeatable .class .getName ());
148
145
}
149
146
150
147
@ Test
151
148
void standardAndExplicitReturnsRepeats () {
152
- RepeatableContainers repeatableContainers = RepeatableContainers .standardRepeatables ().and (
153
- ExplicitContainer .class , ExplicitRepeatable .class );
154
- assertThat (findRepeatedAnnotationValues (repeatableContainers ,
155
- WithStandardRepeatables .class , StandardContainer .class )).containsExactly (
156
- "a" , "b" );
157
- assertThat (findRepeatedAnnotationValues (repeatableContainers ,
158
- WithExplicitRepeatables .class , ExplicitContainer .class )).containsExactly (
159
- "a" , "b" );
149
+ RepeatableContainers repeatableContainers = RepeatableContainers .standardRepeatables ()
150
+ .and (ExplicitContainer .class , ExplicitRepeatable .class );
151
+ assertThat (findRepeatedAnnotationValues (repeatableContainers , StandardRepeatablesTestCase .class , StandardContainer .class ))
152
+ .containsExactly ("a" , "b" );
153
+ assertThat (findRepeatedAnnotationValues (repeatableContainers , ExplicitRepeatablesTestCase .class , ExplicitContainer .class ))
154
+ .containsExactly ("a" , "b" );
160
155
}
161
156
162
157
@ Test
163
158
void noneAlwaysReturnsNull () {
164
- Object [] values = findRepeatedAnnotationValues (
165
- RepeatableContainers .none (), WithStandardRepeatables .class ,
166
- StandardContainer .class );
159
+ Object [] values = findRepeatedAnnotationValues (RepeatableContainers .none (), StandardRepeatablesTestCase .class ,
160
+ StandardContainer .class );
167
161
assertThat (values ).isNull ();
168
162
}
169
163
170
164
@ Test
171
165
void equalsAndHashcode () {
172
- RepeatableContainers c1 = RepeatableContainers .of (ExplicitRepeatable .class ,
173
- ExplicitContainer .class );
174
- RepeatableContainers c2 = RepeatableContainers .of (ExplicitRepeatable .class ,
175
- ExplicitContainer .class );
166
+ RepeatableContainers c1 = RepeatableContainers .of (ExplicitRepeatable .class , ExplicitContainer .class );
167
+ RepeatableContainers c2 = RepeatableContainers .of (ExplicitRepeatable .class , ExplicitContainer .class );
176
168
RepeatableContainers c3 = RepeatableContainers .standardRepeatables ();
177
- RepeatableContainers c4 = RepeatableContainers .standardRepeatables ().and (
178
- ExplicitContainer .class , ExplicitRepeatable .class );
179
- assertThat (c1 .hashCode ()).isEqualTo (c2 .hashCode ());
169
+ RepeatableContainers c4 = RepeatableContainers .standardRepeatables ().and (ExplicitContainer .class , ExplicitRepeatable .class );
170
+ assertThat (c1 ).hasSameHashCodeAs (c2 );
180
171
assertThat (c1 ).isEqualTo (c1 ).isEqualTo (c2 );
181
172
assertThat (c1 ).isNotEqualTo (c3 ).isNotEqualTo (c4 );
182
173
}
183
174
184
- private Object [] findRepeatedAnnotationValues (RepeatableContainers containers ,
175
+
176
+ private static Object [] findRepeatedAnnotationValues (RepeatableContainers containers ,
185
177
Class <?> element , Class <? extends Annotation > annotationType ) {
186
- Annotation [] annotations = containers .findRepeatedAnnotations (
187
- element .getAnnotation (annotationType ));
178
+ Annotation [] annotations = containers .findRepeatedAnnotations (element .getAnnotation (annotationType ));
188
179
return extractValues (annotations );
189
180
}
190
181
191
- private Object [] extractValues (Annotation [] annotations ) {
192
- try {
193
- if (annotations == null ) {
194
- return null ;
195
- }
196
- Object [] result = new String [annotations .length ];
197
- for (int i = 0 ; i < annotations .length ; i ++) {
198
- result [i ] = annotations [i ].annotationType ().getMethod ("value" ).invoke (
199
- annotations [i ]);
200
- }
201
- return result ;
202
- }
203
- catch (Exception ex ) {
204
- throw new RuntimeException (ex );
182
+ private static Object [] extractValues (Annotation [] annotations ) {
183
+ if (annotations == null ) {
184
+ return null ;
205
185
}
186
+ return Arrays .stream (annotations ).map (AnnotationUtils ::getValue ).toArray (Object []::new );
206
187
}
207
188
208
- @ Retention (RetentionPolicy .RUNTIME )
209
- @interface NonRepeatable {
210
-
211
- String value () default "" ;
212
- }
213
189
214
190
@ Retention (RetentionPolicy .RUNTIME )
215
- @ Repeatable (StandardContainer .class )
216
- @interface StandardRepeatable {
191
+ @interface NonRepeatable {
217
192
218
193
String value () default "" ;
219
194
}
@@ -225,7 +200,8 @@ private Object[] extractValues(Annotation[] annotations) {
225
200
}
226
201
227
202
@ Retention (RetentionPolicy .RUNTIME )
228
- @interface ExplicitRepeatable {
203
+ @ Repeatable (StandardContainer .class )
204
+ @interface StandardRepeatable {
229
205
230
206
String value () default "" ;
231
207
}
@@ -236,6 +212,12 @@ private Object[] extractValues(Annotation[] annotations) {
236
212
ExplicitRepeatable [] value ();
237
213
}
238
214
215
+ @ Retention (RetentionPolicy .RUNTIME )
216
+ @interface ExplicitRepeatable {
217
+
218
+ String value () default "" ;
219
+ }
220
+
239
221
@ Retention (RetentionPolicy .RUNTIME )
240
222
@interface InvalidNoValue {
241
223
}
@@ -253,20 +235,20 @@ private Object[] extractValues(Annotation[] annotations) {
253
235
}
254
236
255
237
@ NonRepeatable ("a" )
256
- static class WithNonRepeatable {
238
+ static class NonRepeatableTestCase {
257
239
}
258
240
259
241
@ StandardRepeatable ("a" )
260
- static class WithSingleStandardRepeatable {
242
+ static class SingleStandardRepeatableTestCase {
261
243
}
262
244
263
245
@ StandardRepeatable ("a" )
264
246
@ StandardRepeatable ("b" )
265
- static class WithStandardRepeatables {
247
+ static class StandardRepeatablesTestCase {
266
248
}
267
249
268
250
@ ExplicitContainer ({ @ ExplicitRepeatable ("a" ), @ ExplicitRepeatable ("b" ) })
269
- static class WithExplicitRepeatables {
251
+ static class ExplicitRepeatablesTestCase {
270
252
}
271
253
272
254
}
0 commit comments