1/*
2 * Copyright (C) 2008 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import static com.google.common.base.Preconditions.checkArgument;
20import static java.util.Arrays.asList;
21
22import com.google.common.annotations.GwtCompatible;
23import com.google.common.annotations.GwtIncompatible;
24import com.google.common.collect.testing.SetTestSuiteBuilder;
25import com.google.common.collect.testing.TestStringSetGenerator;
26import com.google.common.collect.testing.features.CollectionFeature;
27import com.google.common.collect.testing.features.CollectionSize;
28
29import junit.framework.Test;
30import junit.framework.TestCase;
31import junit.framework.TestSuite;
32
33import java.util.HashSet;
34import java.util.Set;
35
36/**
37 * Unit tests for {@link Sets#union}, {@link Sets#intersection} and
38 * {@link Sets#difference}.
39 *
40 * @author Kevin Bourrillion
41 */
42@GwtCompatible(emulated = true)
43public class SetOperationsTest extends TestCase {
44  @GwtIncompatible("suite")
45  public static Test suite() {
46    TestSuite suite = new TestSuite();
47
48    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
49          @Override protected Set<String> create(String[] elements) {
50            return Sets.union(
51                Sets.<String>newHashSet(), Sets.<String>newHashSet());
52          }
53        })
54        .named("empty U empty")
55        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
56            CollectionFeature.ALLOWS_NULL_VALUES)
57        .createTestSuite());
58
59    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
60          @Override protected Set<String> create(String[] elements) {
61            checkArgument(elements.length == 1);
62            return Sets.union(
63                Sets.<String>newHashSet(elements), Sets.newHashSet(elements));
64          }
65        })
66        .named("singleton U itself")
67        .withFeatures(CollectionSize.ONE, CollectionFeature.ALLOWS_NULL_VALUES)
68        .createTestSuite());
69
70    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
71          @Override protected Set<String> create(String[] elements) {
72            return Sets.union(
73                Sets.<String>newHashSet(), Sets.newHashSet(elements));
74          }
75        })
76        .named("empty U set")
77        .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL,
78            CollectionFeature.ALLOWS_NULL_VALUES)
79        .createTestSuite());
80
81    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
82          @Override protected Set<String> create(String[] elements) {
83            return Sets.union(
84                Sets.newHashSet(elements), Sets.<String>newHashSet());
85          }
86        })
87        .named("set U empty")
88        .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL,
89            CollectionFeature.ALLOWS_NULL_VALUES)
90        .createTestSuite());
91
92    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
93          @Override protected Set<String> create(String[] elements) {
94            checkArgument(elements.length == 3);
95            // Put the sets in different orders for the hell of it
96            return Sets.union(
97                Sets.newLinkedHashSet(asList(elements)),
98                Sets.newLinkedHashSet(
99                    asList(elements[1], elements[0], elements[2])));
100          }
101        })
102        .named("set U itself")
103        .withFeatures(CollectionSize.SEVERAL,
104            CollectionFeature.ALLOWS_NULL_VALUES)
105        .createTestSuite());
106
107    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
108          @Override protected Set<String> create(String[] elements) {
109            checkArgument(elements.length == 3);
110            return Sets.union(
111                Sets.newHashSet(elements[0]),
112                Sets.newHashSet(elements[1], elements[2]));
113          }
114        })
115        .named("union of disjoint")
116        .withFeatures(CollectionSize.SEVERAL,
117            CollectionFeature.ALLOWS_NULL_VALUES)
118        .createTestSuite());
119
120    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
121          @Override protected Set<String> create(String[] elements) {
122            return Sets.union(
123                Sets.<String>newHashSet(elements[0], elements[1]),
124                Sets.newHashSet(elements[1], elements[2]));
125          }
126        })
127        .named("venn")
128        .withFeatures(CollectionSize.SEVERAL,
129            CollectionFeature.ALLOWS_NULL_VALUES)
130        .createTestSuite());
131
132    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
133          @Override protected Set<String> create(String[] elements) {
134            return Sets.intersection(
135                Sets.<String>newHashSet(), Sets.<String>newHashSet());
136          }
137        })
138        .named("empty & empty")
139        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
140            CollectionFeature.ALLOWS_NULL_VALUES)
141        .createTestSuite());
142
143    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
144          @Override protected Set<String> create(String[] elements) {
145            return Sets.intersection(
146                Sets.<String>newHashSet(), Sets.newHashSet((String) null));
147          }
148        })
149        .named("empty & singleton")
150        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
151            CollectionFeature.ALLOWS_NULL_VALUES)
152        .createTestSuite());
153
154    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
155          @Override protected Set<String> create(String[] elements) {
156            return Sets.intersection(
157                Sets.newHashSet("a", "b"), Sets.newHashSet("c", "d"));
158          }
159        })
160        .named("intersection of disjoint")
161        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
162            CollectionFeature.ALLOWS_NULL_VALUES)
163        .createTestSuite());
164
165    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
166          @Override protected Set<String> create(String[] elements) {
167            return Sets.intersection(
168                Sets.newHashSet(elements), Sets.newHashSet(elements));
169          }
170        })
171        .named("set & itself")
172        .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL,
173            CollectionFeature.ALLOWS_NULL_VALUES)
174        .createTestSuite());
175
176    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
177          @Override protected Set<String> create(String[] elements) {
178            return Sets.intersection(
179                Sets.newHashSet("a", elements[0], "b"),
180                Sets.newHashSet("c", elements[0], "d"));
181          }
182        })
183        .named("intersection with overlap of one")
184        .withFeatures(CollectionSize.ONE, CollectionFeature.ALLOWS_NULL_VALUES)
185        .createTestSuite());
186
187    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
188          @Override protected Set<String> create(String[] elements) {
189            return Sets.difference(
190                Sets.<String>newHashSet(), Sets.<String>newHashSet());
191          }
192        })
193        .named("empty - empty")
194        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
195            CollectionFeature.ALLOWS_NULL_VALUES)
196        .createTestSuite());
197
198    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
199          @Override protected Set<String> create(String[] elements) {
200            return Sets.difference(Sets.newHashSet("a"), Sets.newHashSet("a"));
201          }
202        })
203        .named("singleton - itself")
204        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
205            CollectionFeature.ALLOWS_NULL_VALUES)
206        .createTestSuite());
207
208    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
209          @Override protected Set<String> create(String[] elements) {
210            Set<String> set = Sets.newHashSet("b", "c");
211            Set<String> other = Sets.newHashSet("a", "b", "c", "d");
212            return Sets.difference(set, other);
213          }
214        })
215        .named("set - superset")
216        .withFeatures(CollectionSize.ZERO, CollectionFeature.NONE,
217            CollectionFeature.ALLOWS_NULL_VALUES)
218        .createTestSuite());
219
220    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
221          @Override protected Set<String> create(String[] elements) {
222            Set<String> set = Sets.newHashSet(elements);
223            Set<String> other = Sets.newHashSet("wz", "xq");
224            set.addAll(other);
225            other.add("pq");
226            return Sets.difference(set, other);
227          }
228        })
229        .named("set - set")
230        .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
231            CollectionFeature.ALLOWS_NULL_VALUES)
232        .createTestSuite());
233
234    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
235          @Override protected Set<String> create(String[] elements) {
236            return Sets.difference(
237                Sets.newHashSet(elements), Sets.newHashSet());
238          }
239        })
240        .named("set - empty")
241        .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL,
242            CollectionFeature.ALLOWS_NULL_VALUES)
243        .createTestSuite());
244
245    suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
246          @Override protected Set<String> create(String[] elements) {
247            return Sets.difference(
248                Sets.<String>newHashSet(elements), Sets.newHashSet("xx", "xq"));
249          }
250        })
251        .named("set - disjoint")
252        .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES)
253        .createTestSuite());
254
255    suite.addTestSuite(MoreTests.class);
256    return suite;
257  }
258
259  public static class MoreTests extends TestCase {
260    Set<String> friends;
261    Set<String> enemies;
262
263    @Override public void setUp() {
264      friends = Sets.newHashSet("Tom", "Joe", "Dave");
265      enemies = Sets.newHashSet("Dick", "Harry", "Tom");
266    }
267
268    public void testUnion() {
269      Set<String> all = Sets.union(friends, enemies);
270      assertEquals(5, all.size());
271
272      ImmutableSet<String> immut = Sets.union(friends, enemies).immutableCopy();
273      HashSet<String> mut
274          = Sets.union(friends, enemies).copyInto(new HashSet<String>());
275
276      enemies.add("Buck");
277      assertEquals(6, all.size());
278      assertEquals(5, immut.size());
279      assertEquals(5, mut.size());
280    }
281
282    public void testIntersection() {
283      Set<String> friends = Sets.newHashSet("Tom", "Joe", "Dave");
284      Set<String> enemies = Sets.newHashSet("Dick", "Harry", "Tom");
285
286      Set<String> frenemies = Sets.intersection(friends, enemies);
287      assertEquals(1, frenemies.size());
288
289      ImmutableSet<String> immut
290          = Sets.intersection(friends, enemies).immutableCopy();
291      HashSet<String> mut
292          = Sets.intersection(friends, enemies).copyInto(new HashSet<String>());
293
294      enemies.add("Joe");
295      assertEquals(2, frenemies.size());
296      assertEquals(1, immut.size());
297      assertEquals(1, mut.size());
298    }
299
300    public void testDifference() {
301      Set<String> friends = Sets.newHashSet("Tom", "Joe", "Dave");
302      Set<String> enemies = Sets.newHashSet("Dick", "Harry", "Tom");
303
304      Set<String> goodFriends = Sets.difference(friends, enemies);
305      assertEquals(2, goodFriends.size());
306
307      ImmutableSet<String> immut
308          = Sets.difference(friends, enemies).immutableCopy();
309      HashSet<String> mut
310          = Sets.difference(friends, enemies).copyInto(new HashSet<String>());
311
312      enemies.add("Dave");
313      assertEquals(1, goodFriends.size());
314      assertEquals(2, immut.size());
315      assertEquals(2, mut.size());
316    }
317
318    public void testSymmetricDifference() {
319      Set<String> friends = Sets.newHashSet("Tom", "Joe", "Dave");
320      Set<String> enemies = Sets.newHashSet("Dick", "Harry", "Tom");
321
322      Set<String> symmetricDifferenceFriendsFirst = Sets.symmetricDifference(
323          friends, enemies);
324      assertEquals(4, symmetricDifferenceFriendsFirst.size());
325
326      Set<String> symmetricDifferenceEnemiesFirst = Sets.symmetricDifference(
327          enemies, friends);
328      assertEquals(4, symmetricDifferenceEnemiesFirst.size());
329
330      assertEquals(symmetricDifferenceFriendsFirst,
331          symmetricDifferenceEnemiesFirst);
332
333      ImmutableSet<String> immut
334          = Sets.symmetricDifference(friends, enemies).immutableCopy();
335      HashSet<String> mut = Sets.symmetricDifference(friends, enemies)
336          .copyInto(new HashSet<String>());
337
338      enemies.add("Dave");
339      assertEquals(3, symmetricDifferenceFriendsFirst.size());
340      assertEquals(4, immut.size());
341      assertEquals(4, mut.size());
342
343      immut = Sets.symmetricDifference(enemies, friends).immutableCopy();
344      mut = Sets.symmetricDifference(enemies, friends).
345          copyInto(new HashSet<String>());
346      friends.add("Harry");
347      assertEquals(2, symmetricDifferenceEnemiesFirst.size());
348      assertEquals(3, immut.size());
349      assertEquals(3, mut.size());
350    }
351  }
352}
353