This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new bfaa70e7c8 Commons improvements
bfaa70e7c8 is described below
commit bfaa70e7c8f4dcfbdce15ee4aba5be0f54895eb4
Author: James Bognar <[email protected]>
AuthorDate: Tue Dec 16 18:09:07 2025 -0500
Commons improvements
---
.../commons/collections/FilteredList_Test.java | 227 +++++++++++++++++++++
.../commons/collections/FilteredMap_Test.java | 120 +++++++++++
.../commons/collections/FluentList_Test.java | 13 ++
.../juneau/commons/collections/Lists_Test.java | 164 +++++++++++++++
.../juneau/commons/collections/Maps_Test.java | 14 ++
.../juneau/commons/collections/MultiList_Test.java | 191 +++++++++++++++++
.../juneau/commons/collections/MultiMap_Test.java | 65 ++++++
.../juneau/commons/collections/MultiSet_Test.java | 43 ++++
.../juneau/commons/collections/Sets_Test.java | 219 ++++++++++++++++++++
9 files changed, 1056 insertions(+)
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredList_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredList_Test.java
index f65f116b89..2537cef2a2 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredList_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredList_Test.java
@@ -963,5 +963,232 @@ class FilteredList_Test extends TestBase {
assertEquals("value2", subList.get(0));
assertEquals("value3", subList.get(1));
}
+
+
//====================================================================================================
+ // containsAll() method
+
//====================================================================================================
+
+ @Test
+ void w01_containsAll_allPresent() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+ list.add("value3");
+
+ assertTrue(list.containsAll(List.of("value1", "value2")));
+ assertTrue(list.containsAll(List.of("value1", "value2",
"value3")));
+ }
+
+ @Test
+ void w02_containsAll_someMissing() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertFalse(list.containsAll(List.of("value1", "value4")));
+ assertFalse(list.containsAll(List.of("value4", "value5")));
+ }
+
+ @Test
+ void w03_containsAll_emptyCollection() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+
+ assertTrue(list.containsAll(List.of())); // Empty collection
always returns true
+ }
+
+
//====================================================================================================
+ // removeAll() method
+
//====================================================================================================
+
+ @Test
+ void x01_removeAll_someRemoved() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+ list.add("value3");
+ list.add("value4");
+
+ assertTrue(list.removeAll(List.of("value2", "value4")));
+ assertSize(2, list);
+ assertEquals("value1", list.get(0));
+ assertEquals("value3", list.get(1));
+ }
+
+ @Test
+ void x02_removeAll_noneRemoved() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertFalse(list.removeAll(List.of("value3", "value4"))); //
None present
+ assertSize(2, list);
+ }
+
+ @Test
+ void x03_removeAll_emptyCollection() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertFalse(list.removeAll(List.of())); // Empty collection
returns false
+ assertSize(2, list);
+ }
+
+
//====================================================================================================
+ // retainAll() method
+
//====================================================================================================
+
+ @Test
+ void y01_retainAll_someRetained() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+ list.add("value3");
+ list.add("value4");
+
+ assertTrue(list.retainAll(List.of("value2", "value4")));
+ assertSize(2, list);
+ assertEquals("value2", list.get(0));
+ assertEquals("value4", list.get(1));
+ }
+
+ @Test
+ void y02_retainAll_allRetained() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertFalse(list.retainAll(List.of("value1", "value2",
"value3"))); // All retained, no change
+ assertSize(2, list);
+ }
+
+ @Test
+ void y03_retainAll_noneRetained() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertTrue(list.retainAll(List.of("value3", "value4"))); //
None retained, list cleared
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ void y04_retainAll_emptyCollection() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ assertTrue(list.retainAll(List.of())); // Empty collection,
all removed
+ assertTrue(list.isEmpty());
+ }
+
+
//====================================================================================================
+ // toArray(T[]) method
+
//====================================================================================================
+
+ @Test
+ void z01_toArrayTyped_sufficientSize() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+ list.add("value3");
+
+ var array = list.toArray(new String[3]);
+ assertEquals(3, array.length);
+ assertEquals("value1", array[0]);
+ assertEquals("value2", array[1]);
+ assertEquals("value3", array[2]);
+ }
+
+ @Test
+ void z02_toArrayTyped_insufficientSize() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+ list.add("value3");
+
+ var array = list.toArray(new String[1]); // Array too small,
should create new one
+ assertEquals(3, array.length);
+ assertEquals("value1", array[0]);
+ assertEquals("value2", array[1]);
+ assertEquals("value3", array[2]);
+ }
+
+ @Test
+ void z03_toArrayTyped_largerSize() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ list.add("value1");
+ list.add("value2");
+
+ var array = list.toArray(new String[5]); // Array larger than
list
+ assertEquals(5, array.length);
+ assertEquals("value1", array[0]);
+ assertEquals("value2", array[1]);
+ assertNull(array[2]); // Remaining elements set to null
+ }
+
+ @Test
+ void z04_toArrayTyped_emptyList() {
+ var list = FilteredList
+ .create(String.class)
+ .filter(v -> v != null)
+ .build();
+
+ var array = list.toArray(new String[0]);
+ assertEquals(0, array.length);
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredMap_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredMap_Test.java
index 5b700bff7a..a11432a3f2 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredMap_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FilteredMap_Test.java
@@ -1082,5 +1082,125 @@ class FilteredMap_Test extends TestBase {
assertEquals(underlyingMap.hashCode(), map.hashCode());
}
+
+
//====================================================================================================
+ // addAny() method
+
//====================================================================================================
+
+ @Test
+ void x01_addAny_withMaps() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .build();
+
+ var map1 = Map.of("a", 5, "b", -1);
+ var map2 = Map.of("c", 10);
+ map.addAny(map1, map2); // Adds a=5, c=10 (b=-1 filtered out)
+
+ assertSize(2, map);
+ assertEquals(5, map.get("a"));
+ assertEquals(10, map.get("c"));
+ assertFalse(map.containsKey("b"));
+ }
+
+ @Test
+ void x02_addAny_withNullValues() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .build();
+
+ var map1 = Map.of("a", 5);
+ map.addAny(null, map1, null); // null values ignored
+
+ assertSize(1, map);
+ assertEquals(5, map.get("a"));
+ }
+
+ @Test
+ void x03_addAny_withNonMapObjects() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .build();
+
+ var map1 = Map.of("a", 5);
+ map.addAny(map1, "not-a-map", 123); // Non-Map objects ignored
+
+ assertSize(1, map);
+ assertEquals(5, map.get("a"));
+ }
+
+ @Test
+ void x04_addAny_emptyArray() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .build();
+
+ map.addAny(); // Empty array, no-op
+
+ assertTrue(map.isEmpty());
+ }
+
+
//====================================================================================================
+ // addPairs() method
+
//====================================================================================================
+
+ @Test
+ void y01_addPairs_validPairs() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .build();
+
+ map.addPairs("a", 5, "b", -1, "c", 10); // Adds a=5, c=10
(b=-1 filtered out)
+
+ assertSize(2, map);
+ assertEquals(5, map.get("a"));
+ assertEquals(10, map.get("c"));
+ assertFalse(map.containsKey("b"));
+ }
+
+ @Test
+ void y02_addPairs_oddNumber_throwsException() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null)
+ .build();
+
+ assertThrowsWithMessage(IllegalArgumentException.class, "Odd
number of parameters", () -> {
+ map.addPairs("a", 5, "b"); // Odd number of parameters
+ });
+ }
+
+ @Test
+ void y03_addPairs_emptyArray() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null)
+ .build();
+
+ map.addPairs(); // Empty array, no-op
+
+ assertTrue(map.isEmpty());
+ }
+
+ @Test
+ void y04_addPairs_withTypeConversion() {
+ var map = FilteredMap
+ .create(String.class, Integer.class)
+ .filter((k, v) -> v != null && v > 0)
+ .keyFunction(o -> o.toString())
+ .valueFunction(o -> Integer.parseInt(o.toString()))
+ .build();
+
+ map.addPairs(123, "5", 456, "10"); // Both key and value
converted
+
+ assertSize(2, map);
+ assertEquals(5, map.get("123"));
+ assertEquals(10, map.get("456"));
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FluentList_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FluentList_Test.java
index 36a3169b6d..5b9cba74a5 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FluentList_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/FluentList_Test.java
@@ -255,6 +255,19 @@ class FluentList_Test extends TestBase {
assertEquals("item3", list.get(2));
}
+ @Test
+ void e05b_listInterface_addAllAtIndex() {
+ var list = new FluentList<>(new ArrayList<String>());
+ list.a("item1").a("item4");
+ assertTrue(list.addAll(1, List.of("item2", "item3")));
+
+ assertSize(4, list);
+ assertEquals("item1", list.get(0));
+ assertEquals("item2", list.get(1));
+ assertEquals("item3", list.get(2));
+ assertEquals("item4", list.get(3));
+ }
+
@Test
void e06_listInterface_remove() {
var list = new FluentList<>(new ArrayList<String>());
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Lists_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Lists_Test.java
index 7ab9a1188d..48f0f51a8e 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Lists_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Lists_Test.java
@@ -608,5 +608,169 @@ class Lists_Test extends TestBase {
list.a("c").aa(l("d", "e"));
assertList(list, "a", "b", "c", "d", "e");
}
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // buildFiltered
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void o01_buildFiltered_returnsFilteredList() {
+ var list = Lists.create(String.class)
+ .add("a", "b", "c")
+ .buildFiltered();
+
+ assertNotNull(list);
+ assertSize(3, list);
+ assertList(list, "a", "b", "c");
+ }
+
+ @Test
+ void o02_buildFiltered_sparseEmpty() {
+ var list = Lists.create(String.class)
+ .sparse()
+ .buildFiltered();
+
+ assertNull(list);
+ }
+
+ @Test
+ void o03_buildFiltered_withFiltering() {
+ var list = Lists.create(Integer.class)
+ .filtered(v -> v != null && v > 0)
+ .add(5, -1, 10, 0)
+ .buildFiltered();
+
+ assertNotNull(list);
+ assertList(list, 5, 10);
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // concurrent
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void p01_concurrent_createsSynchronizedList() {
+ var list = Lists.create(String.class)
+ .add("a", "b", "c")
+ .concurrent()
+ .build();
+
+ assertNotNull(list);
+ assertSize(3, list);
+ // Verify it's synchronized by checking it's wrapped
(Collections.synchronizedList returns a wrapper)
+ assertList(list, "a", "b", "c");
+ }
+
+ @Test
+ void p02_concurrent_withSorted() {
+ var list = Lists.create(String.class)
+ .add("c", "a", "b")
+ .sorted()
+ .concurrent()
+ .build();
+
+ assertNotNull(list);
+ assertList(list, "a", "b", "c");
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // filtered
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void q01_filtered_defaultFiltering() {
+ var list = Lists.create(Object.class)
+ .filtered()
+ .add("a", null, false, -1, new String[0], l(), m())
+ .build();
+
+ assertList(list, "a");
+ }
+
+ @Test
+ void q02_filtered_withBooleanFalse() {
+ var list = Lists.create(Boolean.class)
+ .filtered()
+ .add(true, false, true)
+ .build();
+
+ assertList(list, true, true);
+ }
+
+ @Test
+ void q03_filtered_withNumberMinusOne() {
+ var list = Lists.create(Integer.class)
+ .filtered()
+ .add(1, -1, 2, -1, 3)
+ .build();
+
+ assertList(list, 1, 2, 3);
+ }
+
+ @Test
+ void q04_filtered_withEmptyArray() {
+ var list = Lists.create(Object.class)
+ .filtered()
+ .add("a", new String[0], "b")
+ .build();
+
+ assertList(list, "a", "b");
+ }
+
+ @Test
+ void q05_filtered_withEmptyMap() {
+ var list = Lists.create(Object.class)
+ .filtered()
+ .add("a", m(), "b")
+ .build();
+
+ assertList(list, "a", "b");
+ }
+
+ @Test
+ void q06_filtered_withEmptyCollection() {
+ var list = Lists.create(Object.class)
+ .filtered()
+ .add("a", l(), "b")
+ .build();
+
+ assertList(list, "a", "b");
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // filtered(Predicate)
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void r01_filtered_withPredicate() {
+ var list = Lists.create(Integer.class)
+ .filtered(v -> v != null && v > 0)
+ .add(5, -1, 10, 0, 15)
+ .build();
+
+ assertList(list, 5, 10, 15);
+ }
+
+ @Test
+ void r02_filtered_multipleFilters() {
+ var list = Lists.create(Integer.class)
+ .filtered(v -> v != null)
+ .filtered(v -> v > 0)
+ .filtered(v -> v < 100)
+ .add(5, -1, 150, 0, 50, null)
+ .build();
+
+ assertList(list, 5, 50);
+ }
+
+ @Test
+ void r03_filtered_withStringPredicate() {
+ var list = Lists.create(String.class)
+ .filtered(s -> s != null && s.length() > 2)
+ .add("a", "ab", "abc", "abcd", "")
+ .build();
+
+ assertList(list, "abc", "abcd");
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Maps_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Maps_Test.java
index 4e87a0f9c2..150139c615 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Maps_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Maps_Test.java
@@ -706,6 +706,20 @@ class Maps_Test extends TestBase {
});
}
+ @Test
+ void k11_addAny_noKeyFunction_conversionFailure() {
+ // Test line 726: convertKey throws exception when keyFunction
is null and key can't be converted
+ var inputMap = new LinkedHashMap<Object,String>();
+ inputMap.put(new Object(), "value"); // Object can't be
converted to String, and no keyFunction
+
+ assertThrows(RuntimeException.class, () -> {
+ Maps.create(String.class, String.class)
+ // No keyFunction set
+ .addAny(inputMap)
+ .build();
+ });
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Concurrent
//-----------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiList_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiList_Test.java
index 94fee985f3..38cdc5ffa5 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiList_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiList_Test.java
@@ -616,5 +616,196 @@ class MultiList_Test extends TestBase {
assertEquals(multiList.hashCode(), regularList.hashCode());
}
+
+
//====================================================================================================
+ // Additional coverage for specific lines
+
//====================================================================================================
+
+ @Test
+ void h01_iterator_hasNext_whenI2IsNull() {
+ // Line 258: return false when i2 == null
+ // This happens when MultiList is created with no lists
+ var ml = new MultiList<String>();
+ var it = ml.iterator();
+ assertFalse(it.hasNext()); // i2 is null, should return false
+ }
+
+ @Test
+ void h02_listIterator_hasNext_whenCurrentIteratorIsNull() {
+ // Line 356: return false when currentIterator == null
+ // This can happen in edge cases with empty lists
+ List<String> l1 = l(a());
+ List<String> l2 = l(a());
+ var ml = new MultiList<>(l1, l2);
+ var li = ml.listIterator(0); // Start at beginning of empty
lists
+ // After positioning, if all lists are empty, currentIterator
might be null
+ assertFalse(li.hasNext());
+ }
+
+ @Test
+ void h03_listIterator_hasNext_findsNextNonEmptyList() {
+ // Lines 359-360: Loop checking for next non-empty list
+ var l1 = l(a("1", "2"));
+ List<String> l2 = l(a()); // Empty list
+ var l3 = l(a("3", "4"));
+ var ml = new MultiList<>(l1, l2, l3);
+ var li = ml.listIterator();
+
+ // Exhaust first list
+ assertEquals("1", li.next());
+ assertEquals("2", li.next());
+ // Now currentIterator.hasNext() is false, but hasNext() should
find l3
+ assertTrue(li.hasNext()); // Should check remaining lists and
find l3
+ assertEquals("3", li.next());
+ }
+
+ @Test
+ void h04_listIterator_next_throwsWhenCurrentIteratorIsNull() {
+ // Line 368: throw NoSuchElementException when currentIterator
== null
+ // This is tricky to trigger, but can happen with edge cases
+ List<String> l1 = l(a());
+ var ml = new MultiList<>(l1);
+ var li = ml.listIterator(0);
+ // If we somehow get into a state where currentIterator is null
+ assertThrows(NoSuchElementException.class, li::next);
+ }
+
+ @Test
+ void h05_listIterator_next_throwsWhenExhausted() {
+ // Line 371: throw NoSuchElementException when no more elements
+ var l1 = l(a("1", "2"));
+ var l2 = l(a("3"));
+ var ml = new MultiList<>(l1, l2);
+ var li = ml.listIterator();
+
+ // Exhaust all elements
+ assertEquals("1", li.next());
+ assertEquals("2", li.next());
+ assertEquals("3", li.next());
+ // Now listIndex + 1 >= l.length, should throw
+ assertThrows(NoSuchElementException.class, li::next);
+ }
+
+ @Test
+ void h06_listIterator_hasPrevious_whenCurrentIteratorIsNull() {
+ // Line 382: return false when currentIterator == null
+ var l1 = l(a());
+ var ml = new MultiList<>(l1);
+ var li = ml.listIterator(0);
+ assertFalse(li.hasPrevious()); // currentIterator is null
+ }
+
+ @Test
+ void h07_listIterator_hasPrevious_findsPreviousList() {
+ // Line 387: return true when previous list has elements
+ var l1 = l(a("1", "2"));
+ List<String> l2 = l(a()); // Empty list
+ var l3 = l(a("3", "4"));
+ var ml = new MultiList<>(l1, l2, l3);
+ var li = ml.listIterator(ml.size()); // Start at end
+
+ // Move back through l3
+ assertEquals("4", li.previous());
+ assertEquals("3", li.previous());
+ // Now currentIterator.hasPrevious() is false, but
hasPrevious() should find l1
+ assertTrue(li.hasPrevious()); // Should check previous lists
and find l1
+ assertEquals("2", li.previous());
+ }
+
+ @Test
+ void h08_listIterator_remove_throwsWhenCurrentIteratorIsNull() {
+ // Line 418: throw IllegalStateException when currentIterator
== null
+ var l1 = l(a("1"));
+ var ml = new MultiList<>(l1);
+ var li = ml.listIterator();
+ // Remove without calling next/previous first
+ assertThrows(IllegalStateException.class, li::remove);
+ }
+
+ @Test
+ void h09_listIterator_set_throwsWhenCurrentIteratorIsNull() {
+ // Line 426: throw IllegalStateException when currentIterator
== null
+ var l1 = l(a("1"));
+ var ml = new MultiList<>(l1);
+ var li = ml.listIterator();
+ // Set without calling next/previous first
+ assertThrows(IllegalStateException.class, () -> li.set("x"));
+ }
+
+ @Test
+ void h10_listIterator_constructor_atEndWithNonEmptyLists() {
+ // Line 346: if (currentIterator == null && l.length > 0)
+ // This happens when index is at the end
+ var l1 = l(a("1", "2"));
+ var l2 = l(a("3", "4"));
+ var ml = new MultiList<>(l1, l2);
+ var li = ml.listIterator(ml.size()); // Index at end
+
+ // Should position at last list
+ assertTrue(li.hasPrevious());
+ assertEquals("4", li.previous());
+ }
+
+ @Test
+ void h11_equals_differentLengths() {
+ // Line 509: while (e1.hasNext() && e2.hasNext())
+ // Line 515: return !(e1.hasNext() || e2.hasNext());
+ // Test when lists have different lengths
+ var l1 = l(a("1", "2"));
+ var ml1 = new MultiList<>(l1);
+
+ var l2 = l(a("1", "2", "3"));
+ var ml2 = new MultiList<>(l2);
+
+ assertFalse(ml1.equals(ml2)); // Different lengths
+ assertFalse(ml2.equals(ml1));
+ }
+
+ @Test
+ void h12_equals_oneExhausted() {
+ // Test equals when one iterator is exhausted before the other
+ var l1 = l(a("1", "2"));
+ var ml1 = new MultiList<>(l1);
+
+ var l2 = l(a("1", "2", "3"));
+ var ml2 = new MultiList<>(l2);
+
+ // ml1 is shorter, so e1.hasNext() becomes false first
+ // Then we check e2.hasNext() which is true, so return false
+ assertFalse(ml1.equals(ml2));
+ }
+
+ @Test
+ void h13_hashCode_iteratesThroughAllElements() {
+ // Line 541: for (E e : this)
+ // Test that hashCode iterates through all elements
+ var l1 = l(a("1", "2"));
+ var l2 = l(a("3", "4"));
+ var ml = new MultiList<>(l1, l2);
+
+ // Calculate expected hashCode manually
+ int expectedHashCode = 1;
+ for (String e : ml) {
+ expectedHashCode = 31 * expectedHashCode + (e == null ?
0 : e.hashCode());
+ }
+
+ assertEquals(expectedHashCode, ml.hashCode());
+ }
+
+ @Test
+ void h14_hashCode_withNullElements() {
+ // Test hashCode with null elements
+ var l1 = l(a("1", null));
+ var l2 = l(a("2"));
+ var ml = new MultiList<>(l1, l2);
+
+ // Calculate expected hashCode manually (null contributes 0)
+ int expectedHashCode = 1;
+ expectedHashCode = 31 * expectedHashCode + "1".hashCode();
+ expectedHashCode = 31 * expectedHashCode + 0; // null
+ expectedHashCode = 31 * expectedHashCode + "2".hashCode();
+
+ assertEquals(expectedHashCode, ml.hashCode());
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiMap_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiMap_Test.java
index bf379f2263..0227a0e379 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiMap_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiMap_Test.java
@@ -513,5 +513,70 @@ class MultiMap_Test extends TestBase {
assertEquals(multiMap.hashCode(), regularMap.hashCode());
}
+
+
//====================================================================================================
+ // Additional coverage for specific lines
+
//====================================================================================================
+
+ @Test
+ void m01_entrySet_iterator_emptyMaps() {
+ // Line 218: if (m.length > 0) - when there are no maps
+ Map<String, String> map1 = map();
+ Map<String, String> map2 = map();
+ var multiMap = new MultiMap<>(map1, map2);
+ var iterator = multiMap.entrySet().iterator();
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ void m02_entrySet_iterator_next_throwsWhenNextEntryIsNull() {
+ // Line 253: throw NoSuchElementException when nextEntry == null
+ Map<String, String> map1 = map();
+ var multiMap = new MultiMap<>(map1);
+ var iterator = multiMap.entrySet().iterator();
+ assertThrows(NoSuchElementException.class, iterator::next);
+ }
+
+ @Test
+ void m03_entrySet_iterator_remove_throwsWhenCanRemoveIsFalse() {
+ // Line 264: throw IllegalStateException when canRemove is
false or lastIterator is null
+ var map1 = new LinkedHashMap<>(map("key1", "value1"));
+ var multiMap = new MultiMap<>(map1);
+ var iterator = multiMap.entrySet().iterator();
+ // Remove without calling next first
+ assertThrows(IllegalStateException.class, iterator::remove);
+ }
+
+ @Test
+ void m04_entrySet_iterator_remove_throwsWhenLastIteratorIsNull() {
+ // Line 264: throw IllegalStateException when lastIterator is
null
+ var map1 = new LinkedHashMap<>(map("key1", "value1"));
+ var multiMap = new MultiMap<>(map1);
+ var iterator = multiMap.entrySet().iterator();
+ iterator.next(); // Sets canRemove = true and lastIterator
+ iterator.remove(); // First remove works
+ // Now try to remove again without calling next
+ assertThrows(IllegalStateException.class, iterator::remove);
+ }
+
+ @Test
+ void m05_values_iterator_remove() {
+ // Lines 350-351: entryIterator.remove() in values iterator
+ // Test that remove() delegates to entryIterator.remove()
+ var map1 = new LinkedHashMap<>(map("key1", "value1"));
+ var multiMap = new MultiMap<>(map1);
+ var valuesIterator = multiMap.values().iterator();
+
+ // Get first value
+ assertEquals("value1", valuesIterator.next());
+
+ // Remove should work (delegates to entryIterator.remove()
which calls entrySet iterator remove)
+ // This covers lines 350-351
+ valuesIterator.remove();
+
+ // Verify the entry was removed from the underlying map
+ assertFalse(map1.containsKey("key1"));
+ assertTrue(map1.isEmpty());
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiSet_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiSet_Test.java
index 9dae3e02b6..aed9307575 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiSet_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/MultiSet_Test.java
@@ -306,5 +306,48 @@ class MultiSet_Test extends TestBase {
assertEquals(multiSet.hashCode(), regularSet.hashCode());
}
+
+
//====================================================================================================
+ // Additional coverage for specific lines
+
//====================================================================================================
+
+ @Test
+ void iterator_hasNext_whenI2IsNull() {
+ // Line 213: return false when i2 == null
+ // This happens when MultiSet is created with no collections
+ var ms = new MultiSet<String>();
+ var it = ms.iterator();
+ assertFalse(it.hasNext()); // i2 is null, should return false
+ }
+
+ @Test
+ void equals_notASet_otherTypes() {
+ // Line 308: return (o instanceof Set o2) && ...
+ // Test when object is not a Set (testing the instanceof check)
+ var l1 = l(a("1", "2"));
+ var multiSet = new MultiSet<>(l1);
+
+ // Not a Set - should return false immediately due to
instanceof check
+ assertFalse(multiSet.equals("not a set"));
+ assertFalse(multiSet.equals(123));
+ assertFalse(multiSet.equals(List.of("1", "2"))); // List is not
a Set
+ }
+
+ @Test
+ void hashCode_withNullElements() {
+ // Line 330: h += e == null ? 0 : e.hashCode()
+ // Test hashCode with null elements
+ var l1 = l(a("1", null));
+ var l2 = l(a("2"));
+ var multiSet = new MultiSet<>(l1, l2);
+
+ // Calculate expected hashCode manually (null contributes 0)
+ int expectedHashCode = 0;
+ expectedHashCode += "1".hashCode();
+ expectedHashCode += 0; // null
+ expectedHashCode += "2".hashCode();
+
+ assertEquals(expectedHashCode, multiSet.hashCode());
+ }
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Sets_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Sets_Test.java
index 528eb43e33..4d6db8e676 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Sets_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/Sets_Test.java
@@ -502,6 +502,8 @@ class Sets_Test extends TestBase {
@Test
void m10_addAny_noElementFunction_throwsException() {
+ // Test line 698: convertElement returns null when
elementFunction is null and element can't be converted
+ // This causes line 242 to throw an exception
// When elementFunction is null and we try to add a
non-matching type, it should throw
assertThrows(RuntimeException.class, () -> {
Sets.create(Integer.class)
@@ -650,4 +652,221 @@ class Sets_Test extends TestBase {
set.a("c").aa(l("d", "e"));
assertList(set, "a", "b", "c", "d", "e");
}
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // buildFiltered
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void q01_buildFiltered_returnsFilteredSet() {
+ var set = Sets.create(String.class)
+ .add("a", "b", "c")
+ .buildFiltered();
+
+ assertNotNull(set);
+ assertSize(3, set);
+ assertList(set, "a", "b", "c");
+ }
+
+ @Test
+ void q02_buildFiltered_sparseEmpty() {
+ var set = Sets.create(String.class)
+ .sparse()
+ .buildFiltered();
+
+ assertNull(set);
+ }
+
+ @Test
+ void q03_buildFiltered_withFiltering() {
+ var set = Sets.create(Integer.class)
+ .filtered(v -> v != null && v > 0)
+ .add(5, -1, 10, 0)
+ .buildFiltered();
+
+ assertNotNull(set);
+ assertList(set, 5, 10);
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // concurrent
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void r01_concurrent_createsSynchronizedSet() {
+ var set = Sets.create(String.class)
+ .add("a", "b", "c")
+ .concurrent()
+ .build();
+
+ assertNotNull(set);
+ assertSize(3, set);
+ }
+
+ @Test
+ void r02_concurrent_withSorted() {
+ var set = Sets.create(String.class)
+ .add("c", "a", "b")
+ .sorted()
+ .concurrent()
+ .build();
+
+ assertNotNull(set);
+ assertList(set, "a", "b", "c");
+ }
+
+ @Test
+ void r03_concurrent_withOrdered() {
+ var set = Sets.create(String.class)
+ .add("c", "a", "b")
+ .ordered()
+ .concurrent()
+ .build();
+
+ assertNotNull(set);
+ assertSize(3, set);
+ assertTrue(set.contains("a"));
+ assertTrue(set.contains("b"));
+ assertTrue(set.contains("c"));
+ // Order may not be preserved when concurrent is set, so we
just verify all elements are present
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // concurrent(boolean)
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void s01_concurrent_boolean_true() {
+ var set = Sets.create(String.class)
+ .add("a", "b", "c")
+ .concurrent(true)
+ .build();
+
+ assertNotNull(set);
+ assertSize(3, set);
+ }
+
+ @Test
+ void s02_concurrent_boolean_false() {
+ var set = Sets.create(String.class)
+ .add("a", "b", "c")
+ .concurrent(false)
+ .build();
+
+ assertNotNull(set);
+ assertSize(3, set);
+ // Should not be synchronized when false
+ }
+
+ @Test
+ void s03_concurrent_boolean_withSorted() {
+ var set = Sets.create(String.class)
+ .add("c", "a", "b")
+ .sorted()
+ .concurrent(true)
+ .build();
+
+ assertNotNull(set);
+ assertList(set, "a", "b", "c");
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // filtered
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void t01_filtered_defaultFiltering() {
+ var set = Sets.create(Object.class)
+ .filtered()
+ .add("a", null, false, -1, new String[0], l(), m())
+ .build();
+
+ assertList(set, "a");
+ }
+
+ @Test
+ void t02_filtered_withBooleanFalse() {
+ var set = Sets.create(Boolean.class)
+ .filtered()
+ .add(true, false, true)
+ .build();
+
+ assertList(set, true);
+ }
+
+ @Test
+ void t03_filtered_withNumberMinusOne() {
+ var set = Sets.create(Integer.class)
+ .filtered()
+ .add(1, -1, 2, -1, 3)
+ .build();
+
+ assertList(set, 1, 2, 3);
+ }
+
+ @Test
+ void t04_filtered_withEmptyArray() {
+ var set = Sets.create(Object.class)
+ .filtered()
+ .add("a", new String[0], "b")
+ .build();
+
+ assertList(set, "a", "b");
+ }
+
+ @Test
+ void t05_filtered_withEmptyMap() {
+ var set = Sets.create(Object.class)
+ .filtered()
+ .add("a", m(), "b")
+ .build();
+
+ assertList(set, "a", "b");
+ }
+
+ @Test
+ void t06_filtered_withEmptyCollection() {
+ var set = Sets.create(Object.class)
+ .filtered()
+ .add("a", l(), "b")
+ .build();
+
+ assertList(set, "a", "b");
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // filtered(Predicate)
+
//-----------------------------------------------------------------------------------------------------------------
+
+ @Test
+ void u01_filtered_withPredicate() {
+ var set = Sets.create(Integer.class)
+ .filtered(v -> v != null && v > 0)
+ .add(5, -1, 10, 0, 15)
+ .build();
+
+ assertList(set, 5, 10, 15);
+ }
+
+ @Test
+ void u02_filtered_multipleFilters() {
+ var set = Sets.create(Integer.class)
+ .filtered(v -> v != null)
+ .filtered(v -> v > 0)
+ .filtered(v -> v < 100)
+ .add(5, -1, 150, 0, 50, null)
+ .build();
+
+ assertList(set, 5, 50);
+ }
+
+ @Test
+ void u03_filtered_withStringPredicate() {
+ var set = Sets.create(String.class)
+ .filtered(s -> s != null && s.length() > 2)
+ .add("a", "ab", "abc", "abcd", "")
+ .build();
+
+ assertList(set, "abc", "abcd");
+ }
}
\ No newline at end of file