From 70ffcbd72a65c19429832663d438532f29371199 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sun, 19 Apr 2026 14:53:51 -0400 Subject: [PATCH 1/4] Scaffold the AbstractRichIterableAssert and two beginning concrete types. --- .../api/AbstractRichIterableAssert.java | 75 +++++++++++++++++++ .../eclipse/collections/api/Assertions.java | 19 ++++- .../collections/api/BDDAssertions.java | 26 ++++++- .../eclipse/collections/api/BagAssert.java | 38 ++++++++++ ...ipseCollectionsSoftAssertionsProvider.java | 22 +++++- .../collections/api/SetIterableAssert.java | 38 ++++++++++ src/test/java/module-info.java | 2 + .../api/bag/BagAssert_HasSize_Test.java | 58 ++++++++++++++ .../MultimapAssert_IsNullOrEmpty_Test.java | 2 +- .../api/set/SetAssert_HasSize_Test.java | 58 ++++++++++++++ 10 files changed, 334 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java create mode 100644 src/main/java/org/assertj/eclipse/collections/api/BagAssert.java create mode 100644 src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java diff --git a/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java new file mode 100644 index 0000000..f3c5ed5 --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java @@ -0,0 +1,75 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api; + +import static org.assertj.core.error.ShouldHaveSize.shouldHaveSize; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.AbstractIterableAssert; +import org.eclipse.collections.api.RichIterable; + +/** + * Base class for implementations of Eclipse Collections {@link RichIterable} assertions. + * + * @param the "self" type of this assertion class. Please read "Emulating 'self types' using Java Generics to simplify fluent API implementation" + * for more details. + * @param the type of the "actual" value. + * @param the type of elements of the "actual" value. + * @param used for navigational assertions to return the right assert type. + */ +//@format:off +public abstract class AbstractRichIterableAssert, + ACTUAL extends RichIterable, + ELEMENT, + ELEMENT_ASSERT extends AbstractAssert> + extends AbstractIterableAssert { +//@format:on + + protected AbstractRichIterableAssert(ACTUAL actual, Class selfType) { + super(actual, selfType); + } + + /** + * Verifies that the number of values in the actual RichIterable is equal to the given one. + *

+ * Example: + *

{@code
+   * // assertions will pass
+   * assertThat(Sets.immutable.of("TNG", "DS9")).hasSize(2);
+   * assertThat(Bags.immutable.of(1, 2, 3)).hasSize(3);
+   *
+   * // assertions will fail
+   * assertThat(Sets.immutable.empty()).hasSize(1);
+   * assertThat(Bags.immutable.of(1, 2, 3)).hasSize(2);
+   * }
+ * + * @param expected the expected number of values in the actual collection. + * @return {@code this} assertion object. + * @throws AssertionError if the number of values of the actual collection is not equal to the given one. + */ + @Override + public SELF hasSize(int expected) { + isNotNull(); + + int actualSize = actual.size(); + if (actualSize == expected) { + return myself; + } + + throw assertionError(shouldHaveSize(actual, actualSize, expected)); + } +} diff --git a/src/main/java/org/assertj/eclipse/collections/api/Assertions.java b/src/main/java/org/assertj/eclipse/collections/api/Assertions.java index 42c7d79..4535b17 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/Assertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/Assertions.java @@ -15,8 +15,10 @@ */ package org.assertj.eclipse.collections.api; -import org.assertj.core.util.CheckReturnValue; +import org.assertj.core.annotation.CheckReturnValue; +import org.eclipse.collections.api.bag.Bag; import org.eclipse.collections.api.multimap.Multimap; +import org.eclipse.collections.api.set.SetIterable; /** * Entry point for assertion methods for the Eclipse Collections library. Each method in this class is a static factory @@ -31,6 +33,10 @@ protected Assertions() { // Do nothing } + public static BagAssert assertThat(Bag actual) { + return new BagAssert<>(actual); + } + /** * Creates a new instance of {@link MultimapAssert}. * @@ -42,4 +48,15 @@ protected Assertions() { public static MultimapAssert assertThat(Multimap actual) { return new MultimapAssert<>(actual); } + + /** + * Creates a new instance of {@link SetIterableAssert}. + * + * @param actual the actual value. + * @return the created assertion object. + * @param The type of the elements in the set + */ + public static SetIterableAssert assertThat(SetIterable actual) { + return new SetIterableAssert<>(actual); + } } diff --git a/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java b/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java index f269f74..4b43b1b 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java @@ -15,8 +15,10 @@ */ package org.assertj.eclipse.collections.api; -import org.assertj.core.util.CheckReturnValue; +import org.assertj.core.annotation.CheckReturnValue; +import org.eclipse.collections.api.bag.Bag; import org.eclipse.collections.api.multimap.Multimap; +import org.eclipse.collections.api.set.SetIterable; /** * Behavior-driven development style entry point for assertion methods for the Eclipse Collections library. Each method @@ -31,6 +33,17 @@ protected BDDAssertions() { // Do nothing } + /** + * Creates a new instance of {@link BagAssert}. + * + * @param actual the actual value. + * @return thre created assertion object. + * @param THe type of the elements in the bag + */ + public static BagAssert then(Bag actual) { + return assertThat(actual); + } + /** * Creates a new instance of {@link MultimapAssert}. * @@ -42,4 +55,15 @@ protected BDDAssertions() { public static MultimapAssert then(Multimap actual) { return assertThat(actual); } + + /** + * Creates a new instance of {@link SetIterableAssert}. + * + * @param actual the actual value. + * @return the created assertion object. + * @param The type of the elements in the set + */ + public static SetIterableAssert then(SetIterable actual) { + return assertThat(actual); + } } diff --git a/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java b/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java new file mode 100644 index 0000000..da0d17f --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java @@ -0,0 +1,38 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api; + +import org.assertj.core.api.ObjectAssert; +import org.eclipse.collections.api.bag.Bag; +import org.eclipse.collections.api.bag.ImmutableBag; +import org.eclipse.collections.api.factory.Bags; + +public class BagAssert extends AbstractRichIterableAssert, Bag, ELEMENT, ObjectAssert> { + public BagAssert(Bag elements) { + super(elements, BagAssert.class); + } + + @Override + protected ObjectAssert toAssert(ELEMENT value) { + return new ObjectAssert<>(value); + } + + @Override + protected BagAssert newAbstractIterableAssert(Iterable iterable) { + ImmutableBag elements = Bags.immutable.ofAll(iterable); + return new BagAssert<>(elements); + } +} diff --git a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java index cc830ed..b2fc400 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java +++ b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java @@ -15,15 +15,30 @@ */ package org.assertj.eclipse.collections.api; +import org.assertj.core.annotation.CheckReturnValue; import org.assertj.core.api.SoftAssertionsProvider; -import org.assertj.core.util.CheckReturnValue; +import org.eclipse.collections.api.bag.Bag; import org.eclipse.collections.api.multimap.Multimap; +import org.eclipse.collections.api.set.SetIterable; /** * Soft assertions implementations for Eclipse Collections types. */ @CheckReturnValue public interface EclipseCollectionsSoftAssertionsProvider extends SoftAssertionsProvider { + + /** + * Create a new, proxied instance of a {@link BagAssert} + * + * @param actual the actual value + * @return the created assertion object + * @param The type of the elements in the bag + */ + @SuppressWarnings("unchecked") + default BagAssert assertThat(Bag actual) { + return this.proxy(BagAssert.class, Bag.class, actual); + } + /** * Creates a new, proxied instance of a {@link MultimapAssert} * @@ -36,4 +51,9 @@ public interface EclipseCollectionsSoftAssertionsProvider extends SoftAssertions default MultimapAssert assertThat(Multimap actual) { return this.proxy(MultimapAssert.class, Multimap.class, actual); } + + @SuppressWarnings("unchecked") + default SetIterableAssert assertThat(SetIterable actual) { + return this.proxy(SetIterableAssert.class, SetIterable.class, actual); + } } diff --git a/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java new file mode 100644 index 0000000..0651e10 --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java @@ -0,0 +1,38 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api; + +import org.assertj.core.api.ObjectAssert; +import org.eclipse.collections.api.factory.Sets; +import org.eclipse.collections.api.set.ImmutableSet; +import org.eclipse.collections.api.set.SetIterable; + +public class SetIterableAssert extends AbstractRichIterableAssert, SetIterable, ELEMENT, ObjectAssert> { + public SetIterableAssert(SetIterable elements) { + super(elements, SetIterableAssert.class); + } + + @Override + protected ObjectAssert toAssert(ELEMENT value) { + return new ObjectAssert<>(value); + } + + @Override + protected SetIterableAssert newAbstractIterableAssert(Iterable iterable) { + ImmutableSet elements = Sets.immutable.ofAll(iterable); + return new SetIterableAssert<>(elements); + } +} diff --git a/src/test/java/module-info.java b/src/test/java/module-info.java index cf08280..72338a6 100644 --- a/src/test/java/module-info.java +++ b/src/test/java/module-info.java @@ -17,7 +17,9 @@ * Test module for AssertJ Eclipse Collections */ open module org.assertj.eclipse.collections.test { + exports org.assertj.eclipse.collections.api.bag; exports org.assertj.eclipse.collections.api.multimap; + exports org.assertj.eclipse.collections.api.set; requires org.assertj.eclipse.collections; requires org.assertj.core; diff --git a/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java b/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java new file mode 100644 index 0000000..afb3d16 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java @@ -0,0 +1,58 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api.bag; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.eclipse.collections.api.BagAssert; +import org.assertj.eclipse.collections.api.SoftAssertions; +import org.eclipse.collections.api.bag.ImmutableBag; +import org.eclipse.collections.api.factory.Bags; +import org.junit.jupiter.api.Test; + +public class BagAssert_HasSize_Test { + @Test + void passes() { + ImmutableBag bag = createBag(); + assertThatNoException().isThrownBy(() -> new BagAssert<>(bag).hasSize(5)); + } + + @Test + void failsEmpty() { + ImmutableBag bag = Bags.immutable.empty(); + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> new BagAssert<>(bag).hasSize(5)) + .withMessageContaining(String.format("Expected size: %s but was: 0", 5)); + } + + @Test + void failsNullMultimap() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> new BagAssert<>(null).hasSize(5)) + .withMessageContaining("Expecting actual not to be null"); + } + + @Test + void softAssertionPasses() { + ImmutableBag bag = createBag(); + SoftAssertions.assertSoftly(softly -> softly.assertThat(bag).hasSize(5)); + } + + private static ImmutableBag createBag() { + return Bags.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/multimap/MultimapAssert_IsNullOrEmpty_Test.java b/src/test/java/org/assertj/eclipse/collections/api/multimap/MultimapAssert_IsNullOrEmpty_Test.java index c8ca533..d65de97 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/multimap/MultimapAssert_IsNullOrEmpty_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/multimap/MultimapAssert_IsNullOrEmpty_Test.java @@ -54,6 +54,6 @@ void softAssertionPassesEmpty(Multimap actual) { @Test void softAssertionPassesNullMultimap() { - assertThatNoException().isThrownBy(() -> SoftAssertions.assertSoftly(softly -> softly.assertThat(null).isNullOrEmpty())); + assertThatNoException().isThrownBy(() -> SoftAssertions.assertSoftly(softly -> softly.assertThat((Multimap) null).isNullOrEmpty())); } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java b/src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java new file mode 100644 index 0000000..11cd372 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java @@ -0,0 +1,58 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api.set; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.eclipse.collections.api.SetIterableAssert; +import org.assertj.eclipse.collections.api.SoftAssertions; +import org.eclipse.collections.api.factory.Sets; +import org.eclipse.collections.api.set.ImmutableSet; +import org.junit.jupiter.api.Test; + +public class SetAssert_HasSize_Test { + @Test + void passes() { + ImmutableSet set = createSet(); + assertThatNoException().isThrownBy(() -> new SetIterableAssert<>(set).hasSize(5)); + } + + @Test + void failsEmpty() { + ImmutableSet set = Sets.immutable.empty(); + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> new SetIterableAssert<>(set).hasSize(5)) + .withMessageContaining(String.format("Expected size: %s but was: 0", 5)); + } + + @Test + void failsNullInput() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> new SetIterableAssert<>(null).hasSize(5)) + .withMessageContaining("Expecting actual not to be null"); + } + + @Test + void softAssertionPasses() { + ImmutableSet set = createSet(); + SoftAssertions.assertSoftly(softly -> softly.assertThat(set).hasSize(5)); + } + + private static ImmutableSet createSet() { + return Sets.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + } +} From d6a56776484aaa3af91a7022a8d7948e1b3cfa9b Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sun, 19 Apr 2026 14:54:56 -0400 Subject: [PATCH 2/4] Rename misnamed class --- ...rt_HasSize_Test.java => SetIterableAssert_HasSize_Test.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/test/java/org/assertj/eclipse/collections/api/set/{SetAssert_HasSize_Test.java => SetIterableAssert_HasSize_Test.java} (97%) diff --git a/src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java b/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java similarity index 97% rename from src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java rename to src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java index 11cd372..043605d 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/set/SetAssert_HasSize_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java @@ -24,7 +24,7 @@ import org.eclipse.collections.api.set.ImmutableSet; import org.junit.jupiter.api.Test; -public class SetAssert_HasSize_Test { +public class SetIterableAssert_HasSize_Test { @Test void passes() { ImmutableSet set = createSet(); From 27ca6101e6c165e7138de399cc184f8b732d6a5b Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sun, 19 Apr 2026 17:54:40 -0400 Subject: [PATCH 3/4] Get filteredOn methods in place --- .../api/AbstractRichIterableAssert.java | 48 ++++++++++++++ .../api/bag/BagAssert_FilteredOn_Test.java | 65 +++++++++++++++++++ .../SetIterableAssert_FilteredOn_Test.java | 65 +++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java diff --git a/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java index f3c5ed5..a7aef79 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java +++ b/src/main/java/org/assertj/eclipse/collections/api/AbstractRichIterableAssert.java @@ -16,6 +16,11 @@ package org.assertj.eclipse.collections.api; import static org.assertj.core.error.ShouldHaveSize.shouldHaveSize; +import static org.assertj.core.util.Preconditions.checkArgument; + +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; import org.assertj.core.api.AbstractAssert; import org.assertj.core.api.AbstractIterableAssert; @@ -43,6 +48,36 @@ protected AbstractRichIterableAssert(ACTUAL actual, Class selfType) { super(actual, selfType); } + @Override + public SELF filteredOn(Function function, T expectedValue) { + checkArgument(function != null, "The filter function should not be null"); + return internalFilteredOn(element -> Objects.equals(function.apply(element), expectedValue)); + } + + /** + * Filters the iterable under test keeping only elements matching the given {@link Predicate}. + *

+ * Example: check old employees whose age > 100: + * + *

 Employee yoda   = new Employee(1L, new Name("Yoda"), 800);
+   * Employee obiwan = new Employee(2L, new Name("Obiwan"), 800);
+   * Employee luke   = new Employee(3L, new Name("Luke", "Skywalker"), 26);
+   *
+   * List<Employee> employees = List.of(yoda, luke, obiwan);
+   *
+   * assertThat(employees).filteredOn(employee -> employee.getAge() > 100)
+   *                      .containsOnly(yoda, obiwan);
+ * + * @param predicate the filter predicate + * @return a new assertion object with the filtered iterable under test + * @throws IllegalArgumentException if the given predicate is {@code null}. + */ + @Override + public SELF filteredOn(Predicate predicate) { + checkArgument(predicate != null, "The filter predicate should not be null"); + return internalFilteredOn(predicate::test); + } + /** * Verifies that the number of values in the actual RichIterable is equal to the given one. *

@@ -72,4 +107,17 @@ public SELF hasSize(int expected) { throw assertionError(shouldHaveSize(actual, actualSize, expected)); } + + /** + * Helper method that filters via Eclipse Collections to avoid creating any JCL collections. + * + * @param predicate The predicate to filter on. + * @return A new {@link AbstractRichIterableAssert} with the filtered values. + */ + private SELF internalFilteredOn(org.eclipse.collections.api.block.predicate.Predicate predicate) { + checkArgument(predicate != null, "The filter predicate should not be null"); + // TODO: In AbstractIterableAssert the withAssertionState method is package-private. Need to find out how to handle + // this method or if we need to use it + return newAbstractIterableAssert(actual.select(predicate));//.withAssertionState(myself); + } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java b/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java new file mode 100644 index 0000000..c73990a --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java @@ -0,0 +1,65 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api.bag; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import java.util.function.Function; +import java.util.function.Predicate; + +import org.assertj.eclipse.collections.api.BagAssert; +import org.eclipse.collections.api.bag.ImmutableBag; +import org.eclipse.collections.api.factory.Bags; +import org.junit.jupiter.api.Test; + +public class BagAssert_FilteredOn_Test { + @Test + void filteredOn_function_passes() { + ImmutableBag bag = Bags.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatNoException().isThrownBy(() -> new BagAssert<>(bag).filteredOn(s -> s.charAt(0), 'T') + .hasSize(2) + .containsOnly("TOS", "TNG")); + } + + @Test + void filteredOn_function_nullFunction_throwsException() { + ImmutableBag bag = Bags.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new BagAssert<>(bag).filteredOn((Function) null, 'T')) + .withMessageContaining("The filter function should not be null"); + } + + @Test + void filteredOn_predicate_passes() { + ImmutableBag bag = Bags.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatNoException().isThrownBy(() -> new BagAssert<>(bag).filteredOn(s -> s.startsWith("T")) + .hasSize(2) + .containsOnly("TOS", "TNG")); + } + + @Test + void filteredOn_predicate_nullPredicate_throwsException() { + ImmutableBag bag = Bags.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new BagAssert<>(bag).filteredOn((Predicate) null)) + .withMessageContaining("The filter predicate should not be null"); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java b/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java new file mode 100644 index 0000000..a8d18ca --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java @@ -0,0 +1,65 @@ +/* + * Copyright 2025-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.assertj.eclipse.collections.api.set; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import java.util.function.Function; +import java.util.function.Predicate; + +import org.assertj.eclipse.collections.api.SetIterableAssert; +import org.eclipse.collections.api.factory.Sets; +import org.eclipse.collections.api.set.ImmutableSet; +import org.junit.jupiter.api.Test; + +public class SetIterableAssert_FilteredOn_Test { + @Test + void filteredOn_function_passes() { + ImmutableSet set = Sets.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatNoException().isThrownBy(() -> new SetIterableAssert<>(set).filteredOn(s -> s.charAt(0), 'T') + .hasSize(2) + .containsOnly("TOS", "TNG")); + } + + @Test + void filteredOn_function_nullFunction_throwsException() { + ImmutableSet set = Sets.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new SetIterableAssert<>(set).filteredOn((Function) null, 'T')) + .withMessageContaining("The filter function should not be null"); + } + + @Test + void filteredOn_predicate_passes() { + ImmutableSet set = Sets.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatNoException().isThrownBy(() -> new SetIterableAssert<>(set).filteredOn(s -> s.startsWith("T")) + .hasSize(2) + .containsOnly("TOS", "TNG")); + } + + @Test + void filteredOn_predicate_nullPredicate_throwsException() { + ImmutableSet set = Sets.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new SetIterableAssert<>(set).filteredOn((Predicate) null)) + .withMessageContaining("The filter predicate should not be null"); + } +} From 604a2a74e91d027ea11c79a45fc1825eb95476b8 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Mon, 20 Apr 2026 07:06:33 -0400 Subject: [PATCH 4/4] More javadoc --- .../org/assertj/eclipse/collections/api/Assertions.java | 7 +++++++ .../org/assertj/eclipse/collections/api/BagAssert.java | 5 +++++ .../api/EclipseCollectionsSoftAssertionsProvider.java | 7 +++++++ .../assertj/eclipse/collections/api/SetIterableAssert.java | 5 +++++ 4 files changed, 24 insertions(+) diff --git a/src/main/java/org/assertj/eclipse/collections/api/Assertions.java b/src/main/java/org/assertj/eclipse/collections/api/Assertions.java index 4535b17..58bcdd2 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/Assertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/Assertions.java @@ -33,6 +33,13 @@ protected Assertions() { // Do nothing } + /** + * Creates a new instance of {@link BagAssert}. + * + * @param actual the actual value. + * @return the created assertion object. + * @param The type of the elements in the bag + */ public static BagAssert assertThat(Bag actual) { return new BagAssert<>(actual); } diff --git a/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java b/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java index da0d17f..09e72c1 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java +++ b/src/main/java/org/assertj/eclipse/collections/api/BagAssert.java @@ -20,6 +20,11 @@ import org.eclipse.collections.api.bag.ImmutableBag; import org.eclipse.collections.api.factory.Bags; +/** + * Assertion methods for the {@link Bag} interface. + * + * @param the type of elements stored in {@link Bag}. + */ public class BagAssert extends AbstractRichIterableAssert, Bag, ELEMENT, ObjectAssert> { public BagAssert(Bag elements) { super(elements, BagAssert.class); diff --git a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java index b2fc400..9e6e8ae 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java +++ b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java @@ -52,6 +52,13 @@ default MultimapAssert assertThat(Multimap return this.proxy(MultimapAssert.class, Multimap.class, actual); } + /** + * Creates a new, proxied instance of a {@link SetIterableAssert} + * + * @param actual the actual value + * @return the created assertion object + * @param The type of the elements in the set + */ @SuppressWarnings("unchecked") default SetIterableAssert assertThat(SetIterable actual) { return this.proxy(SetIterableAssert.class, SetIterable.class, actual); diff --git a/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java index 0651e10..403d502 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java +++ b/src/main/java/org/assertj/eclipse/collections/api/SetIterableAssert.java @@ -20,6 +20,11 @@ import org.eclipse.collections.api.set.ImmutableSet; import org.eclipse.collections.api.set.SetIterable; +/** + * Assertion methods for {@link SetIterable} interface. + * + * @param the type of elements stored in {@link SetIterable}. + */ public class SetIterableAssert extends AbstractRichIterableAssert, SetIterable, ELEMENT, ObjectAssert> { public SetIterableAssert(SetIterable elements) { super(elements, SetIterableAssert.class);