1515 */
1616package org .assertj .eclipse .collections .api ;
1717
18+ import static org .assertj .core .error .ShouldBeAnArray .shouldBeAnArray ;
19+ import static org .assertj .core .error .ShouldBeEmpty .shouldBeEmpty ;
20+ import static org .assertj .core .error .ShouldBeNullOrEmpty .shouldBeNullOrEmpty ;
21+ import static org .assertj .core .error .ShouldHaveSameSizeAs .shouldHaveSameSizeAs ;
1822import static org .assertj .core .error .ShouldHaveSize .shouldHaveSize ;
23+ import static org .assertj .core .error .ShouldHaveSizeBetween .shouldHaveSizeBetween ;
24+ import static org .assertj .core .error .ShouldHaveSizeGreaterThan .shouldHaveSizeGreaterThan ;
25+ import static org .assertj .core .error .ShouldHaveSizeGreaterThanOrEqualTo .shouldHaveSizeGreaterThanOrEqualTo ;
26+ import static org .assertj .core .error .ShouldHaveSizeLessThan .shouldHaveSizeLessThan ;
27+ import static org .assertj .core .error .ShouldHaveSizeLessThanOrEqualTo .shouldHaveSizeLessThanOrEqualTo ;
28+ import static org .assertj .core .error .ShouldNotBeEmpty .shouldNotBeEmpty ;
29+ import static org .assertj .core .util .IterableUtil .sizeOf ;
1930import static org .assertj .core .util .Preconditions .checkArgument ;
2031
32+ import java .lang .reflect .Array ;
2133import java .util .Objects ;
2234import java .util .function .Function ;
2335import java .util .function .Predicate ;
2436
37+ import org .assertj .core .annotation .CheckReturnValue ;
2538import org .assertj .core .api .AbstractAssert ;
2639import org .assertj .core .api .AbstractIterableAssert ;
2740import org .eclipse .collections .api .RichIterable ;
@@ -49,6 +62,7 @@ protected AbstractRichIterableAssert(ACTUAL actual, Class<?> selfType) {
4962 }
5063
5164 @ Override
65+ @ CheckReturnValue
5266 public <T > SELF filteredOn (Function <? super ELEMENT , T > function , T expectedValue ) {
5367 checkArgument (function != null , "The filter function should not be null" );
5468 return internalFilteredOn (element -> Objects .equals (function .apply (element ), expectedValue ));
@@ -57,39 +71,91 @@ public <T> SELF filteredOn(Function<? super ELEMENT, T> function, T expectedValu
5771 /**
5872 * Filters the iterable under test keeping only elements matching the given {@link Predicate}.
5973 * <p>
60- * Example: check old employees whose age > 100 :
74+ * Example: check crew members whose pips > 2 :
6175 *
62- * <pre>< code class='java'> Employee yoda = new Employee (1L, new Name("Yoda "), 800 );
63- * Employee obiwan = new Employee (2L, new Name("Obiwan "), 800 );
64- * Employee luke = new Employee (3L, new Name("Luke ", "Skywalker "), 26 );
76+ * <pre>{@ code CrewMember picard = new CrewMember (1L, new Name("Picard "), 4 );
77+ * CrewMember riker = new CrewMember (2L, new Name("Riker "), 3 );
78+ * CrewMember crusher = new CrewMember (3L, new Name("Wesley ", "Crusher "), 1 );
6579 *
66- * List<Employee> employees = List. of(yoda, luke, obiwan );
80+ * ImmutableList<CrewMember> crew = Lists.immutable. of(picard, crusher, riker );
6781 *
68- * assertThat(employees ).filteredOn(employee -> employee.getAge () > 100 )
69- * .containsOnly(yoda, obiwan);</code> </pre>
82+ * assertThat(crew ).filteredOn(crewMember -> crewMember.getPips () > 2 )
83+ * .containsOnly(picard, riker);} </pre>
7084 *
7185 * @param predicate the filter predicate
7286 * @return a new assertion object with the filtered iterable under test
7387 * @throws IllegalArgumentException if the given predicate is {@code null}.
7488 */
7589 @ Override
90+ @ CheckReturnValue
7691 public SELF filteredOn (Predicate <? super ELEMENT > predicate ) {
7792 checkArgument (predicate != null , "The filter predicate should not be null" );
7893 return internalFilteredOn (predicate ::test );
7994 }
8095
96+ /**
97+ * Verifies that the size of the actual RichIterable is equal to the size of the given iterable.
98+ *
99+ * @param other the iterable to compare the size of the actual RichIterable with.
100+ * @return {@code this} assertion object.
101+ * @throws NullPointerException if the given iterable is {@code null}.
102+ * @throws AssertionError if the size of the actual RichIterable is not equal to the size of the given iterable.
103+ */
104+ @ Override
105+ public SELF hasSameSizeAs (Iterable <?> other ) {
106+ isNotNull ();
107+
108+ final int otherSize ;
109+ if (other instanceof RichIterable <?> richIterable ) {
110+ otherSize = richIterable .size ();
111+ } else {
112+ otherSize = sizeOf (other );
113+ }
114+
115+ int actualSize = actual .size ();
116+ if (actualSize == otherSize ) {
117+ return myself ;
118+ }
119+ throw assertionError (shouldHaveSameSizeAs (actual , other , actualSize , otherSize ));
120+ }
121+
122+ /**
123+ * Verifies that the size of the actual RichIterable matches the size of the given array.
124+ *
125+ * @param other the array to compare the size of the actual RichIterable with.
126+ * @return {@code this} assertion object.
127+ * @throws AssertionError if the provided array is {@code null}.
128+ * @throws AssertionError if the size of the actual RichIterable does not match the size of the given array or if the given array is {@code null}.
129+ */
130+ @ Override
131+ public SELF hasSameSizeAs (Object other ) {
132+ isNotNull ();
133+
134+ if (!(other != null && other .getClass ().isArray ())) {
135+ throw assertionError (shouldBeAnArray (other ));
136+ }
137+
138+ int otherSize = Array .getLength (other );
139+ int actualSize = actual .size ();
140+ if (actualSize == otherSize ) {
141+ return myself ;
142+ }
143+
144+ throw assertionError (shouldHaveSameSizeAs (actual , other , actualSize , otherSize ));
145+ }
146+
81147 /**
82148 * Verifies that the number of values in the actual RichIterable is equal to the given one.
83149 * <p>
84150 * Example:
85151 * <pre>{@code
86152 * // assertions will pass
87153 * assertThat(Sets.immutable.of("TNG", "DS9")).hasSize(2);
88- * assertThat(Bags.immutable.of(1, 2, 3 )).hasSize(3);
154+ * assertThat(Bags.immutable.of("TNG", "DS9", "VOY" )).hasSize(3);
89155 *
90156 * // assertions will fail
91157 * assertThat(Sets.immutable.empty()).hasSize(1);
92- * assertThat(Bags.immutable.of(1, 2, 3 )).hasSize(2);
158+ * assertThat(Bags.immutable.of("TNG", "DS9", "VOY" )).hasSize(2);
93159 * }</pre>
94160 *
95161 * @param expected the expected number of values in the actual collection.
@@ -108,6 +174,201 @@ public SELF hasSize(int expected) {
108174 throw assertionError (shouldHaveSize (actual , actualSize , expected ));
109175 }
110176
177+ /**
178+ * Verifies that the number of values in the actual RichIterable is between the given boundaries (inclusive).
179+ * <p>
180+ * Example:
181+ * <pre><code class='java'> // assertions will pass
182+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeBetween(2, 3)
183+ * .hasSizeBetween(3, 4)
184+ * .hasSizeBetween(3, 3);
185+ *
186+ * // assertion will fail
187+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeBetween(4, 6);</code></pre>
188+ *
189+ * @param lowerBoundary the lower boundary compared to which actual size should be greater than or equal to.
190+ * @param higherBoundary the higher boundary compared to which actual size should be less than or equal to.
191+ * @return {@code this} assertion object.
192+ * @throws AssertionError if the number of values of the actual RichIterable is not between the boundaries.
193+ */
194+ @ Override
195+ public SELF hasSizeBetween (int lowerBoundary , int higherBoundary ) {
196+ isNotNull ();
197+
198+ if (!(higherBoundary >= lowerBoundary )) {
199+ throw new IllegalArgumentException ("The higher boundary <%s> must be greater than the lower boundary <%s>." .formatted (
200+ higherBoundary ,
201+ lowerBoundary ));
202+ }
203+
204+ int actualSize = actual .size ();
205+ if (actualSize >= lowerBoundary && actualSize <= higherBoundary ) {
206+ return myself ;
207+ }
208+
209+ throw assertionError (shouldHaveSizeBetween (actual , actualSize , lowerBoundary , higherBoundary ));
210+ }
211+
212+ /**
213+ * Verifies that the number of values in the actual RichIterable is greater than the given boundary.
214+ * <p>
215+ * Example:
216+ * <pre>{@code // assertion will pass
217+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeGreaterThan(2);
218+ *
219+ * // assertion will fail
220+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeGreaterThan(3);
221+ * }</pre>
222+ *
223+ * @param boundary the given value to compare the actual size to.
224+ * @return {@code this} assertion object.
225+ * @throws AssertionError if the number of values of the actual iterable is not greater than the boundary.
226+ */
227+ @ Override
228+ public SELF hasSizeGreaterThan (int boundary ) {
229+ isNotNull ();
230+
231+ int actualSize = actual .size ();
232+ if (actualSize > boundary ) {
233+ return myself ;
234+ }
235+
236+ throw assertionError (shouldHaveSizeGreaterThan (actual , actualSize , boundary ));
237+ }
238+
239+ /**
240+ * Verifies that the number of values in the actual group is greater than or equal to the given boundary.
241+ * <p>
242+ * Example:
243+ * <pre>{@code // assertions will pass
244+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeGreaterThanOrEqualTo(3);
245+ * assertThat(Lists.immutable.of("TNG", "DS9")).hasSizeGreaterThanOrEqualTo(1);
246+ *
247+ * // assertions will fail
248+ * assertThat(Lists.immutable.of("TNG", "DS9")).hasSizeGreaterThanOrEqualTo(3);
249+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeGreaterThanOrEqualTo(4);
250+ * }</pre>
251+ *
252+ * @param boundary the given value to compare the actual size to.
253+ * @return {@code this} assertion object.
254+ * @throws AssertionError if the number of values of the actual group is not greater than or equal to the boundary.
255+ */
256+ @ Override
257+ public SELF hasSizeGreaterThanOrEqualTo (int boundary ) {
258+ isNotNull ();
259+
260+ int actualSize = actual .size ();
261+ if (actualSize >= boundary ) {
262+ return myself ;
263+ }
264+
265+ throw assertionError (shouldHaveSizeGreaterThanOrEqualTo (actual , actualSize , boundary ));
266+ }
267+
268+ /**
269+ * Verifies that the number of values in the actual RichIterable is less than the given boundary.
270+ * <p>
271+ * Example:
272+ * <pre>{@code
273+ * // assertion will pass
274+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeLessThan(4);
275+ *
276+ * // assertion will fail
277+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeLessThan(3);
278+ * }</pre>
279+ *
280+ * @param boundary the given value to compare the actual size to.
281+ * @return {@code this} assertion object.
282+ * @throws AssertionError if the number of values of the actual RichIterable is not less than the boundary.
283+ */
284+ @ Override
285+ public SELF hasSizeLessThan (int boundary ) {
286+ isNotNull ();
287+
288+ int actualSize = actual .size ();
289+ if (actualSize < boundary ) {
290+ return myself ;
291+ }
292+
293+ throw assertionError (shouldHaveSizeLessThan (actual , actualSize , boundary ));
294+ }
295+
296+ /**
297+ * Verifies that the number of values in the actual RichIterable is less than or equal to the given boundary.
298+ * <p>
299+ * Example:
300+ * <pre>{@code
301+ * // assertions will pass
302+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeLessThanOrEqualTo(5)
303+ * .hasSizeLessThanOrEqualTo(3);
304+ *
305+ * // assertion will fail
306+ * assertThat(Lists.immutable.of("TOS", "TNG", "DS9")).hasSizeLessThanOrEqualTo(2);
307+ * }</pre>
308+ *
309+ * @param boundary the given value to compare the actual size to.
310+ * @return {@code this} assertion object.
311+ * @throws AssertionError if the number of values of the actual RichIterable is not less than or equal to the boundary.
312+ */
313+ @ Override
314+ public SELF hasSizeLessThanOrEqualTo (int boundary ) {
315+ isNotNull ();
316+
317+ int actualSize = actual .size ();
318+ if (actualSize <= boundary ) {
319+ return myself ;
320+ }
321+
322+ throw assertionError (shouldHaveSizeLessThanOrEqualTo (actual , actualSize , boundary ));
323+ }
324+
325+ /**
326+ * Verifies that the actual RichIterable is empty.
327+ *
328+ * @throws AssertionError if the actual RichIterable is not empty.
329+ */
330+ @ Override
331+ public void isEmpty () {
332+ isNotNull ();
333+
334+ if (actual .isEmpty ()) {
335+ return ;
336+ }
337+
338+ throw assertionError (shouldBeEmpty (actual ));
339+ }
340+
341+ /**
342+ * Verifies that the actual RichIterable is not empty.
343+ *
344+ * @return {@code this} assertion object.
345+ * @throws AssertionError if the actual RichIterable is empty.
346+ */
347+ @ Override
348+ public SELF isNotEmpty () {
349+ isNotNull ();
350+
351+ if (actual .notEmpty ()) {
352+ return myself ;
353+ }
354+
355+ throw assertionError (shouldNotBeEmpty ());
356+ }
357+
358+ /**
359+ * Verifies that the actual RichIterable is null or empty.
360+ *
361+ * @throws AssertionError if the actual RichIterable is not null or not empty.
362+ */
363+ @ Override
364+ public void isNullOrEmpty () {
365+ if (actual == null || actual .isEmpty ()) {
366+ return ;
367+ }
368+
369+ throw assertionError (shouldBeNullOrEmpty (actual ));
370+ }
371+
111372 /**
112373 * Helper method that filters via Eclipse Collections to avoid creating any JCL collections.
113374 *
0 commit comments