Skip to content

Commit a06f16c

Browse files
rpoltonscordio
authored andcommitted
More changes for singly-traversable 'contains' assertions (closes #1941)
1 parent 7279cd7 commit a06f16c

File tree

6 files changed

+76
-41
lines changed

6 files changed

+76
-41
lines changed

src/main/java/org/assertj/core/internal/Iterables.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,10 @@ public void assertHasSameSizeAs(AssertionInfo info, Iterable<?> actual, Iterable
332332
* @throws AssertionError if the given {@code Iterable} does not contain the given values.
333333
*/
334334
public void assertContains(AssertionInfo info, Iterable<?> actual, Object[] values) {
335-
if (commonCheckThatIterableAssertionSucceeds(info, actual, values)) return;
335+
final List<?> actualAsList = newArrayList(actual);
336+
if (commonCheckThatIterableAssertionSucceeds(info, actualAsList, values)) return;
336337
// check for elements in values that are missing in actual.
337-
assertIterableContainsGivenValues(actual, values, info);
338+
assertIterableContainsGivenValues(actualAsList, values, info);
338339
}
339340

340341
private void assertIterableContainsGivenValues(Iterable<?> actual, Object[] values, AssertionInfo info) {
@@ -370,14 +371,15 @@ private void iterablesRemove(Iterable<?> actual, Object value) {
370371
* {@code Iterable} contains values that are not in the given array.
371372
*/
372373
public void assertContainsOnly(AssertionInfo info, Iterable<?> actual, Object[] expectedValues) {
373-
if (commonCheckThatIterableAssertionSucceeds(info, actual, expectedValues)) return;
374+
final List<?> actualAsList = newArrayList(actual);
375+
if (commonCheckThatIterableAssertionSucceeds(info, actualAsList, expectedValues)) return;
374376

375377
// after the for loop, unexpected = expectedValues - actual
376-
List<Object> unexpectedValues = newArrayList(actual);
378+
List<Object> unexpectedValues = newArrayList(actualAsList);
377379
// after the for loop, missing = actual - expectedValues
378380
List<Object> missingValues = newArrayList(expectedValues);
379381
for (Object expected : expectedValues) {
380-
if (iterableContains(actual, expected)) {
382+
if (iterableContains(actualAsList, expected)) {
381383
// since expected was found in actual:
382384
// -- it does not belong to the missing elements
383385
iterablesRemove(missingValues, expected);
@@ -387,7 +389,7 @@ public void assertContainsOnly(AssertionInfo info, Iterable<?> actual, Object[]
387389
}
388390

389391
if (!unexpectedValues.isEmpty() || !missingValues.isEmpty()) {
390-
throw failures.failure(info, shouldContainOnly(actual, expectedValues,
392+
throw failures.failure(info, shouldContainOnly(actualAsList, expectedValues,
391393
missingValues, unexpectedValues,
392394
comparisonStrategy));
393395
}

src/test/java/org/assertj/core/internal/iterables/Iterables_assertContainsExactly_Test.java

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.assertj.core.error.ShouldContainExactly.elementsDifferAtIndex;
2121
import static org.assertj.core.error.ShouldContainExactly.shouldContainExactly;
2222
import static org.assertj.core.internal.ErrorMessages.valuesToLookForIsNull;
23+
import static org.assertj.core.internal.iterables.SinglyIterableFactory.createSinglyIterable;
2324
import static org.assertj.core.test.ObjectArrays.emptyArray;
2425
import static org.assertj.core.test.TestData.someInfo;
2526
import static org.assertj.core.util.Arrays.array;
@@ -28,7 +29,6 @@
2829
import static org.assertj.core.util.Lists.newArrayList;
2930
import static org.mockito.Mockito.verify;
3031

31-
import java.util.Iterator;
3232
import java.util.List;
3333

3434
import org.assertj.core.api.AssertionInfo;
@@ -53,32 +53,6 @@ void should_pass_if_nonrestartable_actual_contains_exactly_given_values() {
5353
iterables.assertContainsExactly(someInfo(), createSinglyIterable(actual), array("Luke", "Yoda", "Leia"));
5454
}
5555

56-
static Iterable<String> createSinglyIterable(final List<String> values) {
57-
// can't use Iterable<> for anonymous class in java 8
58-
return new Iterable<String>() {
59-
private boolean isIteratorCreated = false;
60-
61-
@Override
62-
public Iterator<String> iterator() {
63-
if (isIteratorCreated) throw new IllegalArgumentException("Cannot create two iterators on a singly-iterable sequence");
64-
isIteratorCreated = true;
65-
return new Iterator<String>() {
66-
private final Iterator<String> listIterator = values.iterator();
67-
68-
@Override
69-
public boolean hasNext() {
70-
return listIterator.hasNext();
71-
}
72-
73-
@Override
74-
public String next() {
75-
return listIterator.next();
76-
}
77-
};
78-
}
79-
};
80-
}
81-
8256
@Test
8357
void should_pass_if_actual_contains_given_values_exactly_with_null_elements() {
8458
iterables.assertContainsExactly(someInfo(), actual, array("Luke", "Yoda", "Leia"));

src/test/java/org/assertj/core/internal/iterables/Iterables_assertContainsOnly_Test.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.assertj.core.api.Assertions.catchThrowable;
2020
import static org.assertj.core.error.ShouldContainOnly.shouldContainOnly;
2121
import static org.assertj.core.internal.ErrorMessages.valuesToLookForIsNull;
22+
import static org.assertj.core.internal.iterables.SinglyIterableFactory.createSinglyIterable;
2223
import static org.assertj.core.test.ObjectArrays.emptyArray;
2324
import static org.assertj.core.test.TestData.someInfo;
2425
import static org.assertj.core.util.Arrays.array;
@@ -35,7 +36,7 @@
3536

3637
/**
3738
* Tests for <code>{@link Iterables#assertContainsOnly(AssertionInfo, Collection, Object[])}</code>.
38-
*
39+
*
3940
* @author Alex Ruiz
4041
* @author Joel Costigliola
4142
*/
@@ -77,7 +78,8 @@ void should_pass_if_actual_and_given_values_are_empty() {
7778

7879
@Test
7980
void should_fail_if_array_of_values_to_look_for_is_empty_and_actual_is_not() {
80-
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> iterables.assertContainsOnly(someInfo(), actual, emptyArray()));
81+
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> iterables.assertContainsOnly(someInfo(), actual,
82+
emptyArray()));
8183
}
8284

8385
@Test
@@ -88,7 +90,8 @@ void should_throw_error_if_array_of_values_to_look_for_is_null() {
8890

8991
@Test
9092
void should_fail_if_actual_is_null() {
91-
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> iterables.assertContainsOnly(someInfo(), null, array("Yoda")))
93+
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> iterables.assertContainsOnly(someInfo(), null,
94+
array("Yoda")))
9295
.withMessage(actualIsNull());
9396
}
9497

@@ -163,11 +166,16 @@ void should_fail_if_actual_does_not_contain_given_values_only_according_to_custo
163166
AssertionInfo info = someInfo();
164167
Object[] expected = { "Luke", "Yoda", "Han" };
165168

166-
Throwable error = catchThrowable(() -> iterablesWithCaseInsensitiveComparisonStrategy.assertContainsOnly(info, actual, expected));
169+
Throwable error = catchThrowable(() -> iterablesWithCaseInsensitiveComparisonStrategy.assertContainsOnly(info, actual,
170+
expected));
167171

168172
assertThat(error).isInstanceOf(AssertionError.class);
169173
verify(failures).failure(info, shouldContainOnly(actual, expected, newArrayList("Han"), newArrayList("Leia"),
170174
comparisonStrategy));
171175
}
172176

177+
@Test
178+
void should_pass_if_nonrestartable_actual_contains_only_given_values() {
179+
iterables.assertContainsOnly(someInfo(), createSinglyIterable(actual), array("Luke", "Yoda", "Leia"));
180+
}
173181
}

src/test/java/org/assertj/core/internal/iterables/Iterables_assertContainsSequence_Test.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import static org.assertj.core.api.Assertions.catchThrowable;
1919
import static org.assertj.core.error.ShouldContainSequence.shouldContainSequence;
2020
import static org.assertj.core.internal.ErrorMessages.valuesToLookForIsNull;
21-
import static org.assertj.core.internal.iterables.Iterables_assertContainsExactly_Test.createSinglyIterable;
2221
import static org.assertj.core.test.ObjectArrays.emptyArray;
2322
import static org.assertj.core.test.TestData.someInfo;
2423
import static org.assertj.core.util.Arrays.array;
@@ -146,7 +145,7 @@ void should_pass_if_actual_is_an_infinite_sequence_and_contains_sequence() {
146145

147146
@Test
148147
void should_pass_if_actual_is_a_singly_traversable_sequence_and_contains_sequence() {
149-
Iterable<String> actual = createSinglyIterable(list("Leia", "Luke", "Yoda", "Obi-Wan"));
148+
Iterable<String> actual = SinglyIterableFactory.createSinglyIterable(list("Leia", "Luke", "Yoda", "Obi-Wan"));
150149
iterables.assertContainsSequence(someInfo(), actual, array("Leia", "Luke", "Yoda", "Obi-Wan"));
151150
}
152151

src/test/java/org/assertj/core/internal/iterables/Iterables_assertContains_Test.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.catchThrowable;
1919
import static org.assertj.core.error.ShouldContain.shouldContain;
2020
import static org.assertj.core.internal.ErrorMessages.valuesToLookForIsNull;
21+
import static org.assertj.core.internal.iterables.SinglyIterableFactory.createSinglyIterable;
2122
import static org.assertj.core.test.ObjectArrays.emptyArray;
2223
import static org.assertj.core.test.TestData.someInfo;
2324
import static org.assertj.core.util.Arrays.array;
@@ -35,7 +36,7 @@
3536

3637
/**
3738
* Tests for <code>{@link Iterables#assertContains(AssertionInfo, Collection, Object[])}</code>.
38-
*
39+
*
3940
* @author Alex Ruiz
4041
* @author Joel Costigliola
4142
*/
@@ -72,7 +73,12 @@ void should_pass_if_actual_and_given_values_are_empty() {
7273
actual.clear();
7374
iterables.assertContains(someInfo(), actual, array());
7475
}
75-
76+
77+
@Test
78+
void should_pass_if_nonrestartable_actual_contains_given_values() {
79+
iterables.assertContains(someInfo(), createSinglyIterable(actual), array("Luke", "Yoda", "Leia"));
80+
}
81+
7682
@Test
7783
void should_fail_if_array_of_values_to_look_for_is_empty_and_actual_is_not() {
7884
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> iterables.assertContains(someInfo(), actual, emptyArray()));
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
package org.assertj.core.internal.iterables;
14+
15+
import java.util.Iterator;
16+
import java.util.List;
17+
18+
class SinglyIterableFactory {
19+
20+
static Iterable<String> createSinglyIterable(final List<String> values) {
21+
// can't use Iterable<> for anonymous class in java 8
22+
return new Iterable<String>() {
23+
private boolean isIteratorCreated = false;
24+
25+
@Override
26+
public Iterator<String> iterator() {
27+
if (isIteratorCreated) throw new IllegalArgumentException("Cannot create two iterators on a singly-iterable sequence");
28+
isIteratorCreated = true;
29+
return new Iterator<String>() {
30+
private final Iterator<String> listIterator = values.iterator();
31+
32+
@Override
33+
public boolean hasNext() {
34+
return listIterator.hasNext();
35+
}
36+
37+
@Override
38+
public String next() {
39+
return listIterator.next();
40+
}
41+
};
42+
}
43+
};
44+
}
45+
46+
}

0 commit comments

Comments
 (0)