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   * https://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.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
22  import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertFalse;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.util.ArrayList;
29  import java.util.Arrays;
30  import java.util.EnumSet;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.concurrent.TimeUnit;
35  import java.util.function.Function;
36  import java.util.function.ToIntFunction;
37  
38  import org.junit.jupiter.api.Assertions;
39  import org.junit.jupiter.api.Test;
40  
41  enum Enum64 {
42      A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22,
43      A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45,
44      A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60, A61, A62, A63
45  }
46  
47  /**
48   */
49  class EnumUtilsTest extends AbstractLangTest {
50  
51      private void assertArrayEquals(final long[] actual, final long... expected) {
52          Assertions.assertArrayEquals(expected, actual);
53      }
54  
55      @Test
56      void testConstructable() {
57          // enforce public constructor
58          new EnumUtils();
59      }
60  
61      @Test
62      void testGenerateBitVector() {
63          assertEquals(0L, EnumUtils.generateBitVector(Traffic.class, EnumSet.noneOf(Traffic.class)));
64          assertEquals(1L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED)));
65          assertEquals(2L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.AMBER)));
66          assertEquals(4L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.GREEN)));
67          assertEquals(3L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER)));
68          assertEquals(5L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED, Traffic.GREEN)));
69          assertEquals(6L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.AMBER, Traffic.GREEN)));
70          assertEquals(7L,
71              EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN)));
72  
73          // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
74          assertEquals(1L << 31, EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A31)));
75          assertEquals(1L << 32, EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A32)));
76          assertEquals(1L << 63, EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A63)));
77          assertEquals(Long.MIN_VALUE, EnumUtils.generateBitVector(Enum64.class, EnumSet.of(Enum64.A63)));
78      }
79  
80      @Test
81      void testGenerateBitVector_longClass() {
82          assertIllegalArgumentException(
83              () -> EnumUtils.generateBitVector(TooMany.class, EnumSet.of(TooMany.A1)));
84      }
85  
86      @Test
87      void testGenerateBitVector_longClassWithArray() {
88          assertIllegalArgumentException(() -> EnumUtils.generateBitVector(TooMany.class, TooMany.A1));
89      }
90  
91      @SuppressWarnings("unchecked")
92      @Test
93      void testGenerateBitVector_nonEnumClass() {
94          @SuppressWarnings("rawtypes")
95          final Class rawType = Object.class;
96          @SuppressWarnings("rawtypes")
97          final List rawList = new ArrayList();
98          assertIllegalArgumentException(() -> EnumUtils.generateBitVector(rawType, rawList));
99      }
100 
101     @SuppressWarnings("unchecked")
102     @Test
103     void testGenerateBitVector_nonEnumClassWithArray() {
104         @SuppressWarnings("rawtypes")
105         final Class rawType = Object.class;
106         assertIllegalArgumentException(() -> EnumUtils.generateBitVector(rawType));
107     }
108 
109     @Test
110     void testGenerateBitVector_nullArray() {
111         assertNullPointerException(() -> EnumUtils.generateBitVector(Traffic.class, (Traffic[]) null));
112     }
113 
114     @Test
115     void testGenerateBitVector_nullArrayElement() {
116         assertIllegalArgumentException(
117             () -> EnumUtils.generateBitVector(Traffic.class, Traffic.RED, null));
118     }
119 
120     @Test
121     void testGenerateBitVector_nullClass() {
122         assertNullPointerException(() -> EnumUtils.generateBitVector(null, EnumSet.of(Traffic.RED)));
123     }
124 
125     @Test
126     void testGenerateBitVector_nullClassWithArray() {
127         assertNullPointerException(() -> EnumUtils.generateBitVector(null, Traffic.RED));
128     }
129 
130     @Test
131     void testGenerateBitVector_nullElement() {
132         assertNullPointerException(
133             () -> EnumUtils.generateBitVector(Traffic.class, Arrays.asList(Traffic.RED, null)));
134     }
135 
136     @Test
137     void testGenerateBitVector_nullIterable() {
138         assertNullPointerException(
139             () -> EnumUtils.generateBitVector(Traffic.class, (Iterable<Traffic>) null));
140     }
141 
142     @Test
143     void testGenerateBitVectorFromArray() {
144         assertEquals(0L, EnumUtils.generateBitVector(Traffic.class));
145         assertEquals(1L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED));
146         assertEquals(2L, EnumUtils.generateBitVector(Traffic.class, Traffic.AMBER));
147         assertEquals(4L, EnumUtils.generateBitVector(Traffic.class, Traffic.GREEN));
148         assertEquals(3L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER));
149         assertEquals(5L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.GREEN));
150         assertEquals(6L, EnumUtils.generateBitVector(Traffic.class, Traffic.AMBER, Traffic.GREEN));
151         assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN));
152         // gracefully handles duplicates:
153         assertEquals(7L,
154             EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN));
155 
156         // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
157         assertEquals(1L << 31, EnumUtils.generateBitVector(Enum64.class, Enum64.A31));
158         assertEquals(1L << 32, EnumUtils.generateBitVector(Enum64.class, Enum64.A32));
159         assertEquals(1L << 63, EnumUtils.generateBitVector(Enum64.class, Enum64.A63));
160         assertEquals(Long.MIN_VALUE, EnumUtils.generateBitVector(Enum64.class, Enum64.A63));
161     }
162 
163     @Test
164     void testGenerateBitVectors() {
165         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.noneOf(Traffic.class)), 0L);
166         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED)), 1L);
167         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.AMBER)), 2L);
168         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.GREEN)), 4L);
169         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER)), 3L);
170         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.GREEN)), 5L);
171         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.AMBER, Traffic.GREEN)), 6L);
172         assertArrayEquals(
173             EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN)), 7L);
174 
175         // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
176         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A31)), 1L << 31);
177         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A32)), 1L << 32);
178         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A63)), 1L << 63);
179         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, EnumSet.of(Enum64.A63)), Long.MIN_VALUE);
180 
181         // More than 64 values Enum
182         assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, EnumSet.of(TooMany.M2)), 1L, 0L);
183         assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, EnumSet.of(TooMany.L2, TooMany.M2)), 1L,
184             1L << 63);
185     }
186 
187     @SuppressWarnings("unchecked")
188     @Test
189     void testGenerateBitVectors_nonEnumClass() {
190         @SuppressWarnings("rawtypes")
191         final Class rawType = Object.class;
192         @SuppressWarnings("rawtypes")
193         final List rawList = new ArrayList();
194         assertIllegalArgumentException(() -> EnumUtils.generateBitVectors(rawType, rawList));
195     }
196 
197     @SuppressWarnings("unchecked")
198     @Test
199     void testGenerateBitVectors_nonEnumClassWithArray() {
200         @SuppressWarnings("rawtypes")
201         final Class rawType = Object.class;
202         assertIllegalArgumentException(() -> EnumUtils.generateBitVectors(rawType));
203     }
204 
205     @Test
206     void testGenerateBitVectors_nullArray() {
207         assertNullPointerException(() -> EnumUtils.generateBitVectors(Traffic.class, (Traffic[]) null));
208     }
209 
210     @Test
211     void testGenerateBitVectors_nullArrayElement() {
212         assertIllegalArgumentException(
213             () -> EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, null));
214     }
215 
216     @Test
217     void testGenerateBitVectors_nullClass() {
218         assertNullPointerException(() -> EnumUtils.generateBitVectors(null, EnumSet.of(Traffic.RED)));
219     }
220 
221     @Test
222     void testGenerateBitVectors_nullClassWithArray() {
223         assertNullPointerException(() -> EnumUtils.generateBitVectors(null, Traffic.RED));
224     }
225 
226     @Test
227     void testGenerateBitVectors_nullElement() {
228         assertNullPointerException(
229             () -> EnumUtils.generateBitVectors(Traffic.class, Arrays.asList(Traffic.RED, null)));
230     }
231 
232     @Test
233     void testGenerateBitVectors_nullIterable() {
234         assertNullPointerException(() -> EnumUtils.generateBitVectors(null, (Iterable<Traffic>) null));
235     }
236 
237     @Test
238     void testGenerateBitVectorsFromArray() {
239         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class), 0L);
240         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED), 1L);
241         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.AMBER), 2L);
242         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.GREEN), 4L);
243         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER), 3L);
244         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.GREEN), 5L);
245         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.AMBER, Traffic.GREEN), 6L);
246         assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN), 7L);
247         // gracefully handles duplicates:
248         assertArrayEquals(
249             EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN), 7L);
250 
251         // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
252         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A31), 1L << 31);
253         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A32), 1L << 32);
254         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A63), 1L << 63);
255         assertArrayEquals(EnumUtils.generateBitVectors(Enum64.class, Enum64.A63), Long.MIN_VALUE);
256 
257         // More than 64 values Enum
258         assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, TooMany.M2), 1L, 0L);
259         assertArrayEquals(EnumUtils.generateBitVectors(TooMany.class, TooMany.L2, TooMany.M2), 1L, 1L << 63);
260 
261     }
262 
263     @Test
264     void testGetEnum() {
265         assertEquals(Traffic.RED, EnumUtils.getEnum(Traffic.class, "RED"));
266         assertEquals(Traffic.AMBER, EnumUtils.getEnum(Traffic.class, "AMBER"));
267         assertEquals(Traffic.GREEN, EnumUtils.getEnum(Traffic.class, "GREEN"));
268         assertNull(EnumUtils.getEnum(Traffic.class, "PURPLE"));
269         assertNull(EnumUtils.getEnum(Traffic.class, null));
270     }
271 
272     @Test
273     void testGetEnum_defaultEnum() {
274         assertEquals(Traffic.RED, EnumUtils.getEnum(Traffic.class, "RED", Traffic.AMBER));
275         assertEquals(Traffic.AMBER, EnumUtils.getEnum(Traffic.class, "AMBER", Traffic.GREEN));
276         assertEquals(Traffic.GREEN, EnumUtils.getEnum(Traffic.class, "GREEN", Traffic.RED));
277         assertEquals(Traffic.AMBER, EnumUtils.getEnum(Traffic.class, "PURPLE", Traffic.AMBER));
278         assertEquals(Traffic.GREEN, EnumUtils.getEnum(Traffic.class, "PURPLE", Traffic.GREEN));
279         assertEquals(Traffic.RED, EnumUtils.getEnum(Traffic.class, "PURPLE", Traffic.RED));
280         assertEquals(Traffic.AMBER, EnumUtils.getEnum(Traffic.class, null, Traffic.AMBER));
281         assertEquals(Traffic.GREEN, EnumUtils.getEnum(Traffic.class, null, Traffic.GREEN));
282         assertEquals(Traffic.RED, EnumUtils.getEnum(Traffic.class, null, Traffic.RED));
283         assertNull(EnumUtils.getEnum(Traffic.class, "PURPLE", null));
284         assertEquals(Traffic.AMBER, EnumUtils.getEnum(null, "RED", Traffic.AMBER));
285     }
286 
287     /**
288      * Tests raw type.
289      */
290     @SuppressWarnings("unchecked")
291     @Test
292     void testGetEnum_nonEnumClass() {
293         @SuppressWarnings("rawtypes")
294         final Class rawType = Object.class;
295         assertNull(EnumUtils.getEnum(rawType, "rawType"));
296     }
297 
298     @Test
299     void testGetEnum_nullClass() {
300         assertNull(EnumUtils.getEnum((Class<Traffic>) null, "PURPLE"));
301     }
302 
303     @Test
304     void testGetEnumIgnoreCase() {
305         assertEquals(Traffic.RED, EnumUtils.getEnumIgnoreCase(Traffic.class, "red"));
306         assertEquals(Traffic.AMBER, EnumUtils.getEnumIgnoreCase(Traffic.class, "Amber"));
307         assertEquals(Traffic.GREEN, EnumUtils.getEnumIgnoreCase(Traffic.class, "grEEn"));
308         assertNull(EnumUtils.getEnumIgnoreCase(Traffic.class, "purple"));
309         assertNull(EnumUtils.getEnumIgnoreCase(Traffic.class, null));
310     }
311 
312     @Test
313     void testGetEnumIgnoreCase_defaultEnum() {
314         assertEquals(Traffic.RED, EnumUtils.getEnumIgnoreCase(Traffic.class, "red", Traffic.AMBER));
315         assertEquals(Traffic.AMBER, EnumUtils.getEnumIgnoreCase(Traffic.class, "Amber", Traffic.GREEN));
316         assertEquals(Traffic.GREEN, EnumUtils.getEnumIgnoreCase(Traffic.class, "grEEn", Traffic.RED));
317         assertEquals(Traffic.AMBER, EnumUtils.getEnumIgnoreCase(Traffic.class, "PURPLE", Traffic.AMBER));
318         assertEquals(Traffic.GREEN, EnumUtils.getEnumIgnoreCase(Traffic.class, "purple", Traffic.GREEN));
319         assertEquals(Traffic.RED, EnumUtils.getEnumIgnoreCase(Traffic.class, "pUrPlE", Traffic.RED));
320         assertEquals(Traffic.AMBER, EnumUtils.getEnumIgnoreCase(Traffic.class, null, Traffic.AMBER));
321         assertEquals(Traffic.GREEN, EnumUtils.getEnumIgnoreCase(Traffic.class, null, Traffic.GREEN));
322         assertEquals(Traffic.RED, EnumUtils.getEnumIgnoreCase(Traffic.class, null, Traffic.RED));
323         assertNull(EnumUtils.getEnumIgnoreCase(Traffic.class, "PURPLE", null));
324         assertNull(EnumUtils.getEnumIgnoreCase(null, "PURPLE", null));
325     }
326 
327     /**
328      * Tests raw type.
329      */
330     @SuppressWarnings("unchecked")
331     @Test
332     void testGetEnumIgnoreCase_nonEnumClass() {
333         @SuppressWarnings("rawtypes")
334         final Class rawType = Object.class;
335         assertNull(EnumUtils.getEnumIgnoreCase(rawType, "rawType"));
336     }
337 
338     @Test
339     void testGetEnumIgnoreCase_nullClass() {
340         assertNull(EnumUtils.getEnumIgnoreCase((Class<Traffic>) null, "PURPLE"));
341     }
342 
343     @Test
344     void testGetEnumList() {
345         final List<Traffic> test = EnumUtils.getEnumList(Traffic.class);
346         assertEquals(3, test.size());
347         assertEquals(Traffic.RED, test.get(0));
348         assertEquals(Traffic.AMBER, test.get(1));
349         assertEquals(Traffic.GREEN, test.get(2));
350     }
351 
352     @Test
353     void testGetEnumMap() {
354         final Map<String, Traffic> test = EnumUtils.getEnumMap(Traffic.class);
355         final Map<String, Traffic> expected = new HashMap<>();
356         expected.put("RED", Traffic.RED);
357         expected.put("AMBER", Traffic.AMBER);
358         expected.put("GREEN", Traffic.GREEN);
359         assertEquals(expected, test, "getEnumMap not created correctly");
360         assertEquals(3, test.size());
361         assertTrue(test.containsKey("RED"));
362         assertEquals(Traffic.RED, test.get("RED"));
363         assertTrue(test.containsKey("AMBER"));
364         assertEquals(Traffic.AMBER, test.get("AMBER"));
365         assertTrue(test.containsKey("GREEN"));
366         assertEquals(Traffic.GREEN, test.get("GREEN"));
367         assertFalse(test.containsKey("PURPLE"));
368     }
369 
370     @Test
371     void testGetEnumMap_keyFunction() {
372         final Map<Integer, Month> test = EnumUtils.getEnumMap(Month.class, Month::getId);
373         final Map<Integer, Month> expected = new HashMap<>();
374         expected.put(1, Month.JAN);
375         expected.put(2, Month.FEB);
376         expected.put(3, Month.MAR);
377         expected.put(4, Month.APR);
378         expected.put(5, Month.MAY);
379         expected.put(6, Month.JUN);
380         expected.put(7, Month.JUL);
381         expected.put(8, Month.AUG);
382         expected.put(9, Month.SEP);
383         expected.put(10, Month.OCT);
384         expected.put(11, Month.NOV);
385         expected.put(12, Month.DEC);
386         assertEquals(expected, test, "getEnumMap not created correctly");
387         assertEquals(12, test.size());
388         assertFalse(test.containsKey(0));
389         assertTrue(test.containsKey(1));
390         assertEquals(Month.JAN, test.get(1));
391         assertTrue(test.containsKey(2));
392         assertEquals(Month.FEB, test.get(2));
393         assertTrue(test.containsKey(3));
394         assertEquals(Month.MAR, test.get(3));
395         assertTrue(test.containsKey(4));
396         assertEquals(Month.APR, test.get(4));
397         assertTrue(test.containsKey(5));
398         assertEquals(Month.MAY, test.get(5));
399         assertTrue(test.containsKey(6));
400         assertEquals(Month.JUN, test.get(6));
401         assertTrue(test.containsKey(7));
402         assertEquals(Month.JUL, test.get(7));
403         assertTrue(test.containsKey(8));
404         assertEquals(Month.AUG, test.get(8));
405         assertTrue(test.containsKey(9));
406         assertEquals(Month.SEP, test.get(9));
407         assertTrue(test.containsKey(10));
408         assertEquals(Month.OCT, test.get(10));
409         assertTrue(test.containsKey(11));
410         assertEquals(Month.NOV, test.get(11));
411         assertTrue(test.containsKey(12));
412         assertEquals(Month.DEC, test.get(12));
413         assertFalse(test.containsKey(13));
414     }
415 
416     @Test
417     void testGetEnumSystemProperty() {
418         final String key = getClass().getName();
419         System.setProperty(key, Traffic.RED.toString());
420         try {
421             assertEquals(Traffic.RED, EnumUtils.getEnumSystemProperty(Traffic.class, key, null));
422             assertEquals(Traffic.RED, EnumUtils.getEnumSystemProperty(Traffic.class, "?", Traffic.RED));
423             assertEquals(Traffic.RED, EnumUtils.getEnumSystemProperty(null, null, Traffic.RED));
424             assertEquals(Traffic.RED, EnumUtils.getEnumSystemProperty(null, "?", Traffic.RED));
425             assertEquals(Traffic.RED, EnumUtils.getEnumSystemProperty(Traffic.class, null, Traffic.RED));
426         } finally {
427             System.getProperties().remove(key);
428         }
429     }
430 
431     @Test
432     void testGetFirstEnumIgnoreCase_defaultEnum() {
433         final Function<Traffic2, String> f = Traffic2::getLabel;
434         assertEquals(Traffic2.RED, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "***red***", f, Traffic2.AMBER));
435         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "**Amber**", f, Traffic2.GREEN));
436         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "*grEEn*", f, Traffic2.RED));
437         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "PURPLE", f, Traffic2.AMBER));
438         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "purple", f, Traffic2.GREEN));
439         assertEquals(Traffic2.RED, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "pUrPlE", f, Traffic2.RED));
440         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, null, f, Traffic2.AMBER));
441         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, null, f, Traffic2.GREEN));
442         assertEquals(Traffic2.RED, EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, null, f, Traffic2.RED));
443         assertNull(EnumUtils.getFirstEnumIgnoreCase(Traffic2.class, "PURPLE", f, null));
444         assertNull(EnumUtils.getFirstEnumIgnoreCase(null, "PURPLE", f, null));
445     }
446 
447     @Test
448     void testGetFirstEnumToIntFunction() {
449         final ToIntFunction<Traffic2> f = Traffic2::getValue;
450         assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 1, f, Traffic2.AMBER));
451         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 2, f, Traffic2.GREEN));
452         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class, 3, f, Traffic2.RED));
453         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 4, f, Traffic2.AMBER));
454         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class, 5, f, Traffic2.GREEN));
455         assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 6, f, Traffic2.RED));
456         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(Traffic2.class, 0, f, Traffic2.AMBER));
457         assertEquals(Traffic2.GREEN, EnumUtils.getFirstEnum(Traffic2.class, -1, f, Traffic2.GREEN));
458         assertEquals(Traffic2.RED, EnumUtils.getFirstEnum(Traffic2.class, 0, f, Traffic2.RED));
459         assertNull(EnumUtils.getFirstEnum(Traffic2.class, 7, f, null));
460         // Edge cases for 1st argument
461         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum(null, 1, f, Traffic2.AMBER));
462         assertEquals(Traffic2.AMBER, EnumUtils.getFirstEnum((Class) String.class, 1, f, Traffic2.AMBER));
463     }
464 
465     @Test
466     void testIsValidEnum() {
467         assertTrue(EnumUtils.isValidEnum(Traffic.class, "RED"));
468         assertTrue(EnumUtils.isValidEnum(Traffic.class, "AMBER"));
469         assertTrue(EnumUtils.isValidEnum(Traffic.class, "GREEN"));
470         assertFalse(EnumUtils.isValidEnum(Traffic.class, "PURPLE"));
471         assertFalse(EnumUtils.isValidEnum(Traffic.class, null));
472     }
473 
474     @Test
475     void testIsValidEnum_nullClass() {
476         assertFalse(EnumUtils.isValidEnum(null, "PURPLE"));
477     }
478 
479     @Test
480     void testIsValidEnumIgnoreCase() {
481         assertTrue(EnumUtils.isValidEnumIgnoreCase(Traffic.class, "red"));
482         assertTrue(EnumUtils.isValidEnumIgnoreCase(Traffic.class, "Amber"));
483         assertTrue(EnumUtils.isValidEnumIgnoreCase(Traffic.class, "grEEn"));
484         assertFalse(EnumUtils.isValidEnumIgnoreCase(Traffic.class, "purple"));
485         assertFalse(EnumUtils.isValidEnumIgnoreCase(Traffic.class, null));
486     }
487 
488     @Test
489     void testIsValidEnumIgnoreCase_nullClass() {
490         assertFalse(EnumUtils.isValidEnumIgnoreCase(null, "PURPLE"));
491     }
492 
493     @Test
494     void testProcessBitVector() {
495         assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVector(Traffic.class, 0L));
496         assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVector(Traffic.class, 1L));
497         assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVector(Traffic.class, 2L));
498         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVector(Traffic.class, 3L));
499         assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 4L));
500         assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 5L));
501         assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 6L));
502         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN),
503             EnumUtils.processBitVector(Traffic.class, 7L));
504 
505         // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
506         assertEquals(EnumSet.of(Enum64.A31), EnumUtils.processBitVector(Enum64.class, 1L << 31));
507         assertEquals(EnumSet.of(Enum64.A32), EnumUtils.processBitVector(Enum64.class, 1L << 32));
508         assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVector(Enum64.class, 1L << 63));
509         assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVector(Enum64.class, Long.MIN_VALUE));
510     }
511 
512     @Test
513     void testProcessBitVector_longClass() {
514         assertIllegalArgumentException(() -> EnumUtils.processBitVector(TooMany.class, 0L));
515     }
516 
517     @Test
518     void testProcessBitVector_nullClass() {
519         final Class<Traffic> empty = null;
520         assertNullPointerException(() -> EnumUtils.processBitVector(empty, 0L));
521     }
522 
523     @Test
524     void testProcessBitVectors() {
525         assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 0L));
526         assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 1L));
527         assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 2L));
528         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 3L));
529         assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 4L));
530         assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 5L));
531         assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 6L));
532         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN),
533             EnumUtils.processBitVectors(Traffic.class, 7L));
534 
535         assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 0L, 0L));
536         assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 0L, 1L));
537         assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 0L, 2L));
538         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 0L, 3L));
539         assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 4L));
540         assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 5L));
541         assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 6L));
542         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN),
543             EnumUtils.processBitVectors(Traffic.class, 0L, 7L));
544 
545         // demonstrate tolerance of irrelevant high-order digits:
546         assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 666L, 0L));
547         assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 666L, 1L));
548         assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 666L, 2L));
549         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 666L, 3L));
550         assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 4L));
551         assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 5L));
552         assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 6L));
553         assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN),
554             EnumUtils.processBitVectors(Traffic.class, 666L, 7L));
555 
556         // 64 values Enum (to test whether no int<->long jdk conversion issue exists)
557         assertEquals(EnumSet.of(Enum64.A31), EnumUtils.processBitVectors(Enum64.class, 1L << 31));
558         assertEquals(EnumSet.of(Enum64.A32), EnumUtils.processBitVectors(Enum64.class, 1L << 32));
559         assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVectors(Enum64.class, 1L << 63));
560         assertEquals(EnumSet.of(Enum64.A63), EnumUtils.processBitVectors(Enum64.class, Long.MIN_VALUE));
561     }
562 
563     @Test
564     void testProcessBitVectors_longClass() {
565         assertEquals(EnumSet.noneOf(TooMany.class), EnumUtils.processBitVectors(TooMany.class, 0L));
566         assertEquals(EnumSet.of(TooMany.A), EnumUtils.processBitVectors(TooMany.class, 1L));
567         assertEquals(EnumSet.of(TooMany.B), EnumUtils.processBitVectors(TooMany.class, 2L));
568         assertEquals(EnumSet.of(TooMany.A, TooMany.B), EnumUtils.processBitVectors(TooMany.class, 3L));
569         assertEquals(EnumSet.of(TooMany.C), EnumUtils.processBitVectors(TooMany.class, 4L));
570         assertEquals(EnumSet.of(TooMany.A, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 5L));
571         assertEquals(EnumSet.of(TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 6L));
572         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 7L));
573 
574         assertEquals(EnumSet.noneOf(TooMany.class), EnumUtils.processBitVectors(TooMany.class, 0L, 0L));
575         assertEquals(EnumSet.of(TooMany.A), EnumUtils.processBitVectors(TooMany.class, 0L, 1L));
576         assertEquals(EnumSet.of(TooMany.B), EnumUtils.processBitVectors(TooMany.class, 0L, 2L));
577         assertEquals(EnumSet.of(TooMany.A, TooMany.B), EnumUtils.processBitVectors(TooMany.class, 0L, 3L));
578         assertEquals(EnumSet.of(TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 4L));
579         assertEquals(EnumSet.of(TooMany.A, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 5L));
580         assertEquals(EnumSet.of(TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 6L));
581         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 7L));
582         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 7L));
583 
584         assertEquals(EnumSet.of(TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 0L));
585         assertEquals(EnumSet.of(TooMany.A, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 1L));
586         assertEquals(EnumSet.of(TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 2L));
587         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 3L));
588         assertEquals(EnumSet.of(TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 4L));
589         assertEquals(EnumSet.of(TooMany.A, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 5L));
590         assertEquals(EnumSet.of(TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 6L));
591         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2),
592             EnumUtils.processBitVectors(TooMany.class, 1L, 7L));
593         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2),
594             EnumUtils.processBitVectors(TooMany.class, 1L, 7L));
595 
596         // demonstrate tolerance of irrelevant high-order digits:
597         assertEquals(EnumSet.of(TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 0L));
598         assertEquals(EnumSet.of(TooMany.A, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 1L));
599         assertEquals(EnumSet.of(TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 2L));
600         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 3L));
601         assertEquals(EnumSet.of(TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 4L));
602         assertEquals(EnumSet.of(TooMany.A, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 5L));
603         assertEquals(EnumSet.of(TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 6L));
604         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2),
605             EnumUtils.processBitVectors(TooMany.class, 9L, 7L));
606         assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2),
607             EnumUtils.processBitVectors(TooMany.class, 9L, 7L));
608     }
609 
610     @Test
611     void testProcessBitVectors_nullClass() {
612         final Class<Traffic> empty = null;
613         assertNullPointerException(() -> EnumUtils.processBitVectors(empty, 0L));
614     }
615 
616     @Test
617     void testStream() {
618         assertEquals(7, EnumUtils.stream(TimeUnit.class).count());
619         Assertions.assertArrayEquals(TimeUnit.values(), EnumUtils.stream(TimeUnit.class).toArray(TimeUnit[]::new));
620         assertEquals(0, EnumUtils.stream(Object.class).count());
621         assertEquals(0, EnumUtils.stream(null).count());
622     }
623 
624 }
625 
626 enum Month {
627     JAN(1), FEB(2), MAR(3), APR(4), MAY(5), JUN(6), JUL(7), AUG(8), SEP(9), OCT(10), NOV(11), DEC(12);
628 
629     private final int id;
630 
631     Month(final int id) {
632         this.id = id;
633     }
634 
635     public int getId() {
636         return this.id;
637     }
638 }
639 
640 enum TooMany {
641     A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, A1, B1, C1, D1, E1, F1, G1, H1, I1,
642     J1, K1, L1, M1, N1, O1, P1, Q1, R1, S1, T1, U1, V1, W1, X1, Y1, Z1, A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, L2,
643     M2
644 }
645 
646 enum Traffic {
647     RED, AMBER, GREEN
648 }
649 
650 enum Traffic2 {
651 
652     RED("***Red***", 1), AMBER("**Amber**", 2), GREEN("*green*", 3);
653 
654     final String label;
655     final int value;
656 
657     Traffic2(final String label, final int value) {
658         this.label = label;
659         this.value = value;
660     }
661 
662     public String getLabel() {
663         return label;
664     }
665 
666     public int getValue() {
667         return value;
668     }
669 }