1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.collections.set;
18  
19  import java.util.Arrays;
20  import java.util.Collection;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Set;
24  
25  import org.apache.commons.collections.collection.AbstractTestCollection;
26  
27  /**
28   * Abstract test class for {@link Set} methods and contracts.
29   * <p>
30   * Since {@link Set} doesn't stipulate much new behavior that isn't already
31   * found in {@link Collection}, this class basically just adds tests for
32   * {@link Set#equals} and {@link Set#hashCode()} along with an updated
33   * {@link #verify()} that ensures elements do not appear more than once in the
34   * set.
35   * <p>
36   * To use, subclass and override the {@link #makeEmptySet()}
37   * method.  You may have to override other protected methods if your
38   * set is not modifiable, or if your set restricts what kinds of
39   * elements may be added; see {@link AbstractTestCollection} for more details.
40   *
41   * @since Commons Collections 3.0
42   * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
43   * 
44   * @author Paul Jack
45   */
46  public abstract class AbstractTestSet extends AbstractTestCollection {
47  
48      /**
49       * JUnit constructor.
50       *
51       * @param name  name for test
52       */
53      public AbstractTestSet(String name) {
54          super(name);
55      }
56  
57      //-----------------------------------------------------------------------
58      /**
59       * Provides additional verifications for sets.
60       */
61      public void verify() {
62          super.verify();
63          
64          assertEquals("Sets should be equal", confirmed, collection);
65          assertEquals("Sets should have equal hashCodes", 
66                       confirmed.hashCode(), collection.hashCode());
67          Collection set = makeConfirmedCollection();
68          Iterator iterator = collection.iterator();
69          while (iterator.hasNext()) {
70              assertTrue("Set.iterator should only return unique elements", 
71                         set.add(iterator.next()));
72          }
73      }
74  
75      //-----------------------------------------------------------------------
76      /**
77       * Set equals method is defined.
78       */
79      public boolean isEqualsCheckable() {
80          return true;
81      }
82  
83      /**
84       * Returns an empty Set for use in modification testing.
85       *
86       * @return a confirmed empty collection
87       */
88      public Collection makeConfirmedCollection() {
89          return new HashSet();
90      }
91  
92      /**
93       * Returns a full Set for use in modification testing.
94       *
95       * @return a confirmed full collection
96       */
97      public Collection makeConfirmedFullCollection() {
98          Collection set = makeConfirmedCollection();
99          set.addAll(Arrays.asList(getFullElements()));
100         return set;
101     }
102 
103     /**
104      * Makes an empty set.  The returned set should have no elements.
105      *
106      * @return an empty set
107      */
108     public abstract Set makeEmptySet();
109 
110     /**
111      * Makes a full set by first creating an empty set and then adding
112      * all the elements returned by {@link #getFullElements()}.
113      *
114      * Override if your set does not support the add operation.
115      *
116      * @return a full set
117      */
118     public Set makeFullSet() {
119         Set set = makeEmptySet();
120         set.addAll(Arrays.asList(getFullElements()));
121         return set;
122     }
123 
124     /**
125      * Makes an empty collection by invoking {@link #makeEmptySet()}.  
126      *
127      * @return an empty collection
128      */
129     public final Collection makeCollection() {
130         return makeEmptySet();
131     }
132 
133     /**
134      * Makes a full collection by invoking {@link #makeFullSet()}.
135      *
136      * @return a full collection
137      */
138     public final Collection makeFullCollection() {
139         return makeFullSet();
140     }
141 
142     //-----------------------------------------------------------------------
143     /**
144      * Return the {@link AbstractTestCollection#collection} fixture, but cast as a Set.  
145      */
146     public Set getSet() {
147         return (Set)collection;
148     }
149 
150     /**
151      * Return the {@link AbstractTestCollection#confirmed} fixture, but cast as a Set.
152      */
153     public Set getConfirmedSet() {
154         return (Set)confirmed;
155     }
156 
157     //-----------------------------------------------------------------------
158     /**
159      * Tests {@link Set#equals(Object)}.
160      */
161     public void testSetEquals() {
162         resetEmpty();
163         assertEquals("Empty sets should be equal", 
164                      getSet(), getConfirmedSet());
165         verify();
166 
167         Collection set2 = makeConfirmedCollection();
168         set2.add("foo");
169         assertTrue("Empty set shouldn't equal nonempty set", 
170                    !getSet().equals(set2));
171 
172         resetFull();
173         assertEquals("Full sets should be equal", getSet(), getConfirmedSet());
174         verify();
175 
176         set2.clear();
177         set2.addAll(Arrays.asList(getOtherElements()));
178         assertTrue("Sets with different contents shouldn't be equal", 
179                    !getSet().equals(set2));
180     }
181 
182     /**
183      * Tests {@link Set#hashCode()}.
184      */
185     public void testSetHashCode() {
186         resetEmpty();
187         assertEquals("Empty sets have equal hashCodes", 
188                      getSet().hashCode(), getConfirmedSet().hashCode());
189 
190         resetFull();
191         assertEquals("Equal sets have equal hashCodes", 
192                      getSet().hashCode(), getConfirmedSet().hashCode());
193     }
194 
195 }