View Javadoc
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.juneau.commons.collections;
18  
19  import static org.apache.juneau.junit.bct.BctAssertions.*;
20  import static org.junit.jupiter.api.Assertions.*;
21  
22  import java.util.*;
23  
24  import org.apache.juneau.*;
25  import org.junit.jupiter.api.*;
26  
27  class FluentSet_Test extends TestBase {
28  
29  	//====================================================================================================
30  	// Basic functionality - a(E element)
31  	//====================================================================================================
32  
33  	@Test
34  	void a01_addSingleElement() {
35  		var set = new FluentSet<>(new LinkedHashSet<String>());
36  		set.a("item1").a("item2").a("item3");
37  
38  		assertSize(3, set);
39  		assertTrue(set.contains("item1"));
40  		assertTrue(set.contains("item2"));
41  		assertTrue(set.contains("item3"));
42  	}
43  
44  	@Test
45  	void a02_addSingleElement_returnsThis() {
46  		var set = new FluentSet<>(new LinkedHashSet<String>());
47  		var result = set.a("item1");
48  
49  		assertSame(set, result);
50  	}
51  
52  	@Test
53  	void a03_addSingleElement_nullValue() {
54  		var set = new FluentSet<>(new LinkedHashSet<String>());
55  		set.a("item1").a(null).a("item3");
56  
57  		assertSize(3, set);
58  		assertTrue(set.contains("item1"));
59  		assertTrue(set.contains(null));
60  		assertTrue(set.contains("item3"));
61  	}
62  
63  	@Test
64  	void a04_addSingleElement_duplicateIgnored() {
65  		var set = new FluentSet<>(new LinkedHashSet<String>());
66  		set.a("item1").a("item2").a("item1");
67  
68  		assertSize(2, set);
69  		assertTrue(set.contains("item1"));
70  		assertTrue(set.contains("item2"));
71  	}
72  
73  	//====================================================================================================
74  	// a(Collection) method
75  	//====================================================================================================
76  
77  	@Test
78  	void b01_addCollection() {
79  		var set = new FluentSet<>(new LinkedHashSet<String>());
80  		var other = List.of("item1", "item2", "item3");
81  		set.aa(other);
82  
83  		assertSize(3, set);
84  		assertTrue(set.contains("item1"));
85  		assertTrue(set.contains("item2"));
86  		assertTrue(set.contains("item3"));
87  	}
88  
89  	@Test
90  	void b02_addCollection_returnsThis() {
91  		var set = new FluentSet<>(new LinkedHashSet<String>());
92  		var other = List.of("item1", "item2");
93  		var result = set.aa(other);
94  
95  		assertSame(set, result);
96  	}
97  
98  	@Test
99  	void b03_addCollection_nullCollection() {
100 		var set = new FluentSet<>(new LinkedHashSet<String>());
101 		set.a("item1");
102 		set.aa((Collection<String>)null);
103 		set.a("item2");
104 
105 		assertSize(2, set);
106 		assertTrue(set.contains("item1"));
107 		assertTrue(set.contains("item2"));
108 	}
109 
110 	@Test
111 	void b04_addCollection_emptyCollection() {
112 		var set = new FluentSet<>(new LinkedHashSet<String>());
113 		set.a("item1");
114 		set.aa(List.of());
115 		set.a("item2");
116 
117 		assertSize(2, set);
118 		assertTrue(set.contains("item1"));
119 		assertTrue(set.contains("item2"));
120 	}
121 
122 	@Test
123 	void b05_addCollection_duplicatesIgnored() {
124 		var set = new FluentSet<>(new LinkedHashSet<String>());
125 		set.aa(List.of("item1", "item2"));
126 		set.aa(List.of("item2", "item3"));  // item2 is duplicate
127 
128 		assertSize(3, set);
129 		assertTrue(set.contains("item1"));
130 		assertTrue(set.contains("item2"));
131 		assertTrue(set.contains("item3"));
132 	}
133 
134 	//====================================================================================================
135 	// ai(boolean, E) method
136 	//====================================================================================================
137 
138 	@Test
139 	void c01_ai_conditionTrue() {
140 		var set = new FluentSet<>(new LinkedHashSet<String>());
141 		set.a("item1").ai(true, "item2").a("item3");
142 
143 		assertSize(3, set);
144 		assertTrue(set.contains("item1"));
145 		assertTrue(set.contains("item2"));
146 		assertTrue(set.contains("item3"));
147 	}
148 
149 	@Test
150 	void c02_ai_conditionFalse() {
151 		var set = new FluentSet<>(new LinkedHashSet<String>());
152 		set.a("item1").ai(false, "item2").a("item3");
153 
154 		assertSize(2, set);
155 		assertTrue(set.contains("item1"));
156 		assertFalse(set.contains("item2"));
157 		assertTrue(set.contains("item3"));
158 	}
159 
160 	@Test
161 	void c03_ai_returnsThis() {
162 		var set = new FluentSet<>(new LinkedHashSet<String>());
163 		var result1 = set.ai(true, "item1");
164 		var result2 = set.ai(false, "item2");
165 
166 		assertSame(set, result1);
167 		assertSame(set, result2);
168 	}
169 
170 	@Test
171 	void c04_ai_conditionalBuilding() {
172 		boolean includeDebug = true;
173 		boolean includeTest = false;
174 
175 		var set = new FluentSet<>(new LinkedHashSet<String>())
176 			.a("basic")
177 			.ai(includeDebug, "debug")
178 			.ai(includeTest, "test");
179 
180 		assertSize(2, set);
181 		assertTrue(set.contains("basic"));
182 		assertTrue(set.contains("debug"));
183 		assertFalse(set.contains("test"));
184 	}
185 
186 	//====================================================================================================
187 	// Method chaining
188 	//====================================================================================================
189 
190 	@Test
191 	void d01_methodChaining() {
192 		var set = new FluentSet<>(new LinkedHashSet<String>())
193 			.a("item1")
194 			.a("item2")
195 			.ai(true, "item3")
196 			.ai(false, "item4")
197 			.aa(List.of("item5", "item6"));
198 
199 		assertSize(5, set);
200 		assertTrue(set.contains("item1"));
201 		assertTrue(set.contains("item2"));
202 		assertTrue(set.contains("item3"));
203 		assertTrue(set.contains("item5"));
204 		assertTrue(set.contains("item6"));
205 		assertFalse(set.contains("item4"));
206 	}
207 
208 	//====================================================================================================
209 	// Set interface methods
210 	//====================================================================================================
211 
212 	@Test
213 	void e01_setInterface_size() {
214 		var set = new FluentSet<>(new LinkedHashSet<String>());
215 		assertEquals(0, set.size());
216 
217 		set.a("item1");
218 		assertEquals(1, set.size());
219 
220 		set.a("item2");
221 		assertEquals(2, set.size());
222 	}
223 
224 	@Test
225 	void e02_setInterface_add() {
226 		var set = new FluentSet<>(new LinkedHashSet<String>());
227 		assertTrue(set.add("item1"));
228 		assertTrue(set.add("item2"));
229 		assertFalse(set.add("item1"));  // Duplicate, returns false
230 
231 		assertSize(2, set);
232 		assertTrue(set.contains("item1"));
233 		assertTrue(set.contains("item2"));
234 	}
235 
236 	@Test
237 	void e03_setInterface_addAll() {
238 		var set = new FluentSet<>(new LinkedHashSet<String>());
239 		set.a("item1");
240 		assertTrue(set.addAll(List.of("item2", "item3")));
241 
242 		assertSize(3, set);
243 		assertTrue(set.contains("item1"));
244 		assertTrue(set.contains("item2"));
245 		assertTrue(set.contains("item3"));
246 	}
247 
248 	@Test
249 	void e04_setInterface_remove() {
250 		var set = new FluentSet<>(new LinkedHashSet<String>());
251 		set.a("item1").a("item2").a("item3");
252 
253 		assertTrue(set.remove("item2"));
254 		assertSize(2, set);
255 		assertTrue(set.contains("item1"));
256 		assertFalse(set.contains("item2"));
257 		assertTrue(set.contains("item3"));
258 	}
259 
260 	@Test
261 	void e05_setInterface_contains() {
262 		var set = new FluentSet<>(new LinkedHashSet<String>());
263 		set.a("item1").a("item2");
264 
265 		assertTrue(set.contains("item1"));
266 		assertTrue(set.contains("item2"));
267 		assertFalse(set.contains("item3"));
268 	}
269 
270 	@Test
271 	void e06_setInterface_containsAll() {
272 		var set = new FluentSet<>(new LinkedHashSet<String>());
273 		set.a("item1").a("item2").a("item3");
274 
275 		assertTrue(set.containsAll(List.of("item1", "item2")));
276 		assertTrue(set.containsAll(List.of("item1", "item2", "item3")));
277 		assertFalse(set.containsAll(List.of("item1", "item4")));
278 	}
279 
280 	@Test
281 	void e07_setInterface_isEmpty() {
282 		var set = new FluentSet<>(new LinkedHashSet<String>());
283 		assertTrue(set.isEmpty());
284 
285 		set.a("item1");
286 		assertFalse(set.isEmpty());
287 	}
288 
289 	@Test
290 	void e08_setInterface_clear() {
291 		var set = new FluentSet<>(new LinkedHashSet<String>());
292 		set.a("item1").a("item2").a("item3");
293 
294 		set.clear();
295 		assertTrue(set.isEmpty());
296 		assertSize(0, set);
297 	}
298 
299 	@Test
300 	void e09_setInterface_iterator() {
301 		var set = new FluentSet<>(new LinkedHashSet<String>());
302 		set.a("item1").a("item2").a("item3");
303 
304 		var found = new LinkedHashSet<String>();
305 		for (var item : set) {
306 			found.add(item);
307 		}
308 
309 		assertSize(3, found);
310 		assertTrue(found.contains("item1"));
311 		assertTrue(found.contains("item2"));
312 		assertTrue(found.contains("item3"));
313 	}
314 
315 	@Test
316 	void e10_setInterface_toArray() {
317 		var set = new FluentSet<>(new LinkedHashSet<String>());
318 		set.a("item1").a("item2").a("item3");
319 
320 		var array = set.toArray();
321 		assertEquals(3, array.length);
322 		// Order may vary, so just check all items are present
323 		var arrayList = Arrays.asList(array);
324 		assertTrue(arrayList.contains("item1"));
325 		assertTrue(arrayList.contains("item2"));
326 		assertTrue(arrayList.contains("item3"));
327 	}
328 
329 	@Test
330 	void e11_setInterface_toArrayTyped() {
331 		var set = new FluentSet<>(new LinkedHashSet<String>());
332 		set.a("item1").a("item2").a("item3");
333 
334 		var array = set.toArray(new String[0]);
335 		assertEquals(3, array.length);
336 		// Order may vary, so just check all items are present
337 		var arrayList = Arrays.asList(array);
338 		assertTrue(arrayList.contains("item1"));
339 		assertTrue(arrayList.contains("item2"));
340 		assertTrue(arrayList.contains("item3"));
341 	}
342 
343 	//====================================================================================================
344 	// Different set implementations
345 	//====================================================================================================
346 
347 	@Test
348 	void f01_hashSet() {
349 		var set = new FluentSet<>(new HashSet<String>());
350 		set.a("item1").a("item2").a("item3");
351 
352 		assertSize(3, set);
353 	}
354 
355 	@Test
356 	void f02_treeSet() {
357 		var set = new FluentSet<>(new TreeSet<String>());
358 		set.a("zebra").a("apple").a("banana");
359 
360 		assertSize(3, set);
361 		// TreeSet maintains sorted order
362 		var iterator = set.iterator();
363 		assertEquals("apple", iterator.next());
364 		assertEquals("banana", iterator.next());
365 		assertEquals("zebra", iterator.next());
366 	}
367 
368 	//====================================================================================================
369 	// Edge cases
370 	//====================================================================================================
371 
372 	@Test
373 	void g01_emptySet() {
374 		var set = new FluentSet<>(new LinkedHashSet<String>());
375 
376 		assertTrue(set.isEmpty());
377 		assertSize(0, set);
378 		assertFalse(set.contains("anything"));
379 	}
380 
381 	@Test
382 	void g02_removeAll() {
383 		var set = new FluentSet<>(new LinkedHashSet<String>());
384 		set.a("item1").a("item2").a("item3").a("item4");
385 
386 		assertTrue(set.removeAll(List.of("item2", "item4")));
387 		assertSize(2, set);
388 		assertTrue(set.contains("item1"));
389 		assertTrue(set.contains("item3"));
390 		assertFalse(set.contains("item2"));
391 		assertFalse(set.contains("item4"));
392 	}
393 
394 	@Test
395 	void g03_retainAll() {
396 		var set = new FluentSet<>(new LinkedHashSet<String>());
397 		set.a("item1").a("item2").a("item3").a("item4");
398 
399 		assertTrue(set.retainAll(List.of("item2", "item4")));
400 		assertSize(2, set);
401 		assertTrue(set.contains("item2"));
402 		assertTrue(set.contains("item4"));
403 		assertFalse(set.contains("item1"));
404 		assertFalse(set.contains("item3"));
405 	}
406 
407 	@Test
408 	void g04_duplicateHandling() {
409 		var set = new FluentSet<>(new LinkedHashSet<String>());
410 		set.a("item1").a("item1").a("item1");
411 
412 		assertSize(1, set);
413 		assertTrue(set.contains("item1"));
414 	}
415 
416 	//====================================================================================================
417 	// toString(), equals(), hashCode()
418 	//====================================================================================================
419 
420 	@Test
421 	void w01_toString_delegatesToUnderlyingSet() {
422 		var set = new FluentSet<>(new LinkedHashSet<String>());
423 		set.a("item1").a("item2").a("item3");
424 
425 		var underlyingSet = new LinkedHashSet<String>();
426 		underlyingSet.add("item1");
427 		underlyingSet.add("item2");
428 		underlyingSet.add("item3");
429 
430 		assertEquals(underlyingSet.toString(), set.toString());
431 	}
432 
433 	@Test
434 	void w02_equals_delegatesToUnderlyingSet() {
435 		var set1 = new FluentSet<>(new LinkedHashSet<String>());
436 		set1.a("item1").a("item2").a("item3");
437 
438 		var set2 = new LinkedHashSet<String>();
439 		set2.add("item1");
440 		set2.add("item2");
441 		set2.add("item3");
442 
443 		assertTrue(set1.equals(set2));
444 		assertTrue(set2.equals(set1));
445 	}
446 
447 	@Test
448 	void w03_equals_differentContents_returnsFalse() {
449 		var set1 = new FluentSet<>(new LinkedHashSet<String>());
450 		set1.a("item1").a("item2");
451 
452 		var set2 = new LinkedHashSet<String>();
453 		set2.add("item1");
454 		set2.add("item3");
455 
456 		assertFalse(set1.equals(set2));
457 		assertFalse(set2.equals(set1));
458 	}
459 
460 	@Test
461 	void w04_hashCode_delegatesToUnderlyingSet() {
462 		var set = new FluentSet<>(new LinkedHashSet<String>());
463 		set.a("item1").a("item2").a("item3");
464 
465 		var underlyingSet = new LinkedHashSet<String>();
466 		underlyingSet.add("item1");
467 		underlyingSet.add("item2");
468 		underlyingSet.add("item3");
469 
470 		assertEquals(underlyingSet.hashCode(), set.hashCode());
471 	}
472 }
473