1 /*
   2  * Copyright 2003-2004 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug     4904135 4923181
  27  * @summary Unit test for EnumSet
  28  * @author  Josh Bloch
  29  * @author  Neal Gafter
  30  * @author  Yo Ma Ma
  31  */
  32 
  33 import java.util.*;
  34 import java.io.*;
  35 
  36 public class EnumSetBash {
  37     static Random rnd = new Random();
  38 
  39     public static void main(String[] args) {
  40         bash(Silly0.class);
  41         bash(Silly1.class);
  42         bash(Silly31.class);
  43         bash(Silly32.class);
  44         bash(Silly33.class);
  45         bash(Silly63.class);
  46         bash(Silly64.class);
  47         bash(Silly65.class);
  48         bash(Silly127.class);
  49         bash(Silly128.class);
  50         bash(Silly129.class);
  51         bash(Silly500.class);
  52     }
  53 
  54     static <T extends Enum<T>> void bash(Class<T> enumClass) {
  55         Enum[] universe = EnumSet.allOf(enumClass).toArray(new Enum[0]);
  56         int numItr = 1000;
  57 
  58         for (int i=0; i<numItr; i++) {
  59             EnumSet<T> s1 = EnumSet.noneOf(enumClass);
  60             EnumSet<T> s2 = clone(s1, enumClass);
  61             AddRandoms(s1, universe);
  62             AddRandoms(s2, universe);
  63 
  64             EnumSet<T> intersection = clone(s1, enumClass);
  65             intersection.retainAll(s2);
  66             EnumSet<T> diff1 = clone(s1, enumClass); diff1.removeAll(s2);
  67             EnumSet<T> diff2 = clone(s2, enumClass); diff2.removeAll(s1);
  68             EnumSet<T> union = clone(s1, enumClass); union.addAll(s2);
  69 
  70             if (diff1.removeAll(diff2))
  71                 fail("Set algebra identity 2 failed");
  72             if (diff1.removeAll(intersection))
  73                 fail("Set algebra identity 3 failed");
  74             if (diff2.removeAll(diff1))
  75                 fail("Set algebra identity 4 failed");
  76             if (diff2.removeAll(intersection))
  77                 fail("Set algebra identity 5 failed");
  78             if (intersection.removeAll(diff1))
  79                 fail("Set algebra identity 6 failed");
  80             if (intersection.removeAll(diff1))
  81                 fail("Set algebra identity 7 failed");
  82 
  83             intersection.addAll(diff1); intersection.addAll(diff2);
  84             if (!intersection.equals(union))
  85                 fail("Set algebra identity 1 failed");
  86 
  87             if (new HashSet<T>(union).hashCode() != union.hashCode())
  88                 fail("Incorrect hashCode computation.");
  89 
  90             Iterator e = union.iterator();
  91             while (e.hasNext())
  92                 if (!intersection.remove(e.next()))
  93                     fail("Couldn't remove element from copy.");
  94             if (!intersection.isEmpty())
  95                 fail("Copy nonempty after deleting all elements.");
  96 
  97             e = union.iterator();
  98             while (e.hasNext()) {
  99                 Object o = e.next();
 100                 if (!union.contains(o))
 101                     fail("Set doesn't contain one of its elements.");
 102                 e.remove();
 103                 if (union.contains(o))
 104                     fail("Set contains element after deletion.");
 105             }
 106             if (!union.isEmpty())
 107                 fail("Set nonempty after deleting all elements.");
 108 
 109             s1.clear();
 110             if (!s1.isEmpty())
 111                 fail("Set nonempty after clear.");
 112         }
 113     }
 114 
 115     // Done inefficiently so as to exercise various functions
 116     static <E extends Enum<E>> EnumSet<E> clone(EnumSet<E> s, Class<E> cl) {
 117         EnumSet<E> clone = null;
 118         int method = rnd.nextInt(6);
 119         switch(method) {
 120             case 0:
 121                 clone = s.clone();
 122                 break;
 123             case 1:
 124                 clone = EnumSet.noneOf(cl);
 125                 Collection arrayList = (Collection)Arrays.asList(s.toArray());
 126                 clone.addAll((Collection<E>)arrayList);
 127                 break;
 128             case 2:
 129                 clone = EnumSet.copyOf(s);
 130                 break;
 131             case 3:
 132                 clone = EnumSet.copyOf((Collection<E>)s);
 133                 break;
 134             case 4:
 135                 if (s.isEmpty())
 136                     clone = EnumSet.copyOf((Collection<E>)s);
 137                 else
 138                     clone = EnumSet.copyOf((Collection<E>)(Collection)
 139                                            Arrays.asList(s.toArray()));
 140                 break;
 141             case 5:
 142                 clone = (EnumSet<E>) deepCopy(s);
 143         }
 144         if (!s.equals(clone))
 145             fail("Set not equal to copy. " + method);
 146         if (!s.containsAll(clone))
 147             fail("Set does not contain copy. " + method);
 148         if (!clone.containsAll(s))
 149             fail("Copy does not contain set. " + method);
 150         return clone;
 151     }
 152 
 153     // Utility method to do a deep copy of an object *very slowly* using
 154     // serialization/deserialization
 155     static <T> T deepCopy(T oldObj) {
 156         try {
 157             ByteArrayOutputStream bos = new ByteArrayOutputStream();
 158             ObjectOutputStream oos = new ObjectOutputStream(bos);
 159             oos.writeObject(oldObj);
 160             oos.flush();
 161             ByteArrayInputStream bin = new ByteArrayInputStream(
 162                 bos.toByteArray());
 163             ObjectInputStream ois = new ObjectInputStream(bin);
 164             return (T) ois.readObject();
 165         } catch(Exception e) {
 166             throw new IllegalArgumentException(e.toString());
 167         }
 168     }
 169 
 170     static <T extends Enum<T>> void AddRandoms(EnumSet<T> s, Enum[] universe) {
 171         for (int i=0; i < universe.length * 2 / 3; i++) {
 172             T e = (T) universe[rnd.nextInt(universe.length)];
 173 
 174             boolean prePresent = s.contains(e);
 175             int preSize = s.size();
 176             boolean added = s.add(e);
 177             if (!s.contains(e))
 178                 fail ("Element not present after addition.");
 179             if (added == prePresent)
 180                 fail ("added == alreadyPresent");
 181             int postSize = s.size();
 182             if (added && preSize == postSize)
 183                 fail ("Add returned true, but size didn't change.");
 184             if (!added && preSize != postSize)
 185                 fail ("Add returned false, but size changed.");
 186         }
 187     }
 188 
 189     static void fail(String s) {
 190         throw new RuntimeException(s);
 191     }
 192 
 193     public enum Silly0 { };
 194 
 195     public enum Silly1 { e1 }
 196 
 197     public enum Silly31 {
 198         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 199         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30
 200     }
 201 
 202     public enum Silly32 {
 203         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 204         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31
 205     }
 206 
 207     public enum Silly33 {
 208         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 209         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 210         e32
 211     }
 212 
 213     public enum Silly63 {
 214         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 215         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 216         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 217         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 218         e62
 219     }
 220 
 221     public enum Silly64 {
 222         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 223         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 224         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 225         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 226         e62, e63
 227     }
 228 
 229     public enum Silly65 {
 230         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 231         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 232         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 233         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 234         e62, e63, e64
 235     }
 236 
 237     public enum Silly127 {
 238         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 239         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 240         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 241         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 242         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 243         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 244         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 245         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 246         e118, e119, e120, e121, e122, e123, e124, e125, e126
 247     }
 248 
 249     public enum Silly128 {
 250         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 251         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 252         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 253         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 254         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 255         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 256         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 257         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 258         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127
 259     }
 260 
 261     public enum Silly129 {
 262         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 263         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 264         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 265         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 266         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 267         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 268         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 269         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 270         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128
 271     }
 272 
 273     public enum Silly500 {
 274         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 275         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 276         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 277         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 278         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 279         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 280         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 281         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 282         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128, e129,
 283         e130, e131, e132, e133, e134, e135, e136, e137, e138, e139, e140, e141,
 284         e142, e143, e144, e145, e146, e147, e148, e149, e150, e151, e152, e153,
 285         e154, e155, e156, e157, e158, e159, e160, e161, e162, e163, e164, e165,
 286         e166, e167, e168, e169, e170, e171, e172, e173, e174, e175, e176, e177,
 287         e178, e179, e180, e181, e182, e183, e184, e185, e186, e187, e188, e189,
 288         e190, e191, e192, e193, e194, e195, e196, e197, e198, e199, e200, e201,
 289         e202, e203, e204, e205, e206, e207, e208, e209, e210, e211, e212, e213,
 290         e214, e215, e216, e217, e218, e219, e220, e221, e222, e223, e224, e225,
 291         e226, e227, e228, e229, e230, e231, e232, e233, e234, e235, e236, e237,
 292         e238, e239, e240, e241, e242, e243, e244, e245, e246, e247, e248, e249,
 293         e250, e251, e252, e253, e254, e255, e256, e257, e258, e259, e260, e261,
 294         e262, e263, e264, e265, e266, e267, e268, e269, e270, e271, e272, e273,
 295         e274, e275, e276, e277, e278, e279, e280, e281, e282, e283, e284, e285,
 296         e286, e287, e288, e289, e290, e291, e292, e293, e294, e295, e296, e297,
 297         e298, e299, e300, e301, e302, e303, e304, e305, e306, e307, e308, e309,
 298         e310, e311, e312, e313, e314, e315, e316, e317, e318, e319, e320, e321,
 299         e322, e323, e324, e325, e326, e327, e328, e329, e330, e331, e332, e333,
 300         e334, e335, e336, e337, e338, e339, e340, e341, e342, e343, e344, e345,
 301         e346, e347, e348, e349, e350, e351, e352, e353, e354, e355, e356, e357,
 302         e358, e359, e360, e361, e362, e363, e364, e365, e366, e367, e368, e369,
 303         e370, e371, e372, e373, e374, e375, e376, e377, e378, e379, e380, e381,
 304         e382, e383, e384, e385, e386, e387, e388, e389, e390, e391, e392, e393,
 305         e394, e395, e396, e397, e398, e399, e400, e401, e402, e403, e404, e405,
 306         e406, e407, e408, e409, e410, e411, e412, e413, e414, e415, e416, e417,
 307         e418, e419, e420, e421, e422, e423, e424, e425, e426, e427, e428, e429,
 308         e430, e431, e432, e433, e434, e435, e436, e437, e438, e439, e440, e441,
 309         e442, e443, e444, e445, e446, e447, e448, e449, e450, e451, e452, e453,
 310         e454, e455, e456, e457, e458, e459, e460, e461, e462, e463, e464, e465,
 311         e466, e467, e468, e469, e470, e471, e472, e473, e474, e475, e476, e477,
 312         e478, e479, e480, e481, e482, e483, e484, e485, e486, e487, e488, e489,
 313         e490, e491, e492, e493, e494, e495, e496, e497, e498, e499
 314     }
 315 
 316 }