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