1/*
2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug     4904140
27 * @summary Unit test for EnumMap
28 * @author  Josh Bloch
29 * @author  Yo Yo Ma
30 */
31
32import java.util.*;
33import java.io.*;
34
35public class EnumMapBash {
36    static Random rnd = new Random();
37
38    public static void main(String[] args) {
39        bash(Silly31.class);
40        bash(Silly32.class);
41        bash(Silly33.class);
42        bash(Silly63.class);
43        bash(Silly64.class);
44        bash(Silly65.class);
45        bash(Silly127.class);
46        bash(Silly128.class);
47        bash(Silly129.class);
48        bash(Silly500.class);
49    }
50
51    static <T extends Enum<T>> void bash(Class<T> enumClass) {
52        Enum[] universe = enumClass.getEnumConstants();
53
54        int numItr = 100;
55
56        // Linked List test
57        for (int i=0; i<numItr; i++) {
58            int mapSize = universe.length * 7 / 8;
59
60            // Build the linked list
61            Map<T, T> m = new EnumMap<T, T>(enumClass);
62            if (!m.isEmpty())
63                fail("New instance non empty.");
64            Enum[] perm = (Enum[]) universe.clone();
65            Collections.shuffle(Arrays.asList(perm));
66            T head = (T) perm[0];
67            for (int j = 0; j < mapSize; j++)
68                m.put((T)perm[j], (T)perm[j + 1]);
69            T nil = (T)perm[mapSize];
70
71            if (m.size() != mapSize)
72                fail("Size not as expected.");
73
74            Map<T, T> tm = new TreeMap<T, T>(m);
75
76            if (m.hashCode() != tm.hashCode())
77                fail("Incorrect hashCode computation.");
78            if (!m.toString().equals(tm.toString()))
79                fail("Incorrect toString computation.");
80            if (!tm.equals(m))
81                fail("Incorrect equals (1).");
82            if (!m.equals(tm))
83                fail("Incorrect equals (2).");
84
85            Map<T, T> m2 = new EnumMap<T, T>(enumClass); m2.putAll(m);
86            m2.values().removeAll(m.keySet());
87            if (m2.size()!= 1 || !m2.containsValue(nil))
88                fail("Collection views test failed.");
89
90            int j=0;
91            while (head != nil) {
92                if (!m.containsKey(head))
93                    fail("Linked list doesn't contain a link.");
94                T newHead = m.get(head);
95                if (newHead == null)
96                    fail("Could not retrieve a link.");
97                m.remove(head);
98                head = newHead;
99                j++;
100            }
101            if (!m.isEmpty())
102                fail("Map nonempty after removing all links.");
103            if (j != mapSize)
104                fail("Linked list size not as expected.");
105        }
106
107        EnumMap<T, T> m = new EnumMap<T, T>(enumClass);
108        int mapSize = 0;
109        for (int i=0; i<universe.length; i += 2) {
110            if (m.put((T)universe[i], (T)universe[i]) != null)
111                fail("put returns a non-null value erroenously.");
112            mapSize++;
113        }
114        for (int i=0; i<universe.length; i++)
115            if (m.containsValue(universe[i]) != (i%2==0))
116                fail("contains value "+i);
117        if (m.put((T)universe[0], (T)universe[0]) == null)
118            fail("put returns a null value erroenously.");
119
120        Map<T, T>  m2 = m.clone();
121        cloneTest(m, m2);
122
123        m2 = new EnumMap<T,T>(enumClass);
124        m2.putAll(m);
125        cloneTest(m, m2);
126
127        m2 = new EnumMap<T, T>(m);
128        cloneTest(m, m2);
129
130        m2 = new EnumMap<T, T>((Map<T, T>) m);
131        cloneTest(m, m2);
132        if (!m.isEmpty()) {
133            m2 = new EnumMap<T, T>(new HashMap<T, T>(m));
134            cloneTest(m, m2);
135        }
136
137        m2 = deepCopy(m);
138        cloneTest(m, m2);
139
140        if (!m.equals(m2))
141            fail("Clone not equal to original. (1)");
142        if (!m2.equals(m))
143            fail("Clone not equal to original. (2)");
144
145        Set<Map.Entry<T,T>> s = m.entrySet(), s2 = m2.entrySet();
146
147        if (!s.equals(s2))
148            fail("Clone not equal to original. (3)");
149        if (!s2.equals(s))
150            fail("Clone not equal to original. (4)");
151        if (!s.containsAll(s2))
152            fail("Original doesn't contain clone!");
153        if (!s2.containsAll(s))
154            fail("Clone doesn't contain original!");
155
156        s2.removeAll(s);
157        if (!m2.isEmpty()) {
158            System.out.println(m2.size());
159            System.out.println(m2);
160            fail("entrySet().removeAll failed.");
161        }
162
163        m2.putAll(m);
164        m2.clear();
165        if (!m2.isEmpty())
166            fail("clear failed.");
167
168        Iterator i = m.entrySet().iterator();
169        while(i.hasNext()) {
170            i.next();
171            i.remove();
172        }
173        if (!m.isEmpty())
174            fail("Iterator.remove() failed");
175    }
176
177    // Done inefficiently so as to exercise various functions
178    static <K, V> void cloneTest(Map<K, V> m, Map<K, V> clone) {
179        if (!m.equals(clone))
180            fail("Map not equal to copy.");
181        if (!clone.equals(m))
182            fail("Copy not equal to map.");
183        if (!m.entrySet().containsAll(clone.entrySet()))
184            fail("Set does not contain copy.");
185        if (!clone.entrySet().containsAll(m.entrySet()))
186            fail("Copy does not contain set.");
187        if (!m.entrySet().equals(clone.entrySet()))
188            fail("Set not equal clone set");
189        if (!clone.entrySet().equals(m.entrySet()))
190            fail("Clone set not equal set");
191    }
192
193    // Utility method to do a deep copy of an object *very slowly* using
194    // serialization/deserialization
195    static <T> T deepCopy(T oldObj) {
196        try {
197            ByteArrayOutputStream bos = new ByteArrayOutputStream();
198            ObjectOutputStream oos = new ObjectOutputStream(bos);
199            oos.writeObject(oldObj);
200            oos.flush();
201            ByteArrayInputStream bin = new ByteArrayInputStream(
202                bos.toByteArray());
203            ObjectInputStream ois = new ObjectInputStream(bin);
204            return (T) ois.readObject();
205        } catch(Exception e) {
206            throw new IllegalArgumentException(e.toString());
207        }
208    }
209
210    static void fail(String s) {
211        throw new RuntimeException(s);
212    }
213
214    public enum Silly31 {
215        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
216        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30
217    }
218
219    public enum Silly32 {
220        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
221        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31
222    }
223
224    public enum Silly33 {
225        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
226        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
227        e32
228    }
229
230    public enum Silly63 {
231        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
232        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
233        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
234        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
235        e62
236    }
237
238    public enum Silly64 {
239        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
240        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
241        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
242        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
243        e62, e63
244    }
245
246    public enum Silly65 {
247        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
248        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
249        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
250        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
251        e62, e63, e64
252    }
253
254    public enum Silly127 {
255        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
256        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
257        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
258        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
259        e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
260        e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
261        e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
262        e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
263        e118, e119, e120, e121, e122, e123, e124, e125, e126
264    }
265
266    public enum Silly128 {
267        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
268        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
269        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
270        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
271        e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
272        e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
273        e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
274        e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
275        e118, e119, e120, e121, e122, e123, e124, e125, e126, e127
276    }
277
278    public enum Silly129 {
279        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
280        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
281        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
282        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
283        e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
284        e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
285        e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
286        e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
287        e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128
288    }
289
290    public enum Silly500 {
291        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
292        e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
293        e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
294        e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
295        e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
296        e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
297        e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
298        e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
299        e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128, e129,
300        e130, e131, e132, e133, e134, e135, e136, e137, e138, e139, e140, e141,
301        e142, e143, e144, e145, e146, e147, e148, e149, e150, e151, e152, e153,
302        e154, e155, e156, e157, e158, e159, e160, e161, e162, e163, e164, e165,
303        e166, e167, e168, e169, e170, e171, e172, e173, e174, e175, e176, e177,
304        e178, e179, e180, e181, e182, e183, e184, e185, e186, e187, e188, e189,
305        e190, e191, e192, e193, e194, e195, e196, e197, e198, e199, e200, e201,
306        e202, e203, e204, e205, e206, e207, e208, e209, e210, e211, e212, e213,
307        e214, e215, e216, e217, e218, e219, e220, e221, e222, e223, e224, e225,
308        e226, e227, e228, e229, e230, e231, e232, e233, e234, e235, e236, e237,
309        e238, e239, e240, e241, e242, e243, e244, e245, e246, e247, e248, e249,
310        e250, e251, e252, e253, e254, e255, e256, e257, e258, e259, e260, e261,
311        e262, e263, e264, e265, e266, e267, e268, e269, e270, e271, e272, e273,
312        e274, e275, e276, e277, e278, e279, e280, e281, e282, e283, e284, e285,
313        e286, e287, e288, e289, e290, e291, e292, e293, e294, e295, e296, e297,
314        e298, e299, e300, e301, e302, e303, e304, e305, e306, e307, e308, e309,
315        e310, e311, e312, e313, e314, e315, e316, e317, e318, e319, e320, e321,
316        e322, e323, e324, e325, e326, e327, e328, e329, e330, e331, e332, e333,
317        e334, e335, e336, e337, e338, e339, e340, e341, e342, e343, e344, e345,
318        e346, e347, e348, e349, e350, e351, e352, e353, e354, e355, e356, e357,
319        e358, e359, e360, e361, e362, e363, e364, e365, e366, e367, e368, e369,
320        e370, e371, e372, e373, e374, e375, e376, e377, e378, e379, e380, e381,
321        e382, e383, e384, e385, e386, e387, e388, e389, e390, e391, e392, e393,
322        e394, e395, e396, e397, e398, e399, e400, e401, e402, e403, e404, e405,
323        e406, e407, e408, e409, e410, e411, e412, e413, e414, e415, e416, e417,
324        e418, e419, e420, e421, e422, e423, e424, e425, e426, e427, e428, e429,
325        e430, e431, e432, e433, e434, e435, e436, e437, e438, e439, e440, e441,
326        e442, e443, e444, e445, e446, e447, e448, e449, e450, e451, e452, e453,
327        e454, e455, e456, e457, e458, e459, e460, e461, e462, e463, e464, e465,
328        e466, e467, e468, e469, e470, e471, e472, e473, e474, e475, e476, e477,
329        e478, e479, e480, e481, e482, e483, e484, e485, e486, e487, e488, e489,
330        e490, e491, e492, e493, e494, e495, e496, e497, e498, e499
331    }
332
333}
334