From e6de04c638e03d0e2e754f9b0397401e1450d810 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Fri, 22 May 2026 15:53:40 -0400 Subject: [PATCH 1/8] Introduce AbstractOrderedIterableAssert and the corresponding ListIterable and StackIterable assertion types. Overhauling how RichIterable tests are parameterized. --- .../api/AbstractOrderedIterableAssert.java | 70 +++++++++++++++ .../eclipse/collections/api/Assertions.java | 12 ++- .../collections/api/BDDAssertions.java | 10 +++ ...ipseCollectionsSoftAssertionsProvider.java | 12 +++ .../collections/api/ListIterableAssert.java | 63 ++++++++++++++ .../collections/api/StackIterableAssert.java | 40 +++++++++ src/test/java/module-info.java | 3 +- ...ctRichIterableAssert_FilteredOn_Test.java} | 41 +++------ ...tractRichIterableAssert_HasSize_Test.java} | 41 ++++----- .../RichIterableArgumentsProvider.java | 85 +++++++++++++++++++ .../RichIterableAssertFactory.java | 67 +++++++++++++++ .../RichIterableParameterizedTest.java | 31 +++++++ .../SetIterableAssert_FilteredOn_Test.java | 65 -------------- .../set/SetIterableAssert_HasSize_Test.java | 58 ------------- 14 files changed, 420 insertions(+), 178 deletions(-) create mode 100644 src/main/java/org/assertj/eclipse/collections/api/AbstractOrderedIterableAssert.java create mode 100644 src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java create mode 100644 src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java rename src/test/java/org/assertj/eclipse/collections/api/{bag/BagAssert_FilteredOn_Test.java => richiterable/AbstractRichIterableAssert_FilteredOn_Test.java} (50%) rename src/test/java/org/assertj/eclipse/collections/api/{bag/BagAssert_HasSize_Test.java => richiterable/AbstractRichIterableAssert_HasSize_Test.java} (53%) create mode 100644 src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableArgumentsProvider.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableAssertFactory.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableParameterizedTest.java delete mode 100644 src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java delete mode 100644 src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java diff --git a/src/main/java/org/assertj/eclipse/collections/api/AbstractOrderedIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/AbstractOrderedIterableAssert.java new file mode 100644 index 0000000..65ee63e --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/AbstractOrderedIterableAssert.java @@ -0,0 +1,70 @@ +/* + * 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.AbstractAssert; +import org.assertj.core.api.InstanceOfAssertFactory; +import org.eclipse.collections.api.ordered.OrderedIterable; + +//@format:off +public abstract class AbstractOrderedIterableAssert, + ACTUAL extends OrderedIterable, + ELEMENT, + ELEMENT_ASSERT extends AbstractAssert> + extends AbstractRichIterableAssert { +//@format:on + + protected AbstractOrderedIterableAssert(ACTUAL actual, Class selfType) { + super(actual, selfType); + } + + @Override + public ELEMENT_ASSERT first() { + return executeAssertionNavigation(this::internalFirst, () -> nullElementNavigationAssert("check first element")); + } + + @Override + public > ASSERT first(InstanceOfAssertFactory assertFactory) { + return executeAssertionNavigation(() -> internalFirst().asInstanceOf(assertFactory), + () -> nullValueAssert(assertFactory)); + } + + @Override + public ELEMENT_ASSERT last() { + return executeAssertionNavigation(this::internalLast, () -> nullElementNavigationAssert("check last element")); + } + + @Override + public > ASSERT last(InstanceOfAssertFactory assertFactory) { + return executeAssertionNavigation(() -> internalLast().asInstanceOf(assertFactory), + () -> nullValueAssert(assertFactory)); + } + + private ELEMENT_ASSERT internalFirst() { + isNotEmpty(); + return toAssert(actual.getFirst(), navigationDescription("check first element")); + } + + private ELEMENT_ASSERT internalLast() { + isNotEmpty(); + return toAssert(actual.getLast(), navigationDescription("check last element")); + } + + // TODO: Decide where this method should live: here, in AbstractRichIterableAssert, or somewhere else + protected ELEMENT_ASSERT nullElementNavigationAssert(String description) { + return toAssert(null, navigationDescription(description)); + } +} 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 58bcdd2..086c37e 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/Assertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/Assertions.java @@ -17,8 +17,10 @@ import org.assertj.core.annotation.CheckReturnValue; import org.eclipse.collections.api.bag.Bag; +import org.eclipse.collections.api.list.ListIterable; import org.eclipse.collections.api.multimap.Multimap; import org.eclipse.collections.api.set.SetIterable; +import org.eclipse.collections.api.stack.StackIterable; /** * Entry point for assertion methods for the Eclipse Collections library. Each method in this class is a static factory @@ -44,6 +46,10 @@ public static BagAssert assertThat(Bag actual) { return new BagAssert<>(actual); } + public static ListIterableAssert assertThat(ListIterable actual) { + return new ListIterableAssert<>(actual); + } + /** * Creates a new instance of {@link MultimapAssert}. * @@ -63,7 +69,11 @@ public static MultimapAssert assertThat(Multimap The type of the elements in the set */ - public static SetIterableAssert assertThat(SetIterable actual) { + public static SetIterableAssert assertThat(SetIterable actual) { return new SetIterableAssert<>(actual); } + + public static StackIterableAssert assertThat(StackIterable actual) { + return new StackIterableAssert<>(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 4b43b1b..42fc66e 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java @@ -17,8 +17,10 @@ import org.assertj.core.annotation.CheckReturnValue; import org.eclipse.collections.api.bag.Bag; +import org.eclipse.collections.api.list.ListIterable; import org.eclipse.collections.api.multimap.Multimap; import org.eclipse.collections.api.set.SetIterable; +import org.eclipse.collections.api.stack.StackIterable; /** * Behavior-driven development style entry point for assertion methods for the Eclipse Collections library. Each method @@ -44,6 +46,10 @@ public static BagAssert then(Bag actual) { return assertThat(actual); } + public static ListIterableAssert then(ListIterable actual) { + return assertThat(actual); + } + /** * Creates a new instance of {@link MultimapAssert}. * @@ -66,4 +72,8 @@ public static MultimapAssert then(Multimap public static SetIterableAssert then(SetIterable actual) { return assertThat(actual); } + + public static StackIterableAssert then(StackIterable actual) { + return assertThat(actual); + } } 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 9e6e8ae..970be4e 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java +++ b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java @@ -18,8 +18,10 @@ import org.assertj.core.annotation.CheckReturnValue; import org.assertj.core.api.SoftAssertionsProvider; import org.eclipse.collections.api.bag.Bag; +import org.eclipse.collections.api.list.ListIterable; import org.eclipse.collections.api.multimap.Multimap; import org.eclipse.collections.api.set.SetIterable; +import org.eclipse.collections.api.stack.StackIterable; /** * Soft assertions implementations for Eclipse Collections types. @@ -39,6 +41,11 @@ default BagAssert assertThat(Bag actual) { return this.proxy(BagAssert.class, Bag.class, actual); } + @SuppressWarnings("unchecked") + default ListIterableAssert assertThat(ListIterable actual) { + return this.proxy(ListIterableAssert.class, ListIterable.class, actual); + } + /** * Creates a new, proxied instance of a {@link MultimapAssert} * @@ -63,4 +70,9 @@ default MultimapAssert assertThat(Multimap default SetIterableAssert assertThat(SetIterable actual) { return this.proxy(SetIterableAssert.class, SetIterable.class, actual); } + + @SuppressWarnings("unchecked") + default StackIterableAssert assertThat(StackIterable actual) { + return this.proxy(StackIterableAssert.class, StackIterable.class, actual); + } } diff --git a/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java new file mode 100644 index 0000000..b99613b --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java @@ -0,0 +1,63 @@ +/* + * 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.api.Assertions.assertThat; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.InstanceOfAssertFactory; +import org.assertj.core.api.ObjectAssert; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.eclipse.collections.api.list.ListIterable; + +public class ListIterableAssert extends AbstractOrderedIterableAssert, ListIterable, ELEMENT, ObjectAssert> { + public ListIterableAssert(ListIterable actual) { + super(actual, ListIterableAssert.class); + } + + @Override + protected ObjectAssert toAssert(ELEMENT value) { + return new ObjectAssert<>(value); + } + + @Override + protected ListIterableAssert newAbstractIterableAssert(Iterable iterable) { + ImmutableList elements = Lists.immutable.ofAll(iterable); + return new ListIterableAssert<>(elements); + } + + @Override + public ObjectAssert element(int index) { + return executeAssertionNavigation(() -> internalElement(index), + () -> nullElementNavigationAssert("element at index " + index)); + } + + @Override + public > ASSERT element(int index, InstanceOfAssertFactory assertFactory) { + return executeAssertionNavigation(() -> internalElement(index).asInstanceOf(assertFactory), + () -> nullValueAssert(assertFactory)); + } + + private ObjectAssert internalElement(int index) { + isNotEmpty(); + assertThat(index).describedAs(navigationDescription("check index validity")) + .isBetween(0, actual.size() - 1); + ELEMENT elementAtIndex = actual.get(index); + + return toAssert(elementAtIndex, navigationDescription("element at index " + index)); + } +} diff --git a/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java new file mode 100644 index 0000000..7e37a93 --- /dev/null +++ b/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java @@ -0,0 +1,40 @@ +/* + * 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.annotation.CheckReturnValue; +import org.assertj.core.api.ObjectAssert; +import org.eclipse.collections.api.factory.Stacks; +import org.eclipse.collections.api.stack.ImmutableStack; +import org.eclipse.collections.api.stack.StackIterable; + +@CheckReturnValue +public class StackIterableAssert extends AbstractOrderedIterableAssert, StackIterable, ELEMENT, ObjectAssert> { + public StackIterableAssert(StackIterable actual) { + super(actual, StackIterableAssert.class); + } + + @Override + protected ObjectAssert toAssert(ELEMENT value) { + return new ObjectAssert<>(value); + } + + @Override + protected StackIterableAssert newAbstractIterableAssert(Iterable iterable) { + ImmutableStack elements = Stacks.immutable.ofAll(iterable); + return new StackIterableAssert<>(elements); + } +} diff --git a/src/test/java/module-info.java b/src/test/java/module-info.java index 72338a6..58dec8e 100644 --- a/src/test/java/module-info.java +++ b/src/test/java/module-info.java @@ -17,9 +17,8 @@ * 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; + exports org.assertj.eclipse.collections.api.richiterable; requires org.assertj.eclipse.collections; requires org.assertj.core; 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/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java similarity index 50% rename from src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java rename to src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java index c73990a..aa531e6 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_FilteredOn_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.assertj.eclipse.collections.api.bag; +package org.assertj.eclipse.collections.api.richiterable; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatNoException; @@ -21,45 +21,32 @@ 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') +public class AbstractRichIterableAssert_FilteredOn_Test { + @RichIterableParameterizedTest + void filteredOn_function_passes(RichIterableAssertFactory assertFactory) { + assertThatNoException().isThrownBy(() -> assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").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"); - + @RichIterableParameterizedTest + void filteredOn_function_nullFunction_throwsException(RichIterableAssertFactory assertFactory) { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> new BagAssert<>(bag).filteredOn((Function) null, 'T')) + .isThrownBy(() -> assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").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")) + @RichIterableParameterizedTest + void filteredOn_predicate_passes(RichIterableAssertFactory assertFactory) { + assertThatNoException().isThrownBy(() -> assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").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"); - + @RichIterableParameterizedTest + void filteredOn_predicate_nullPredicate_throwsException(RichIterableAssertFactory assertFactory) { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> new BagAssert<>(bag).filteredOn((Predicate) null)) + .isThrownBy(() -> assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").filteredOn((Predicate) null)) .withMessageContaining("The filter predicate should not be null"); } } 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/richiterable/AbstractRichIterableAssert_HasSize_Test.java similarity index 53% rename from src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java rename to src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_HasSize_Test.java index afb3d16..74c6d31 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/bag/BagAssert_HasSize_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_HasSize_Test.java @@ -13,46 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.assertj.eclipse.collections.api.bag; +package org.assertj.eclipse.collections.api.richiterable; 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)); +class AbstractRichIterableAssert_HasSize_Test { + + @RichIterableParameterizedTest + void passes(RichIterableAssertFactory assertFactory) { + assertThatNoException().isThrownBy(() -> + assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").hasSize(5)); } - @Test - void failsEmpty() { - ImmutableBag bag = Bags.immutable.empty(); + @RichIterableParameterizedTest + void failsEmpty(RichIterableAssertFactory assertFactory) { assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> new BagAssert<>(bag).hasSize(5)) + .isThrownBy(() -> assertFactory.fromEmpty().hasSize(5)) .withMessageContaining(String.format("Expected size: %s but was: 0", 5)); } - @Test - void failsNullMultimap() { + @RichIterableParameterizedTest + void failsNullInput(RichIterableAssertFactory assertFactory) { assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> new BagAssert<>(null).hasSize(5)) + .isThrownBy(() -> assertFactory.fromNull().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"); + @RichIterableParameterizedTest + void softAssertionPasses(RichIterableAssertFactory assertFactory) { + SoftAssertions.assertSoftly(softly -> assertFactory.softlyFromElements(softly, "TOS", "TNG", "DS9", "VOY", "ENT").hasSize(5)); } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableArgumentsProvider.java b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableArgumentsProvider.java new file mode 100644 index 0000000..18fbd69 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableArgumentsProvider.java @@ -0,0 +1,85 @@ +/* + * 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.richiterable; + +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import java.util.stream.Stream; + +import org.assertj.eclipse.collections.api.BagAssert; +import org.assertj.eclipse.collections.api.ListIterableAssert; +import org.assertj.eclipse.collections.api.SetIterableAssert; +import org.assertj.eclipse.collections.api.StackIterableAssert; +import org.eclipse.collections.api.factory.Bags; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.factory.Sets; +import org.eclipse.collections.api.factory.Stacks; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.support.ParameterDeclarations; + +class RichIterableArgumentsProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ParameterDeclarations parameters, ExtensionContext context) { + return Stream.of( + arguments(createBagAssert()), + arguments(createListIterableAssert()), + arguments(createSetIterableAssert()), + arguments(createStackIterableAssert()) + ); + } + + private static RichIterableAssertFactory createBagAssert() { + return new RichIterableAssertFactory<>( + "Bag", + elements -> new BagAssert<>(Bags.immutable.of(elements)), + () -> new BagAssert<>(Bags.immutable.empty()), + () -> new BagAssert<>(null), + (softAssertions, elements) -> softAssertions.assertThat(Bags.immutable.of(elements)) + ); + } + + private static RichIterableAssertFactory createListIterableAssert() { + return new RichIterableAssertFactory<>( + "List", + elements -> new ListIterableAssert<>(Lists.immutable.of(elements)), + () -> new ListIterableAssert<>(Lists.immutable.empty()), + () -> new ListIterableAssert<>(null), + (softAssertions, elements) -> softAssertions.assertThat(Lists.immutable.of(elements)) + ); + } + + private static RichIterableAssertFactory createSetIterableAssert() { + return new RichIterableAssertFactory<>( + "Set", + elements -> new SetIterableAssert<>(Sets.immutable.of(elements)), + () -> new SetIterableAssert<>(Sets.immutable.empty()), + () -> new SetIterableAssert<>(null), + (softAssertions, elements) -> softAssertions.assertThat(Sets.immutable.of(elements)) + ); + } + + private static RichIterableAssertFactory createStackIterableAssert() { + return new RichIterableAssertFactory<>( + "Stack", + elements -> new StackIterableAssert<>(Stacks.immutable.of(elements)), + () -> new StackIterableAssert<>(Stacks.immutable.empty()), + () -> new StackIterableAssert<>(null), + (softAssertions, elements) -> softAssertions.assertThat(Stacks.immutable.of(elements)) + ); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableAssertFactory.java b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableAssertFactory.java new file mode 100644 index 0000000..147a0f8 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableAssertFactory.java @@ -0,0 +1,67 @@ +/* + * 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.richiterable; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.assertj.eclipse.collections.api.AbstractRichIterableAssert; +import org.assertj.eclipse.collections.api.SoftAssertions; + +final class RichIterableAssertFactory { + private final String name; + private final Function> fromElements; + private final Supplier> fromEmpty; + private final Supplier> fromNull; + private final BiFunction> softlyFromElements; + + RichIterableAssertFactory( + String name, + Function> fromElements, + Supplier> fromEmpty, + Supplier> fromNull, + BiFunction> softlyFromElements) { + this.name = name; + this.fromElements = fromElements; + this.fromEmpty = fromEmpty; + this.fromNull = fromNull; + this.softlyFromElements = softlyFromElements; + } + + @SafeVarargs + public final AbstractRichIterableAssert fromElements(ELEMENT... elements) { + return fromElements.apply(elements); + } + + public AbstractRichIterableAssert fromEmpty() { + return fromEmpty.get(); + } + + public AbstractRichIterableAssert fromNull() { + return fromNull.get(); + } + + @SafeVarargs + public final AbstractRichIterableAssert softlyFromElements(SoftAssertions softAssertions, ELEMENT... elements) { + return softlyFromElements.apply(softAssertions, elements); + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableParameterizedTest.java b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableParameterizedTest.java new file mode 100644 index 0000000..1488505 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/RichIterableParameterizedTest.java @@ -0,0 +1,31 @@ +/* + * 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.richiterable; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@ParameterizedTest(name = "{0}") +@ArgumentsSource(RichIterableArgumentsProvider.class) +public @interface RichIterableParameterizedTest { +} 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 deleted file mode 100644 index a8d18ca..0000000 --- a/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_FilteredOn_Test.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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"); - } -} diff --git a/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java b/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java deleted file mode 100644 index 043605d..0000000 --- a/src/test/java/org/assertj/eclipse/collections/api/set/SetIterableAssert_HasSize_Test.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 SetIterableAssert_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 3f75c280359a072ed9ce8b887320937b67de614e Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Fri, 22 May 2026 16:07:44 -0400 Subject: [PATCH 2/8] Change visibility --- .../AbstractRichIterableAssert_FilteredOn_Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java b/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java index aa531e6..1c51b63 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/richiterable/AbstractRichIterableAssert_FilteredOn_Test.java @@ -21,7 +21,7 @@ import java.util.function.Function; import java.util.function.Predicate; -public class AbstractRichIterableAssert_FilteredOn_Test { +class AbstractRichIterableAssert_FilteredOn_Test { @RichIterableParameterizedTest void filteredOn_function_passes(RichIterableAssertFactory assertFactory) { assertThatNoException().isThrownBy(() -> assertFactory.fromElements("TOS", "TNG", "DS9", "VOY", "ENT").filteredOn(s -> s.charAt(0), 'T') From a579beb3111e213a053bf309df16664334ab6438 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Fri, 22 May 2026 16:10:09 -0400 Subject: [PATCH 3/8] Add javadoc --- .../eclipse/collections/api/BDDAssertions.java | 18 ++++++++++++++++-- ...lipseCollectionsSoftAssertionsProvider.java | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) 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 42fc66e..4df3baf 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java +++ b/src/main/java/org/assertj/eclipse/collections/api/BDDAssertions.java @@ -39,13 +39,20 @@ protected BDDAssertions() { * 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 + * @return the 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 ListIterableAssert}. + * + * @param actual the actual value. + * @return the created assertion object. + * @param The type of the elements in the list + */ public static ListIterableAssert then(ListIterable actual) { return assertThat(actual); } @@ -73,6 +80,13 @@ public static SetIterableAssert then(SetIterable actual) { return assertThat(actual); } + /** + * Creates a new instance of {@link StackIterableAssert}. + * + * @param actual the actual value. + * @return the created assertion object. + * @param The type of the elements in the stack + */ public static StackIterableAssert then(StackIterable actual) { return assertThat(actual); } 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 970be4e..313c74c 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java +++ b/src/main/java/org/assertj/eclipse/collections/api/EclipseCollectionsSoftAssertionsProvider.java @@ -41,6 +41,13 @@ default BagAssert assertThat(Bag actual) { return this.proxy(BagAssert.class, Bag.class, actual); } + /** + * Creates a new, proxied instance of a {@link ListIterableAssert} + * + * @param actual the actual value + * @return the created assertion object + * @param The type of the elements in the list + */ @SuppressWarnings("unchecked") default ListIterableAssert assertThat(ListIterable actual) { return this.proxy(ListIterableAssert.class, ListIterable.class, actual); @@ -71,6 +78,13 @@ default SetIterableAssert assertThat(SetIterable actual) { return this.proxy(SetIterableAssert.class, SetIterable.class, actual); } + /** + * Creates a new, proxied instance of a {@link StackIterableAssert} + * + * @param actual the actual value + * @return the created assertion object + * @param The type of the elements in the stack + */ @SuppressWarnings("unchecked") default StackIterableAssert assertThat(StackIterable actual) { return this.proxy(StackIterableAssert.class, StackIterable.class, actual); From fadcb89078a6b36bb0af33ada35b99b30aaf8881 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Fri, 22 May 2026 16:21:09 -0400 Subject: [PATCH 4/8] Add javadoc --- .../assertj/eclipse/collections/api/ListIterableAssert.java | 5 +++++ .../assertj/eclipse/collections/api/StackIterableAssert.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java index b99613b..e595295 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java +++ b/src/main/java/org/assertj/eclipse/collections/api/ListIterableAssert.java @@ -24,6 +24,11 @@ import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ListIterable; +/** + * Assertion methods for {@link ListIterable} interface. + * + * @param the type of elements stored in {@link ListIterable}. + */ public class ListIterableAssert extends AbstractOrderedIterableAssert, ListIterable, ELEMENT, ObjectAssert> { public ListIterableAssert(ListIterable actual) { super(actual, ListIterableAssert.class); diff --git a/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java b/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java index 7e37a93..f262baf 100644 --- a/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java +++ b/src/main/java/org/assertj/eclipse/collections/api/StackIterableAssert.java @@ -21,6 +21,11 @@ import org.eclipse.collections.api.stack.ImmutableStack; import org.eclipse.collections.api.stack.StackIterable; +/** + * Assertion methods for {@link StackIterable} interface. + * + * @param the type of elements stored in {@link StackIterable}. + */ @CheckReturnValue public class StackIterableAssert extends AbstractOrderedIterableAssert, StackIterable, ELEMENT, ObjectAssert> { public StackIterableAssert(StackIterable actual) { From 52af24fe68628fcb70b5d182fec580af62999c3f Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sat, 23 May 2026 15:48:22 -0400 Subject: [PATCH 5/8] First and last method tests. --- src/test/java/module-info.java | 2 + .../list/ListIterableAssert_First_Test.java | 50 +++++++++++++++++++ .../list/ListIterableAssert_Last_Test.java | 35 +++++++++++++ .../stack/StackIterableAssert_First_Test.java | 50 +++++++++++++++++++ .../stack/StackIterableAssert_Last_Test.java | 50 +++++++++++++++++++ 5 files changed, 187 insertions(+) create mode 100644 src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java create mode 100644 src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java diff --git a/src/test/java/module-info.java b/src/test/java/module-info.java index 58dec8e..f8f1fea 100644 --- a/src/test/java/module-info.java +++ b/src/test/java/module-info.java @@ -17,8 +17,10 @@ * Test module for AssertJ Eclipse Collections */ open module org.assertj.eclipse.collections.test { + exports org.assertj.eclipse.collections.api.list; exports org.assertj.eclipse.collections.api.multimap; exports org.assertj.eclipse.collections.api.richiterable; + exports org.assertj.eclipse.collections.api.stack; requires org.assertj.eclipse.collections; requires org.assertj.core; diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java new file mode 100644 index 0000000..ad746ed --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java @@ -0,0 +1,50 @@ +/* + * 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.list; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.eclipse.collections.api.ListIterableAssert; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.junit.jupiter.api.Test; + +class ListIterableAssert_First_Test { + @Test + void passes() { + assertThatNoException().isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new ListIterableAssert<>(list).first().isEqualTo("TOS"); + }); + } + + @Test + void passesWithCustomAssertFactory() { + assertThatNoException().isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new ListIterableAssert<>(list).first(InstanceOfAssertFactories.STRING).startsWith("T"); + }); + } + + @Test + void throwsExceptionWhenActualIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + new ListIterableAssert<>(null).first().isEqualTo("TOS") + ).withMessageContaining("Expecting actual not to be null"); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java new file mode 100644 index 0000000..ba06842 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java @@ -0,0 +1,35 @@ +package org.assertj.eclipse.collections.api.list; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.eclipse.collections.api.ListIterableAssert; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +class ListIterableAssert_Last_Test { + @Test + void passes() { + assertThatNoException().isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new ListIterableAssert<>(list).last().isEqualTo("ENT"); + }); + } + + @Test + void passesWithCustomAssertFactory() { + assertThatNoException().isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new ListIterableAssert<>(list).last(InstanceOfAssertFactories.STRING).startsWith("E"); + }); + } + + @Test + void throwsExceptionWhenActualIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + new ListIterableAssert<>(null).last().isEqualTo("ENT") + ).withMessageContaining("Expecting actual not to be null"); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java new file mode 100644 index 0000000..f3810f3 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java @@ -0,0 +1,50 @@ +/* + * 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.stack; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.eclipse.collections.api.StackIterableAssert; +import org.eclipse.collections.api.factory.Stacks; +import org.eclipse.collections.api.stack.ImmutableStack; +import org.junit.jupiter.api.Test; + +public class StackIterableAssert_First_Test { + @Test + void passes() { + assertThatNoException().isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new StackIterableAssert<>(list).first().isEqualTo("ENT"); + }); + } + + @Test + void passesWithCustomAssertFactory() { + assertThatNoException().isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new StackIterableAssert<>(list).first(InstanceOfAssertFactories.STRING).startsWith("E"); + }); + } + + @Test + void throwsExceptionWhenActualIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + new StackIterableAssert<>(null).first().isEqualTo("ENT") + ).withMessageContaining("Expecting actual not to be null"); + } +} diff --git a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java new file mode 100644 index 0000000..42843dc --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java @@ -0,0 +1,50 @@ +/* + * 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.stack; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.core.api.InstanceOfAssertFactories; +import org.assertj.eclipse.collections.api.StackIterableAssert; +import org.eclipse.collections.api.factory.Stacks; +import org.eclipse.collections.api.stack.ImmutableStack; +import org.junit.jupiter.api.Test; + +public class StackIterableAssert_Last_Test { + @Test + void passes() { + assertThatNoException().isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new StackIterableAssert<>(list).last().isEqualTo("TOS"); + }); + } + + @Test + void passesWithCustomAssertFactory() { + assertThatNoException().isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new StackIterableAssert<>(list).last(InstanceOfAssertFactories.STRING).startsWith("T"); + }); + } + + @Test + void throwsExceptionWhenActualIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> + new StackIterableAssert<>(null).last().isEqualTo("TOS") + ).withMessageContaining("Expecting actual not to be null"); + } +} From 5e71028aa3def09f69128957147ef0c8e4f01367 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sat, 23 May 2026 15:54:04 -0400 Subject: [PATCH 6/8] More tests --- .../api/list/ListIterableAssert_First_Test.java | 9 +++++++++ .../api/list/ListIterableAssert_Last_Test.java | 12 ++++++++++++ .../api/stack/StackIterableAssert_First_Test.java | 9 +++++++++ .../api/stack/StackIterableAssert_Last_Test.java | 9 +++++++++ 4 files changed, 39 insertions(+) diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java index ad746ed..68004a0 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_First_Test.java @@ -47,4 +47,13 @@ void throwsExceptionWhenActualIsNull() { new ListIterableAssert<>(null).first().isEqualTo("TOS") ).withMessageContaining("Expecting actual not to be null"); } + + @Test + void throwsExceptionWhenLastElementIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> { + ImmutableList list = Lists.immutable.of(null, "TNG", "DS9", "VOY", null); + new ListIterableAssert<>(list).first().isEqualTo("TOS"); + }).withMessageContaining("check first element") + .withMessageContaining("but was: null"); + } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java index ba06842..ebee33e 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java @@ -2,8 +2,11 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.eclipse.collections.api.ListIterableAssert; +import org.assertj.eclipse.collections.api.StackIterableAssert; import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.factory.Stacks; import org.eclipse.collections.api.list.ImmutableList; +import org.eclipse.collections.api.stack.ImmutableStack; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -32,4 +35,13 @@ void throwsExceptionWhenActualIsNull() { new ListIterableAssert<>(null).last().isEqualTo("ENT") ).withMessageContaining("Expecting actual not to be null"); } + + @Test + void throwsExceptionWhenLastElementIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", null); + new ListIterableAssert<>(list).last().isEqualTo("ENT"); + }).withMessageContaining("check last element") + .withMessageContaining("but was: null"); + } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java index f3810f3..aae4cc5 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_First_Test.java @@ -47,4 +47,13 @@ void throwsExceptionWhenActualIsNull() { new StackIterableAssert<>(null).first().isEqualTo("ENT") ).withMessageContaining("Expecting actual not to be null"); } + + @Test + void throwsExceptionWhenFirstElementIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of("TOS", "TNG", "DS9", "VOY", null); + new StackIterableAssert<>(list).first().isEqualTo("ENT"); + }).withMessageContaining("check first element") + .withMessageContaining("but was: null"); + } } diff --git a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java index 42843dc..a774b86 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/stack/StackIterableAssert_Last_Test.java @@ -47,4 +47,13 @@ void throwsExceptionWhenActualIsNull() { new StackIterableAssert<>(null).last().isEqualTo("TOS") ).withMessageContaining("Expecting actual not to be null"); } + + @Test + void throwsExceptionWhenLastElementIsNull() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> { + ImmutableStack list = Stacks.immutable.of(null, "TNG", "DS9", "VOY", "ENT"); + new StackIterableAssert<>(list).last().isEqualTo("TOS"); + }).withMessageContaining("check last element") + .withMessageContaining("but was: null"); + } } From 61779e91ce53b3a1a1299a8462f631e1a2b95e8f Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sat, 23 May 2026 15:54:44 -0400 Subject: [PATCH 7/8] Add license --- .../api/list/ListIterableAssert_Last_Test.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java index ebee33e..954ecc0 100644 --- a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Last_Test.java @@ -1,3 +1,18 @@ +/* + * 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.list; import org.assertj.core.api.InstanceOfAssertFactories; From 4ec4581a5233994a0cdff63203911460ae111836 Mon Sep 17 00:00:00 2001 From: Matt Bertolini Date: Sat, 23 May 2026 16:07:07 -0400 Subject: [PATCH 8/8] Element test --- .../list/ListIterableAssert_Element_Test.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Element_Test.java diff --git a/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Element_Test.java b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Element_Test.java new file mode 100644 index 0000000..a8a16b3 --- /dev/null +++ b/src/test/java/org/assertj/eclipse/collections/api/list/ListIterableAssert_Element_Test.java @@ -0,0 +1,33 @@ +/* + * 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.list; + +import static org.assertj.core.api.Assertions.assertThatNoException; + +import org.assertj.eclipse.collections.api.ListIterableAssert; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.junit.jupiter.api.Test; + +class ListIterableAssert_Element_Test { + @Test + void passes() { + assertThatNoException().isThrownBy(() -> { + ImmutableList list = Lists.immutable.of("TOS", "TNG", "DS9", "VOY", "ENT"); + new ListIterableAssert<>(list).element(2).isEqualTo("DS9"); + }); + } +}