View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.lang3;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.lang.reflect.Constructor;
29  import java.lang.reflect.Modifier;
30  import java.util.Collection;
31  import java.util.Collections;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Set;
35  
36  import org.junit.jupiter.api.Nested;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * Tests {@link Validate}.
41   */
42  public class ValidateTest extends AbstractLangTest {
43  
44      @Nested
45      final class ExclusiveBetween {
46  
47          @Nested
48          final class WithComparable {
49  
50              @Nested
51              final class WithMessage {
52  
53                  @Test
54                  void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
55                      Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "2", "MSG");
56                  }
57  
58                  @Test
59                  void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
60                      final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
61                          () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "4", "MSG"));
62                      assertEquals("MSG", ex.getMessage());
63                  }
64  
65                  @Test
66                  void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
67                      final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
68                          () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "0", "MSG"));
69                      assertEquals("MSG", ex.getMessage());
70                  }
71  
72                  @Test
73                  void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsLowerBound() {
74                      final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
75                          () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG"));
76                      assertEquals("MSG", ex.getMessage());
77                  }
78  
79                  @Test
80                  void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsUpperBound() {
81                      final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
82                          () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG"));
83                      assertEquals("MSG", ex.getMessage());
84                  }
85              }
86              @Nested
87              final class WithoutMessage {
88  
89                  @Test
90                  void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
91                      Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "2");
92                  }
93  
94                  @Test
95                  void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
96                      final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
97                          () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "4"));
98                      assertEquals("The value 4 is not in the specified exclusive range of 1 to 3", ex.getMessage());
99                  }
100 
101                 @Test
102                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
103                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
104                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, "0"));
105                     assertEquals("The value 0 is not in the specified exclusive range of 1 to 3", ex.getMessage());
106                 }
107 
108                 @Test
109                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsLowerBound() {
110                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
111                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND));
112                     assertEquals("The value 1 is not in the specified exclusive range of 1 to 3", ex.getMessage());
113                 }
114 
115                 @Test
116                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsUpperBound() {
117                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
118                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND));
119                     assertEquals("The value 3 is not in the specified exclusive range of 1 to 3", ex.getMessage());
120                 }
121             }
122 
123             private static final String LOWER_BOUND = "1";
124 
125             private static final String UPPER_BOUND = "3";
126         }
127 
128         @Nested
129         final class WithDouble {
130 
131             @Nested
132             final class WithMessage {
133 
134                 @Test
135                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
136                     Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2.1, "MSG");
137                 }
138 
139                 @Test
140                 void shouldThrowIllegalArgumentExcdeptionWhenValueIsLowerBound() {
141                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
142                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG"));
143                     assertEquals("MSG", ex.getMessage());
144                 }
145 
146                 @Test
147                 void shouldThrowIllegalArgumentExcdeptionWhenValueIsUpperBound() {
148                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
149                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG"));
150                     assertEquals("MSG", ex.getMessage());
151                 }
152 
153                 @Test
154                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsAboveUpperBound() {
155                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
156                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4.1, "MSG"));
157                     assertEquals("MSG", ex.getMessage());
158                 }
159 
160                 @Test
161                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
162                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
163                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0.01, "MSG"));
164                     assertEquals("MSG", ex.getMessage());
165                 }
166             }
167             @Nested
168             final class WithoutMessage {
169 
170                 @Test
171                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
172                     Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2.1);
173                 }
174 
175                 @Test
176                 void shouldThrowIllegalArgumentExcdeptionWhenValueIsLowerBound() {
177                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
178                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND));
179                     assertEquals("The value 0.1 is not in the specified exclusive range of 0.1 to 3.1", ex.getMessage());
180                 }
181 
182                 @Test
183                 void shouldThrowIllegalArgumentExcdeptionWhenValueIsUpperBound() {
184                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
185                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND));
186                     assertEquals("The value 3.1 is not in the specified exclusive range of 0.1 to 3.1", ex.getMessage());
187                 }
188 
189                 @Test
190                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
191                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
192                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4.1));
193                     assertEquals("The value 4.1 is not in the specified exclusive range of 0.1 to 3.1", ex.getMessage());
194                 }
195 
196                 @Test
197                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
198                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
199                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0.01));
200                     assertEquals("The value 0.01 is not in the specified exclusive range of 0.1 to 3.1", ex.getMessage());
201                 }
202             }
203 
204             private static final double LOWER_BOUND = 0.1;
205 
206             private static final double UPPER_BOUND = 3.1;
207         }
208 
209         @Nested
210         final class WithLong {
211 
212             @Nested
213             final class WithMessage {
214 
215                 @Test
216                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
217                     Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2, "MSG");
218                 }
219 
220                 @Test
221                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
222                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
223                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4, "MSG"));
224                     assertEquals("MSG", ex.getMessage());
225                 }
226 
227                 @Test
228                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
229                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
230                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0, "MSG"));
231                     assertEquals("MSG", ex.getMessage());
232                 }
233 
234                 @Test
235                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsLowerBound() {
236                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
237                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG"));
238                     assertEquals("MSG", ex.getMessage());
239                 }
240 
241                 @Test
242                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsUpperBound() {
243                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
244                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG"));
245                     assertEquals("MSG", ex.getMessage());
246                 }
247             }
248             @Nested
249             final class WithoutMessage {
250 
251                 @Test
252                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
253                     Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2);
254                 }
255 
256                 @Test
257                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
258                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
259                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4));
260                     assertEquals("The value 4 is not in the specified exclusive range of 1 to 3", ex.getMessage());
261                 }
262 
263                 @Test
264                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
265                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
266                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0));
267                     assertEquals("The value 0 is not in the specified exclusive range of 1 to 3", ex.getMessage());
268                 }
269 
270                 @Test
271                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsLowerBound() {
272                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
273                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND));
274                     assertEquals("The value 1 is not in the specified exclusive range of 1 to 3", ex.getMessage());
275                 }
276 
277                 @Test
278                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsUpperBound() {
279                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
280                         () -> Validate.exclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND));
281                     assertEquals("The value 3 is not in the specified exclusive range of 1 to 3", ex.getMessage());
282                 }
283             }
284 
285             private static final long LOWER_BOUND = 1;
286 
287             private static final long UPPER_BOUND = 3;
288         }
289     }
290 
291     @Nested
292     final class Finite {
293 
294         @Nested
295         final class WithMessage {
296 
297             @Test
298             void shouldNotThrowExceptionForFiniteValue() {
299                 Validate.finite(0.0, "MSG");
300             }
301 
302             @Test
303             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForNaN() {
304                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.NaN, "MSG"));
305                 assertEquals("MSG", ex.getMessage());
306             }
307 
308             @Test
309             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForNegativeInfinity() {
310                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.NEGATIVE_INFINITY, "MSG"));
311                 assertEquals("MSG", ex.getMessage());
312             }
313 
314             @Test
315             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForPositiveInfinity() {
316                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.POSITIVE_INFINITY, "MSG"));
317                 assertEquals("MSG", ex.getMessage());
318             }
319         }
320 
321         @Nested
322         final class WithoutMessage {
323 
324             @Test
325             void shouldNotThrowExceptionForFiniteValue() {
326                 Validate.finite(0.0);
327             }
328 
329             @Test
330             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForNaN() {
331                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.NaN));
332                 assertEquals("The value is invalid: NaN", ex.getMessage());
333             }
334 
335             @Test
336             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForNegativeInfinity() {
337                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.NEGATIVE_INFINITY));
338                 assertEquals("The value is invalid: -Infinity", ex.getMessage());
339             }
340 
341             @Test
342             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForPositiveInfinity() {
343                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.finite(Double.POSITIVE_INFINITY));
344                 assertEquals("The value is invalid: Infinity", ex.getMessage());
345             }
346         }
347     }
348 
349     @Nested
350     final class InclusiveBetween {
351 
352         @Nested
353         final class WithComparable {
354 
355             @Nested
356             final class WithMessage {
357 
358                 @Test
359                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
360                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "2", "MSG");
361                 }
362 
363                 @Test
364                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
365                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG");
366                 }
367 
368                 @Test
369                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
370                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG");
371                 }
372 
373                 @Test
374                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsAboveUpperBound() {
375                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
376                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "4", "MSG"));
377                     assertEquals("MSG", ex.getMessage());
378                 }
379 
380                 @Test
381                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
382                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
383                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "0", "MSG"));
384                     assertEquals("MSG", ex.getMessage());
385                 }
386             }
387             @Nested
388             final class WithoutMessage {
389 
390                 @Test
391                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
392                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "2");
393                 }
394 
395                 @Test
396                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
397                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND);
398                 }
399 
400                 @Test
401                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
402                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND);
403                 }
404 
405                 @Test
406                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
407                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
408                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "4"));
409                     assertEquals("The value 4 is not in the specified inclusive range of 1 to 3", ex.getMessage());
410                 }
411 
412                 @Test
413                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
414                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
415                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, "0"));
416                     assertEquals("The value 0 is not in the specified inclusive range of 1 to 3", ex.getMessage());
417                 }
418             }
419 
420             private static final String LOWER_BOUND = "1";
421 
422             private static final String UPPER_BOUND = "3";
423         }
424 
425         @Nested
426         final class WithDouble {
427 
428             @Nested
429             final class WithMessage {
430 
431                 @Test
432                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
433                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2.1, "MSG");
434                 }
435 
436                 @Test
437                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
438                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG");
439                 }
440 
441                 @Test
442                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
443                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG");
444                 }
445 
446                 @Test
447                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsAboveUpperBound() {
448                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
449                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4.1, "MSG"));
450                     assertEquals("MSG", ex.getMessage());
451                 }
452 
453                 @Test
454                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
455                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
456                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0.01, "MSG"));
457                     assertEquals("MSG", ex.getMessage());
458                 }
459             }
460             @Nested
461             final class WithoutMessage {
462 
463                 @Test
464                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
465                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2.1);
466                 }
467 
468                 @Test
469                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
470                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND);
471                 }
472 
473                 @Test
474                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
475                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND);
476                 }
477 
478                 @Test
479                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
480                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
481                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4.1));
482                     assertEquals("The value 4.1 is not in the specified inclusive range of 0.1 to 3.1", ex.getMessage());
483                 }
484 
485                 @Test
486                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
487                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
488                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0.01));
489                     assertEquals("The value 0.01 is not in the specified inclusive range of 0.1 to 3.1", ex.getMessage());
490                 }
491             }
492 
493             private static final double LOWER_BOUND = 0.1;
494 
495             private static final double UPPER_BOUND = 3.1;
496         }
497 
498         @Nested
499         final class WithLong {
500 
501             @Nested
502             final class WithMessage {
503 
504                 @Test
505                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
506                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2, "MSG");
507                 }
508 
509                 @Test
510                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
511                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND, "MSG");
512                 }
513 
514                 @Test
515                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
516                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND, "MSG");
517                 }
518 
519                 @Test
520                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsAboveUpperBound() {
521                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
522                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4, "MSG"));
523                     assertEquals("MSG", ex.getMessage());
524                 }
525 
526                 @Test
527                 void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsBelowLowerBound() {
528                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
529                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0, "MSG"));
530                     assertEquals("MSG", ex.getMessage());
531                 }
532             }
533             @Nested
534             final class WithoutMessage {
535 
536                 @Test
537                 void shouldNotThrowExceptionWhenValueIsBetweenBounds() {
538                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 2);
539                 }
540 
541                 @Test
542                 void shouldNotThrowExceptionWhenValueIsLowerBound() {
543                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, LOWER_BOUND);
544                 }
545 
546                 @Test
547                 void shouldNotThrowExceptionWhenValueIsUpperBound() {
548                     Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, UPPER_BOUND);
549                 }
550 
551                 @Test
552                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsAboveUpperBound() {
553                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
554                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 4));
555                     assertEquals("The value 4 is not in the specified inclusive range of 1 to 3", ex.getMessage());
556                 }
557 
558                 @Test
559                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsBelowLowerBound() {
560                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
561                         () -> Validate.inclusiveBetween(LOWER_BOUND, UPPER_BOUND, 0));
562                     assertEquals("The value 0 is not in the specified inclusive range of 1 to 3", ex.getMessage());
563                 }
564             }
565 
566             private static final long LOWER_BOUND = 1;
567 
568             private static final long UPPER_BOUND = 3;
569         }
570     }
571 
572     @Nested
573     final class IsAssignable {
574 
575         @Nested
576         final class WithMessage {
577 
578             @Test
579             void shouldNotThrowExceptionWhenClassIsAssignable() {
580                 Validate.isAssignableFrom(CharSequence.class, String.class, "MSG");
581             }
582 
583             @Test
584             void shouldThrowIllegalArgumentExceptionWithGiventMessageWhenClassIsNotAssignable() {
585                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
586                     () -> Validate.isAssignableFrom(List.class, String.class, "MSG"));
587                 assertEquals("MSG", ex.getMessage());
588             }
589         }
590 
591         @Nested
592         final class WithoutMessage {
593 
594             @Test
595             void shouldNotThrowExceptionWhenClassIsAssignable() {
596                 Validate.isAssignableFrom(CharSequence.class, String.class);
597             }
598 
599             @Test
600             void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenClassIsNotAssignable() {
601                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isAssignableFrom(List.class, String.class));
602                 assertEquals("Cannot assign a java.lang.String to a java.util.List", ex.getMessage());
603             }
604 
605             @Test
606             void shouldThrowIllegalArgumentExceptionWithNullSuperType() {
607                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isAssignableFrom(null, String.class));
608                 assertEquals("Cannot assign a java.lang.String to a null type", ex.getMessage());
609             }
610 
611             @Test
612             void shouldThrowIllegalArgumentExceptionWithNullType() {
613                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isAssignableFrom(List.class, null));
614                 assertEquals("Cannot assign a null type to a java.util.List", ex.getMessage());
615             }
616 
617             @Test
618             void shouldThrowIllegalArgumentExceptionWithNullTypes() {
619                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isAssignableFrom(null, null));
620                 assertEquals("Cannot assign a null type to a null type", ex.getMessage());
621             }
622         }
623     }
624 
625     @Nested
626     final class IsInstanceOf {
627 
628         @Nested
629         final class WithMessage {
630 
631             @Test
632             void shouldNotThrowExceptionWhenValueIsInstanceOfClass() {
633                 Validate.isInstanceOf(String.class, "hi", "MSG");
634             }
635 
636             @Test
637             void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsNotInstanceOfClass() {
638                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isInstanceOf(List.class, "hi", "MSG"));
639                 assertEquals("MSG", ex.getMessage());
640             }
641         }
642 
643         @Nested
644         final class WithMessageTemplate {
645 
646             @Test
647             void shouldNotThrowExceptionWhenValueIsInstanceOfClass() {
648                 Validate.isInstanceOf(String.class, "hi", "Error %s=%s", "Name", "Value");
649             }
650 
651             @Test
652             void shouldThrowIllegalArgumentExceptionWithGivenMessageWhenValueIsNotInstanceOfClass() {
653                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
654                     () -> Validate.isInstanceOf(List.class, "hi", "Error %s=%s", "Name", "Value"));
655                 assertEquals("Error Name=Value", ex.getMessage());
656             }
657         }
658 
659         @Nested
660         final class WithoutMessage {
661 
662             @Test
663             void shouldNotThrowExceptionWhenValueIsInstanceOfClass() {
664                 Validate.isInstanceOf(String.class, "hi");
665             }
666 
667             @Test
668             void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenValueIsNotInstanceOfClass() {
669                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isInstanceOf(List.class, "hi"));
670                 assertEquals("Expected type: java.util.List, actual: java.lang.String", ex.getMessage());
671             }
672         }
673     }
674 
675     @Nested
676     final class IsTrue {
677 
678         @Nested
679         final class WithDoubleTemplate {
680 
681             @Test
682             void shouldNotThrowForTrueExpression() {
683                 Validate.isTrue(true, "MSG", 7.4d);
684             }
685 
686             @Test
687             void shouldThrowExceptionWithDoubleInsertedIntoTemplateMessageForFalseExpression() {
688                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isTrue(false, "MSG %s", 7.4d));
689                 assertEquals("MSG 7.4", ex.getMessage());
690             }
691         }
692 
693         @Nested
694         final class WithLongTemplate {
695 
696             @Test
697             void shouldNotThrowForTrueExpression() {
698                 Validate.isTrue(true, "MSG", 6);
699             }
700 
701             @Test
702             void shouldThrowExceptionWithLongInsertedIntoTemplateMessageForFalseExpression() {
703                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isTrue(false, "MSG %s", 6));
704                 assertEquals("MSG 6", ex.getMessage());
705             }
706         }
707 
708         @Nested
709         final class WithMessage {
710 
711             @Test
712             void shouldNotThrowForTrueExpression() {
713                 Validate.isTrue(true, "MSG");
714             }
715 
716             @Test
717             void shouldThrowExceptionWithGivenMessageContainingSpecialCharacterForFalseExpression() {
718                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isTrue(false, "%"));
719                 assertEquals("%", ex.getMessage());
720             }
721 
722             @Test
723             void shouldThrowExceptionWithGivenMessageForFalseExpression() {
724                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isTrue(false, "MSG"));
725                 assertEquals("MSG", ex.getMessage());
726             }
727         }
728 
729         @Nested
730         final class WithObjectTemplate {
731 
732             @Test
733             void shouldNotThrowForTrueExpression() {
734                 Validate.isTrue(true, "MSG", "Object 1", "Object 2");
735             }
736 
737             @Test
738             void shouldThrowExceptionWithDoubleInsertedIntoTemplateMessageForFalseExpression() {
739                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
740                     () -> Validate.isTrue(false, "MSG %s %s", "Object 1", "Object 2"));
741                 assertEquals("MSG Object 1 Object 2", ex.getMessage());
742             }
743         }
744 
745         @Nested
746         final class WithoutMessage {
747 
748             @Test
749             void shouldNotThrowForTrueExpression() {
750                 Validate.isTrue(true);
751             }
752 
753             @Test
754             void shouldThrowExceptionWithDefaultMessageForFalseExpression() {
755                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.isTrue(false));
756                 assertEquals("The validated expression is false", ex.getMessage());
757             }
758 
759         }
760     }
761 
762     @Nested
763     final class MatchesPattern {
764 
765         @Nested
766         final class WithMessage {
767 
768             @Test
769             void shouldNotThrowExceptionWhenStringMatchesPattern() {
770                 Validate.matchesPattern("hi", "[a-z]*", "MSG");
771             }
772 
773             @Test
774             void shouldThrowIllegalArgumentExceptionWhenStringDoesNotMatchPattern() {
775                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.matchesPattern("hi", "[0-9]*", "MSG"));
776                 assertEquals("MSG", ex.getMessage());
777             }
778         }
779 
780         @Nested
781         final class WithoutMessage {
782 
783             @Test
784             void shouldNotThrowExceptionWhenStringMatchesPattern() {
785                 Validate.matchesPattern("hi", "[a-z]*");
786             }
787 
788             @Test
789             void shouldThrowIllegalArgumentExceptionWithDefaultMessageWhenStringDoesNotMatchPattern() {
790                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.matchesPattern("hi", "[0-9]*"));
791                 assertEquals("The string hi does not match the pattern [0-9]*", ex.getMessage());
792             }
793         }
794     }
795 
796     @Nested
797     final class NoNullElements {
798 
799         @Nested
800         final class WithArray {
801 
802             @Nested
803             final class WithMessage {
804 
805                 @Test
806                 void shouldNotThrowExceptionForNonEmptyArray() {
807                     Validate.noNullElements(new String[] {"a", "b"}, "MSG");
808                 }
809 
810                 @Test
811                 void shouldReturnSameInstance() {
812                     final String[] array = {"a", "b"};
813                     assertSame(array, Validate.noNullElements(array, "MSG"));
814                 }
815 
816                 @Test
817                 void shouldThrowIllegalArgumentExceptionWithGivenMessageForArrayWithNullElement() {
818                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
819                         () -> Validate.noNullElements(new String[] {"a", null}, "MSG"));
820                     assertEquals("MSG", ex.getMessage());
821                 }
822 
823                 @Test
824                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullArray() {
825                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.noNullElements((Object[]) null, "MSG"));
826                     assertEquals("array", ex.getMessage());
827                 }
828             }
829 
830             @Nested
831             final class WithoutMessage {
832 
833                 @Test
834                 void shouldNotThrowExceptionForNonEmptyArray() {
835                     Validate.noNullElements(new String[] {"a", "b"});
836                 }
837 
838                 @Test
839                 void shouldReturnSameInstance() {
840                     final String[] expected = new String[] {"a", "b"};
841                     assertSame(expected, Validate.noNullElements(expected));
842                 }
843 
844                 @Test
845                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForArrayWithNullElement() {
846                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.noNullElements(new String[] {"a", null}));
847                     assertEquals("The validated array contains null element at index: 1", ex.getMessage());
848                 }
849 
850                 @Test
851                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullArray() {
852                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.noNullElements((Object[]) null));
853                     assertEquals("array", ex.getMessage());
854                 }
855             }
856         }
857 
858         @Nested
859         final class WithCollection {
860 
861             @Nested
862             final class WithMessage {
863 
864                 @Test
865                 void shouldNotThrowExceptionForNonEmptyCollection() {
866                     Validate.noNullElements(Collections.singleton("a"), "MSG");
867                 }
868 
869                 @Test
870                 void shouldReturnSameInstance() {
871                     final Set<String> col = Collections.singleton("a");
872                     assertSame(col, Validate.noNullElements(col, "MSG"));
873                 }
874 
875                 @Test
876                 void shouldThrowIllegalArgumentExceptionWithGivenMessageForCollectionWithNullElement() {
877                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
878                         () -> Validate.noNullElements(Collections.singleton(null), "MSG"));
879                     assertEquals("MSG", ex.getMessage());
880                 }
881 
882                 @Test
883                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullCollection() {
884                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.noNullElements((Collection<?>) null, "MSG"));
885                     assertEquals("iterable", ex.getMessage());
886                 }
887             }
888 
889             @Nested
890             final class WithoutMessage {
891 
892                 @Test
893                 void shouldNotThrowExceptionForNonEmptyCollection() {
894                     Validate.noNullElements(Collections.singleton("a"));
895                 }
896 
897                 @Test
898                 void shouldReturnSameInstance() {
899                     final Set<String> col = Collections.singleton("a");
900                     assertSame(col, Validate.noNullElements(col));
901                 }
902 
903                 @Test
904                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForCollectionWithNullElement() {
905                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
906                         () -> Validate.noNullElements(Collections.singleton(null)));
907                     assertEquals("The validated collection contains null element at index: 0", ex.getMessage());
908                 }
909 
910                 @Test
911                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullCollection() {
912                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.noNullElements((Collection<?>) null));
913                     assertEquals("iterable", ex.getMessage());
914                 }
915             }
916         }
917     }
918 
919     @Nested
920     final class NotBlank {
921 
922         @Nested
923         final class WithMessage {
924 
925             @Test
926             void shouldNotThrowExceptionForNonEmptyString() {
927                 Validate.notBlank("abc", "MSG");
928             }
929 
930             @Test
931             void shouldNotThrowExceptionForNonEmptyStringContainingSpaces() {
932                 Validate.notBlank("  abc   ", "MSG");
933             }
934 
935             @Test
936             void shouldNotThrowExceptionForNonEmptyStringContainingWhitespaceChars() {
937                 Validate.notBlank(" \n \t abc \r \n ", "MSG");
938             }
939 
940             @Test
941             void shouldReturnNonBlankValue() {
942                 assertSame("abc", Validate.notBlank("abc", "MSG"));
943             }
944 
945             @Test
946             void shouldThrowIllegalArgumentExceptionWithGivenMessageForBlankString() {
947                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank("   ", "MSG"));
948                 assertEquals("MSG", ex.getMessage());
949             }
950 
951             @Test
952             void shouldThrowIllegalArgumentExceptionWithGivenMessageForEmptyString() {
953                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank("", "MSG"));
954                 assertEquals("MSG", ex.getMessage());
955             }
956 
957             @Test
958             void shouldThrowIllegalArgumentExceptionWithGivenMessageForStringContainingOnlyWhitespaceChars() {
959                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank(" \n \t \r \n ", "MSG"));
960                 assertEquals("MSG", ex.getMessage());
961             }
962 
963             @Test
964             void shouldThrowNullPointerExceptionWithGivenMessageForNullString() {
965                 final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notBlank(null, "MSG"));
966                 assertEquals("MSG", ex.getMessage());
967             }
968         }
969 
970         @Nested
971         final class WithoutMessage {
972 
973             @Test
974             void shouldNotThrowExceptionForNonEmptyString() {
975                 Validate.notBlank("abc");
976             }
977 
978             @Test
979             void shouldNotThrowExceptionForNonEmptyStringContainingSpaces() {
980                 Validate.notBlank("  abc   ");
981             }
982 
983             @Test
984             void shouldNotThrowExceptionForNonEmptyStringContainingWhitespaceChars() {
985                 Validate.notBlank(" \n \t abc \r \n ");
986             }
987 
988             @Test
989             void shouldReturnNonBlankValue() {
990                 assertSame("abc", Validate.notBlank("abc"));
991             }
992 
993             @Test
994             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForBlankString() {
995                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank("   "));
996                 assertEquals("The validated character sequence is blank", ex.getMessage());
997             }
998 
999             @Test
1000             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyString() {
1001                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank(""));
1002                 assertEquals("The validated character sequence is blank", ex.getMessage());
1003             }
1004 
1005             @Test
1006             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForStringContainingOnlyWhitespaceChars() {
1007                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notBlank(" \n \t \r \n "));
1008                 assertEquals("The validated character sequence is blank", ex.getMessage());
1009             }
1010 
1011             @Test
1012             void shouldThrowNullPointerExceptionWithDefaultMessageForNullString() {
1013                 final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notBlank(null));
1014                 assertEquals("The validated character sequence is blank", ex.getMessage());
1015             }
1016         }
1017     }
1018 
1019     @Nested
1020     final class NotEmpty {
1021 
1022         @Nested
1023         final class WithArray {
1024 
1025             @Nested
1026             final class WithMessage {
1027 
1028                 @Test
1029                 void shouldNotThrowExceptionForArrayContainingNullReference() {
1030                     Validate.notEmpty(new Object[] {null}, "MSG");
1031                 }
1032 
1033                 @Test
1034                 void shouldReturnTheSameInstance() {
1035                     final String[] expected = new String[] {"hi"};
1036                     assertSame(expected, Validate.notEmpty(expected, "MSG"));
1037                 }
1038 
1039                 @Test
1040                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyArray() {
1041                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(new Object[0], "MSG"));
1042                     assertEquals("MSG", ex.getMessage());
1043                 }
1044 
1045                 @Test
1046                 void shouldThrowNullPointerExceptionWithGivenMessageForNullArray() {
1047                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Object[]) null, "MSG"));
1048                     assertEquals("MSG", ex.getMessage());
1049                 }
1050             }
1051 
1052             @Nested
1053             final class WithoutMessage {
1054 
1055                 @Test
1056                 void shouldNotThrowExceptionForArrayContainingNullReference() {
1057                     Validate.notEmpty(new Object[] {null});
1058                 }
1059 
1060                 @Test
1061                 void shouldReturnTheSameInstance() {
1062                     final String[] expected = new String[] {"hi"};
1063                     assertSame(expected, Validate.notEmpty(expected));
1064                 }
1065 
1066                 @Test
1067                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyArray() {
1068                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(new Object[0]));
1069                     assertEquals("The validated array is empty", ex.getMessage());
1070                 }
1071 
1072                 @Test
1073                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullArray() {
1074                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Object[]) null));
1075                     assertEquals("The validated array is empty", ex.getMessage());
1076                 }
1077             }
1078         }
1079 
1080         @Nested
1081         final class WithCharSequence {
1082 
1083             @Nested
1084             final class WithMessage {
1085 
1086                 @Test
1087                 void shouldNotThrowExceptionForNonEmptyString() {
1088                     Validate.notEmpty("Hi", "MSG");
1089                 }
1090 
1091                 @Test
1092                 void shouldReturnTheSameInstance() {
1093                     assertSame("Hi", Validate.notEmpty("Hi", "MSG"));
1094                 }
1095 
1096                 @Test
1097                 void shouldThrowIllegalArgumentExceptionWithGivenMessageForEmptyString() {
1098                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty("", "MSG"));
1099                     assertEquals("MSG", ex.getMessage());
1100                 }
1101 
1102                 @Test
1103                 void shouldThrowNullPointerExceptionWithGivenMessageForNullCharSequence() {
1104                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((CharSequence) null, "MSG"));
1105                     assertEquals("MSG", ex.getMessage());
1106                 }
1107             }
1108 
1109             @Nested
1110             final class WithoutMessage {
1111 
1112                 @Test
1113                 void shouldNotThrowExceptionForNonEmptyString() {
1114                     Validate.notEmpty("Hi");
1115                 }
1116 
1117                 @Test
1118                 void shouldReturnTheSameInstance() {
1119                     assertSame("Hi", Validate.notEmpty("Hi"));
1120                 }
1121 
1122                 @Test
1123                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyString() {
1124                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(""));
1125                     assertEquals("The validated character sequence is empty", ex.getMessage());
1126                 }
1127 
1128                 @Test
1129                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullCharSequence() {
1130                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((CharSequence) null));
1131                     assertEquals("The validated character sequence is empty", ex.getMessage());
1132                 }
1133             }
1134         }
1135 
1136         @Nested
1137         final class WithCollection {
1138 
1139             @Nested
1140             final class WithMessage {
1141 
1142                 @Test
1143                 void shouldNotThrowExceptionForCollectionContainingNullReference() {
1144                     Validate.notEmpty(Collections.singleton(null), "MSG");
1145                 }
1146 
1147                 @Test
1148                 void shouldReturnTheSameInstance() {
1149                     final Set<String> singleton = Collections.singleton("Hi");
1150                     assertSame(singleton, Validate.notEmpty(singleton, "MSG"));
1151                 }
1152 
1153                 @Test
1154                 void shouldThrowIllegalArgumentExceptionWithGivenMessageForEmptyCollection() {
1155                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(Collections.emptySet(), "MSG"));
1156                     assertEquals("MSG", ex.getMessage());
1157                 }
1158 
1159                 @Test
1160                 void shouldThrowNullPointerExceptionWithGivenMessageForNullCollection() {
1161                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Collection<?>) null, "MSG"));
1162                     assertEquals("MSG", ex.getMessage());
1163                 }
1164             }
1165 
1166             @Nested
1167             final class WithoutMessage {
1168 
1169                 @Test
1170                 void shouldNotThrowExceptionForCollectionContainingNullReference() {
1171                     Validate.notEmpty(Collections.singleton(null));
1172                 }
1173 
1174                 @Test
1175                 void shouldReturnTheSameInstance() {
1176                     final Set<String> singleton = Collections.singleton("Hi");
1177                     assertSame(singleton, Validate.notEmpty(singleton));
1178                 }
1179 
1180                 @Test
1181                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyCollection() {
1182                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(Collections.emptySet()));
1183                     assertEquals("The validated collection is empty", ex.getMessage());
1184                 }
1185 
1186                 @Test
1187                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullCollection() {
1188                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Collection<?>) null));
1189                     assertEquals("The validated collection is empty", ex.getMessage());
1190                 }
1191             }
1192         }
1193 
1194         @Nested
1195         final class WithMap {
1196 
1197             @Nested
1198             final class WithMessage {
1199 
1200                 @Test
1201                 void shouldNotThrowExceptionForMapContainingNullMapping() {
1202                     Validate.notEmpty(Collections.singletonMap("key", null), "MSG");
1203                 }
1204 
1205                 @Test
1206                 void shouldReturnTheSameInstance() {
1207                     final Map<String, String> singletonMap = Collections.singletonMap("key", "value");
1208                     assertSame(singletonMap, Validate.notEmpty(singletonMap, "MSG"));
1209                 }
1210 
1211                 @Test
1212                 void shouldThrowIllegalArgumentExceptionWithGivenMessageForEmptyMap() {
1213                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(Collections.emptyMap(), "MSG"));
1214                     assertEquals("MSG", ex.getMessage());
1215                 }
1216 
1217                 @Test
1218                 void shouldThrowNullPointerExceptionWithGivenMessageForNullMap() {
1219                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Map<?, ?>) null, "MSG"));
1220                     assertEquals("MSG", ex.getMessage());
1221                 }
1222             }
1223 
1224             @Nested
1225             final class WithoutMessage {
1226 
1227                 @Test
1228                 void shouldNotThrowExceptionForMapContainingNullMapping() {
1229                     Validate.notEmpty(Collections.singletonMap("key", null));
1230                 }
1231 
1232                 @Test
1233                 void shouldReturnTheSameInstance() {
1234                     final Map<String, String> singletonMap = Collections.singletonMap("key", "value");
1235                     assertSame(singletonMap, Validate.notEmpty(singletonMap));
1236                 }
1237 
1238                 @Test
1239                 void shouldThrowIllegalArgumentExceptionWithDefaultMessageForEmptyMap() {
1240                     final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notEmpty(Collections.emptyMap()));
1241                     assertEquals("The validated map is empty", ex.getMessage());
1242                 }
1243 
1244                 @Test
1245                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullMap() {
1246                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notEmpty((Map<?, ?>) null));
1247                     assertEquals("The validated map is empty", ex.getMessage());
1248                 }
1249             }
1250         }
1251     }
1252 
1253     @Nested
1254     final class NotNaN {
1255 
1256         @Nested
1257         final class WithMessage {
1258 
1259             @Test
1260             void shouldNotThrowExceptionForNegativeInfinity() {
1261                 Validate.notNaN(Double.NEGATIVE_INFINITY, "MSG");
1262             }
1263 
1264             @Test
1265             void shouldNotThrowExceptionForNumber() {
1266                 Validate.notNaN(0.0, "MSG");
1267             }
1268 
1269             @Test
1270             void shouldNotThrowExceptionForPositiveInfinity() {
1271                 Validate.notNaN(Double.POSITIVE_INFINITY, "MSG");
1272             }
1273 
1274             @Test
1275             void shouldThrowIllegalArgumentExceptionWithGivenMessageForNaN() {
1276                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notNaN(Double.NaN, "MSG"));
1277                 assertEquals("MSG", ex.getMessage());
1278             }
1279         }
1280 
1281         @Nested
1282         final class WithoutMessage {
1283 
1284             @Test
1285             void shouldNotThrowExceptionForNegativeInfinity() {
1286                 Validate.notNaN(Double.NEGATIVE_INFINITY);
1287             }
1288 
1289             @Test
1290             void shouldNotThrowExceptionForNumber() {
1291                 Validate.notNaN(0.0);
1292             }
1293 
1294             @Test
1295             void shouldNotThrowExceptionForPositiveInfinity() {
1296                 Validate.notNaN(Double.POSITIVE_INFINITY);
1297             }
1298 
1299             @Test
1300             void shouldThrowIllegalArgumentExceptionWithDefaultMessageForNaN() {
1301                 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Validate.notNaN(Double.NaN));
1302                 assertEquals("The validated value is not a number", ex.getMessage());
1303             }
1304         }
1305     }
1306 
1307     @Nested
1308     final class NotNull {
1309 
1310         @Nested
1311         final class WithMessage {
1312 
1313             @Test
1314             void shouldNotThrowForNonNullReference() {
1315                 Validate.notNull(new Object(), "MSG");
1316             }
1317 
1318             @Test
1319             void shouldReturnTheSameInstance() {
1320                 assertSame("Hi", Validate.notNull("Hi", "MSG"));
1321             }
1322 
1323             @Test
1324             void shouldThrowExceptionWithGivenMessageForNullReference() {
1325                 final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notNull(null, "MSG"));
1326                 assertEquals("MSG", ex.getMessage());
1327             }
1328         }
1329 
1330         @Nested
1331         final class WithoutMessage {
1332 
1333             @Test
1334             void shouldNotThrowForNonNullReference() {
1335                 Validate.notNull(new Object());
1336             }
1337 
1338             @Test
1339             void shouldReturnTheSameInstance() {
1340                 assertSame("Hi", Validate.notNull("Hi"));
1341             }
1342 
1343             @Test
1344             void shouldThrowExceptionWithDefaultMessageForNullReference() {
1345                 final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.notNull(null));
1346                 assertEquals("The validated object is null", ex.getMessage());
1347             }
1348         }
1349     }
1350 
1351     @Nested
1352     final class UtilClassConventions {
1353 
1354         @Test
1355         void hasOnlyOnePublicConstructor() {
1356             final Constructor<?>[] cons = Validate.class.getDeclaredConstructors();
1357             assertEquals(1, cons.length);
1358         }
1359 
1360         @Test
1361         void instancesCanBeConstrcuted() {
1362             assertNotNull(new Validate());
1363         }
1364 
1365         @Test
1366         void isNonFinalClass() {
1367             assertFalse(Modifier.isFinal(Validate.class.getModifiers()));
1368         }
1369 
1370         @Test
1371         void isPublicClass() {
1372             assertTrue(Modifier.isPublic(Validate.class.getModifiers()));
1373         }
1374     }
1375 
1376     @Nested
1377     final class ValidIndex {
1378 
1379         @Nested
1380         final class WithArray {
1381 
1382             @Nested
1383             final class WithMessage {
1384 
1385                 @Test
1386                 void shouldNotThrowExceptionForValidIndex() {
1387                     Validate.validIndex(new String[] {"a"}, 0, "MSG");
1388                 }
1389 
1390                 @Test
1391                 void shouldReturnSameInstance() {
1392                     final String[] array = {"a"};
1393                     assertSame(array, Validate.validIndex(array, 0, "MSG"));
1394                 }
1395 
1396                 @Test
1397                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForIndexOutOfBounds() {
1398                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex(new String[] {"a"}, 1, "MSG"));
1399                     assertEquals("MSG", ex.getMessage());
1400                 }
1401 
1402                 @Test
1403                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForNegativeIndex() {
1404                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class,
1405                         () -> Validate.validIndex(new String[] {"a"}, -1, "MSG"));
1406                     assertEquals("MSG", ex.getMessage());
1407                 }
1408 
1409                 @Test
1410                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullArray() {
1411                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((Object[]) null, 1, "MSG"));
1412                     assertEquals("array", ex.getMessage());
1413                 }
1414             }
1415 
1416             @Nested
1417             final class WithoutMessage {
1418 
1419                 @Test
1420                 void shouldNotThrowExceptionForValidIndex() {
1421                     Validate.validIndex(new String[] {"a"}, 0);
1422                 }
1423 
1424                 @Test
1425                 void shouldReturnSameInstance() {
1426                     final String[] array = {"a"};
1427                     assertSame(array, Validate.validIndex(array, 0));
1428                 }
1429 
1430                 @Test
1431                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForIndexOutOfBounds() {
1432                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex(new String[] {"a"}, 1));
1433                     assertEquals("The validated array index is invalid: 1", ex.getMessage());
1434                 }
1435 
1436                 @Test
1437                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForNegativeIndex() {
1438                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex(new String[] {"a"}, -1));
1439                     assertEquals("The validated array index is invalid: -1", ex.getMessage());
1440                 }
1441 
1442                 @Test
1443                 void shouldThrowNullPointerExceptionWithDefaultForNullArray() {
1444                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((Object[]) null, 1));
1445                     assertEquals("array", ex.getMessage());
1446                 }
1447             }
1448         }
1449 
1450         @Nested
1451         final class WithCharSequence {
1452 
1453             @Nested
1454             final class WithMessage {
1455 
1456                 @Test
1457                 void shouldNotThrowExceptionForValidIndex() {
1458                     Validate.validIndex("a", 0, "MSG");
1459                 }
1460 
1461                 @Test
1462                 void shouldReturnSameInstance() {
1463                     final String str = "a";
1464                     assertSame(str, Validate.validIndex(str, 0, "MSG"));
1465                 }
1466 
1467                 @Test
1468                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForIndexOutOfBounds() {
1469                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex("a", 1, "MSG"));
1470                     assertEquals("MSG", ex.getMessage());
1471                 }
1472 
1473                 @Test
1474                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForNegativeIndex() {
1475                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex("a", -1, "MSG"));
1476                     assertEquals("MSG", ex.getMessage());
1477                 }
1478 
1479                 @Test
1480                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullStr() {
1481                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((String) null, 1, "MSG"));
1482                     assertEquals("chars", ex.getMessage());
1483                 }
1484             }
1485 
1486             @Nested
1487             final class WithoutMessage {
1488 
1489                 @Test
1490                 void shouldNotThrowExceptionForValidIndex() {
1491                     Validate.validIndex("a", 0);
1492                 }
1493 
1494                 @Test
1495                 void shouldReturnSameInstance() {
1496                     final String str = "a";
1497                     assertSame(str, Validate.validIndex(str, 0));
1498                 }
1499 
1500                 @Test
1501                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForIndexOutOfBounds() {
1502                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex("a", 1));
1503                     assertEquals("The validated character sequence index is invalid: 1", ex.getMessage());
1504                 }
1505 
1506                 @Test
1507                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForNegativeIndex() {
1508                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex("a", -1));
1509                     assertEquals("The validated character sequence index is invalid: -1", ex.getMessage());
1510                 }
1511 
1512                 @Test
1513                 void shouldThrowNullPointerExceptionWithDefaultForNullString() {
1514                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((String) null, 1));
1515                     assertEquals("chars", ex.getMessage());
1516                 }
1517             }
1518         }
1519 
1520         @Nested
1521         final class WithCollection {
1522 
1523             @Nested
1524             final class WithMessage {
1525 
1526                 @Test
1527                 void shouldNotThrowExceptionForValidIndex() {
1528                     Validate.validIndex(Collections.singleton("a"), 0, "MSG");
1529                 }
1530 
1531                 @Test
1532                 void shouldReturnSameInstance() {
1533                     final Set<String> col = Collections.singleton("a");
1534                     assertSame(col, Validate.validIndex(col, 0, "MSG"));
1535                 }
1536 
1537                 @Test
1538                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForIndexOutOfBounds() {
1539                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> Validate.validIndex(Collections.singleton("a"), 1, "MSG"));
1540                     assertEquals("MSG", ex.getMessage());
1541                 }
1542 
1543                 @Test
1544                 void shouldThrowIndexOutOfBoundsExceptionWithGivenMessageForNegativeIndex() {
1545                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class,
1546                         () -> Validate.validIndex(Collections.singleton("a"), -1, "MSG"));
1547                     assertEquals("MSG", ex.getMessage());
1548                 }
1549 
1550                 @Test
1551                 void shouldThrowNullPointerExceptionWithDefaultMessageForNullCollection() {
1552                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((Collection<?>) null, 1, "MSG"));
1553                     assertEquals("collection", ex.getMessage());
1554                 }
1555             }
1556 
1557             @Nested
1558             final class WithoutMessage {
1559 
1560                 @Test
1561                 void shouldNotThrowExceptionForValidIndex() {
1562                     Validate.validIndex(Collections.singleton("a"), 0);
1563                 }
1564 
1565                 @Test
1566                 void shouldReturnSameInstance() {
1567                     final Set<String> col = Collections.singleton("a");
1568                     assertSame(col, Validate.validIndex(col, 0));
1569                 }
1570 
1571                 @Test
1572                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForIndexOutOfBounds() {
1573                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class,
1574                         () -> Validate.validIndex(Collections.singleton("a"), 1));
1575                     assertEquals("The validated collection index is invalid: 1", ex.getMessage());
1576                 }
1577 
1578                 @Test
1579                 void shouldThrowIndexOutOfBoundsExceptionWithDefaultMessageForNegativeIndex() {
1580                     final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class,
1581                         () -> Validate.validIndex(Collections.singleton("a"), -1));
1582                     assertEquals("The validated collection index is invalid: -1", ex.getMessage());
1583                 }
1584 
1585                 @Test
1586                 void shouldThrowNullPointerExceptionWithDefaultForNullCollection() {
1587                     final NullPointerException ex = assertThrows(NullPointerException.class, () -> Validate.validIndex((Collection<?>) null, 1));
1588                     assertEquals("collection", ex.getMessage());
1589                 }
1590             }
1591         }
1592     }
1593 
1594     @Nested
1595     final class ValidState {
1596 
1597         @Nested
1598         final class WithoutMessage {
1599 
1600             @Test
1601             void shouldNotThrowExceptionForTrueExpression() {
1602                 Validate.validState(true);
1603             }
1604 
1605             @Test
1606             void shouldThrowExceptionForTrueExpression() {
1607                 assertThrows(IllegalStateException.class, () -> Validate.validState(false));
1608             }
1609 
1610         }
1611 
1612         @Nested
1613         final class WitMessage {
1614             @Test
1615             void shouldNotThrowExceptionForValidIndex() {
1616                 Validate.validState(true, "The Message");
1617             }
1618 
1619             @Test
1620             void shouldThrowExceptionForTrueExpression() {
1621                 assertThrows(IllegalStateException.class, () -> Validate.validState(false, "The Message"));
1622             }
1623 
1624         }
1625     }
1626 }