Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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 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;
import org.eclipse.collections.api.RichIterable;

/**
* Base class for implementations of Eclipse Collections {@link RichIterable} assertions.
*
* @param <SELF> the "self" type of this assertion class. Please read &quot;<a href="https://bit.ly/1IZIRcY"
* target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>&quot;
* for more details.
* @param <ACTUAL> the type of the "actual" value.
* @param <ELEMENT> the type of elements of the "actual" value.
* @param <ELEMENT_ASSERT> used for navigational assertions to return the right assert type.
*/
//@format:off
public abstract class AbstractRichIterableAssert<SELF extends AbstractRichIterableAssert<SELF, ACTUAL, ELEMENT, ELEMENT_ASSERT>,
ACTUAL extends RichIterable<? extends ELEMENT>,
ELEMENT,
ELEMENT_ASSERT extends AbstractAssert<? extends ELEMENT_ASSERT, ELEMENT>>
extends AbstractIterableAssert<SELF, ACTUAL, ELEMENT, ELEMENT_ASSERT> {
//@format:on

protected AbstractRichIterableAssert(ACTUAL actual, Class<?> selfType) {
super(actual, selfType);
}

@Override
public <T> SELF filteredOn(Function<? super ELEMENT, T> 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}.
* <p>
* Example: check old employees whose age &gt; 100:
*
* <pre><code class='java'> 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&lt;Employee&gt; employees = List.of(yoda, luke, obiwan);
*
* assertThat(employees).filteredOn(employee -&gt; employee.getAge() &gt; 100)
* .containsOnly(yoda, obiwan);</code></pre>
*
* @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<? super ELEMENT> 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.
* <p>
* Example:
* <pre>{@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);
* }</pre>
*
* @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));
}

/**
* 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<? super ELEMENT> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,6 +33,17 @@ protected Assertions() {
// Do nothing
}

/**
* Creates a new instance of {@link BagAssert}.
*
* @param actual the actual value.
* @return the created assertion object.
* @param <T> The type of the elements in the bag
*/
public static <T> BagAssert<T> assertThat(Bag<T> actual) {
return new BagAssert<>(actual);
}

/**
* Creates a new instance of {@link MultimapAssert}.
*
Expand All @@ -42,4 +55,15 @@ protected Assertions() {
public static <KEY, VALUE> MultimapAssert<KEY, VALUE> assertThat(Multimap<KEY, VALUE> actual) {
return new MultimapAssert<>(actual);
}

/**
* Creates a new instance of {@link SetIterableAssert}.
*
* @param actual the actual value.
* @return the created assertion object.
* @param <T> The type of the elements in the set
*/
public static <T>SetIterableAssert<T> assertThat(SetIterable<T> actual) {
return new SetIterableAssert<>(actual);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <T> THe type of the elements in the bag
*/
public static <T> BagAssert<T> then(Bag<T> actual) {
return assertThat(actual);
}

/**
* Creates a new instance of {@link MultimapAssert}.
*
Expand All @@ -42,4 +55,15 @@ protected BDDAssertions() {
public static <KEY, VALUE> MultimapAssert<KEY, VALUE> then(Multimap<KEY, VALUE> actual) {
return assertThat(actual);
}

/**
* Creates a new instance of {@link SetIterableAssert}.
*
* @param actual the actual value.
* @return the created assertion object.
* @param <T> The type of the elements in the set
*/
public static <T> SetIterableAssert<T> then(SetIterable<T> actual) {
return assertThat(actual);
}
}
43 changes: 43 additions & 0 deletions src/main/java/org/assertj/eclipse/collections/api/BagAssert.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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;

/**
* Assertion methods for the {@link Bag} interface.
*
* @param <ELEMENT> the type of elements stored in {@link Bag}.
*/
public class BagAssert<ELEMENT> extends AbstractRichIterableAssert<BagAssert<ELEMENT>, Bag<? extends ELEMENT>, ELEMENT, ObjectAssert<ELEMENT>> {
public BagAssert(Bag<? extends ELEMENT> elements) {
super(elements, BagAssert.class);
}

@Override
protected ObjectAssert<ELEMENT> toAssert(ELEMENT value) {
return new ObjectAssert<>(value);
}

@Override
protected BagAssert<ELEMENT> newAbstractIterableAssert(Iterable<? extends ELEMENT> iterable) {
ImmutableBag<? extends ELEMENT> elements = Bags.immutable.ofAll(iterable);
return new BagAssert<>(elements);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 <T> The type of the elements in the bag
*/
@SuppressWarnings("unchecked")
default <T> BagAssert<T> assertThat(Bag<T> actual) {
return this.proxy(BagAssert.class, Bag.class, actual);
}

/**
* Creates a new, proxied instance of a {@link MultimapAssert}
*
Expand All @@ -36,4 +51,16 @@ public interface EclipseCollectionsSoftAssertionsProvider extends SoftAssertions
default <KEY, VALUE> MultimapAssert<KEY, VALUE> assertThat(Multimap<KEY, VALUE> actual) {
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 <T> The type of the elements in the set
*/
@SuppressWarnings("unchecked")
default <T> SetIterableAssert<T> assertThat(SetIterable<T> actual) {
return this.proxy(SetIterableAssert.class, SetIterable.class, actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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;

/**
* Assertion methods for {@link SetIterable} interface.
*
* @param <ELEMENT> the type of elements stored in {@link SetIterable}.
*/
public class SetIterableAssert<ELEMENT> extends AbstractRichIterableAssert<SetIterableAssert<ELEMENT>, SetIterable<? extends ELEMENT>, ELEMENT, ObjectAssert<ELEMENT>> {
public SetIterableAssert(SetIterable<? extends ELEMENT> elements) {
super(elements, SetIterableAssert.class);
}

@Override
protected ObjectAssert<ELEMENT> toAssert(ELEMENT value) {
return new ObjectAssert<>(value);
}

@Override
protected SetIterableAssert<ELEMENT> newAbstractIterableAssert(Iterable<? extends ELEMENT> iterable) {
ImmutableSet<? extends ELEMENT> elements = Sets.immutable.ofAll(iterable);
return new SetIterableAssert<>(elements);
}
}
2 changes: 2 additions & 0 deletions src/test/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading