001 /*
002 * Created on Sep 17, 2010
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005 * the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 *
013 * Copyright @2010-2011 the original author or authors.
014 */
015 package org.fest.assertions.internal;
016
017 import static org.fest.assertions.error.ConditionAndGroupGenericParameterTypeShouldBeTheSame.shouldBeSameGenericBetweenIterableAndCondition;
018 import static org.fest.assertions.error.ElementsShouldBe.elementsShouldBe;
019 import static org.fest.assertions.error.ElementsShouldBeAtLeast.elementsShouldBeAtLeast;
020 import static org.fest.assertions.error.ElementsShouldBeExactly.elementsShouldBeExactly;
021 import static org.fest.assertions.error.ElementsShouldHave.elementsShouldHave;
022 import static org.fest.assertions.error.ElementsShouldHaveAtLeast.elementsShouldHaveAtLeast;
023 import static org.fest.assertions.error.ElementsShouldHaveAtMost.elementsShouldHaveAtMost;
024 import static org.fest.assertions.error.ElementsShouldHaveExactly.elementsShouldHaveExactly;
025 import static org.fest.assertions.error.ElementsShouldNotBe.elementsShouldNotBe;
026 import static org.fest.assertions.error.ElementsShouldNotBeAtLeast.elementsShouldNotBeAtLeast;
027 import static org.fest.assertions.error.ElementsShouldNotBeAtMost.elementsShouldNotBeAtMost;
028 import static org.fest.assertions.error.ElementsShouldNotBeExactly.elementsShouldNotBeExactly;
029 import static org.fest.assertions.error.ElementsShouldNotHave.elementsShouldNotHave;
030 import static org.fest.assertions.error.ElementsShouldNotHaveAtLeast.elementsShouldNotHaveAtLeast;
031 import static org.fest.assertions.error.ElementsShouldNotHaveAtMost.elementsShouldNotHaveAtMost;
032 import static org.fest.assertions.error.ElementsShouldNotHaveExactly.elementsShouldNotHaveExactly;
033 import static org.fest.assertions.error.ShouldBeEmpty.shouldBeEmpty;
034 import static org.fest.assertions.error.ShouldBeNullOrEmpty.shouldBeNullOrEmpty;
035 import static org.fest.assertions.error.ShouldBeSubsetOf.shouldBeSubsetOf;
036 import static org.fest.assertions.error.ShouldContain.shouldContain;
037 import static org.fest.assertions.error.ShouldContainNull.shouldContainNull;
038 import static org.fest.assertions.error.ShouldContainOnly.shouldContainOnly;
039 import static org.fest.assertions.error.ShouldContainSequence.shouldContainSequence;
040 import static org.fest.assertions.error.ShouldEndWith.shouldEndWith;
041 import static org.fest.assertions.error.ShouldHaveSameSizeAs.shouldHaveSameSizeAs;
042 import static org.fest.assertions.error.ShouldHaveSize.shouldHaveSize;
043 import static org.fest.assertions.error.ShouldNotBeEmpty.shouldNotBeEmpty;
044 import static org.fest.assertions.error.ShouldNotContain.shouldNotContain;
045 import static org.fest.assertions.error.ShouldNotContainNull.shouldNotContainNull;
046 import static org.fest.assertions.error.ShouldNotHaveDuplicates.shouldNotHaveDuplicates;
047 import static org.fest.assertions.error.ShouldStartWith.shouldStartWith;
048 import static org.fest.assertions.internal.CommonErrors.*;
049 import static org.fest.util.Collections.*;
050
051 import java.util.Comparator;
052 import java.util.HashSet;
053 import java.util.LinkedHashSet;
054 import java.util.LinkedList;
055 import java.util.List;
056 import java.util.Set;
057
058 import org.fest.assertions.core.AssertionInfo;
059 import org.fest.assertions.core.Condition;
060 import org.fest.util.ComparatorBasedComparisonStrategy;
061 import org.fest.util.ComparisonStrategy;
062 import org.fest.util.StandardComparisonStrategy;
063 import org.fest.util.VisibleForTesting;
064
065 /**
066 * Reusable assertions for <code>{@link Iterable}</code>s.
067 *
068 * @author Alex Ruiz
069 * @author Yvonne Wang
070 * @author Maciej Jaskowski
071 * @author Nicolas François
072 * @author Joel Costigliola
073 */
074 public class Iterables {
075
076 private static final Iterables INSTANCE = new Iterables();
077
078 /**
079 * Returns the singleton instance of this class based on {@link StandardComparisonStrategy}.
080 * @return the singleton instance of this class based on {@link StandardComparisonStrategy}.
081 */
082 public static Iterables instance() {
083 return INSTANCE;
084 }
085
086 private final ComparisonStrategy comparisonStrategy;
087
088 @VisibleForTesting
089 Failures failures = Failures.instance();
090
091 @VisibleForTesting
092 Conditions conditions = Conditions.instance();
093
094 @VisibleForTesting
095 Iterables() {
096 this(StandardComparisonStrategy.instance());
097 }
098
099 public Iterables(ComparisonStrategy comparisonStrategy) {
100 this.comparisonStrategy = comparisonStrategy;
101 }
102
103 @VisibleForTesting
104 public Comparator<?> getComparator() {
105 if (comparisonStrategy instanceof ComparatorBasedComparisonStrategy) { return ((ComparatorBasedComparisonStrategy) comparisonStrategy)
106 .getComparator(); }
107 return null;
108 }
109
110 /**
111 * Asserts that the given <code>{@link Iterable}</code> is {@code null} or empty.
112 * @param info contains information about the assertion.
113 * @param actual the given {@code Iterable}.
114 * @throws AssertionError if the given {@code Iterable} is not {@code null} *and* contains one or more elements.
115 */
116 public void assertNullOrEmpty(AssertionInfo info, Iterable<?> actual) {
117 if (actual == null || isEmpty(actual)) return;
118 throw failures.failure(info, shouldBeNullOrEmpty(actual));
119 }
120
121 /**
122 * Asserts that the given {@code Iterable} is empty.
123 * @param info contains information about the assertion.
124 * @param actual the given {@code Iterable}.
125 * @throws AssertionError if the given {@code Iterable} is {@code null}.
126 * @throws AssertionError if the given {@code Iterable} is not empty.
127 */
128 public void assertEmpty(AssertionInfo info, Iterable<?> actual) {
129 assertNotNull(info, actual);
130 if (isEmpty(actual)) return;
131 throw failures.failure(info, shouldBeEmpty(actual));
132 }
133
134 /**
135 * Asserts that the given {@code Iterable} is not empty.
136 * @param info contains information about the assertion.
137 * @param actual the given {@code Iterable}.
138 * @throws AssertionError if the given {@code Iterable} is {@code null}.
139 * @throws AssertionError if the given {@code Iterable} is empty.
140 */
141 public void assertNotEmpty(AssertionInfo info, Iterable<?> actual) {
142 assertNotNull(info, actual);
143 if (!isEmpty(actual)) return;
144 throw failures.failure(info, shouldNotBeEmpty());
145 }
146
147 /**
148 * Asserts that the number of elements in the given {@code Iterable} is equal to the expected one.
149 * @param info contains information about the assertion.
150 * @param actual the given {@code Iterable}.
151 * @param expectedSize the expected size of {@code actual}.
152 * @throws AssertionError if the given {@code Iterable} is {@code null}.
153 * @throws AssertionError if the number of elements in the given {@code Iterable} is different than the expected one.
154 */
155 public void assertHasSize(AssertionInfo info, Iterable<?> actual, int expectedSize) {
156 assertNotNull(info, actual);
157 int sizeOfActual = sizeOf(actual);
158 if (sizeOfActual == expectedSize) return;
159 throw failures.failure(info, shouldHaveSize(actual, sizeOfActual, expectedSize));
160 }
161
162 /**
163 * Assert that the actual {@code Iterable} has the same size as the other array.
164 * @param info contains information about the assertion.
165 * @param actual the given {@code Iterable}.
166 * @param other the given array to compare.
167 * @throws AssertionError if the actual group is {@code null}.
168 * @throws AssertionError if the other group is {@code null}.
169 * @throws AssertionError if actual {@code Iterable} and other array don't have the same size.
170 */
171 public void assertHasSameSizeAs(AssertionInfo info, Iterable<?> actual, Object[] other) {
172 assertNotNull(info, actual);
173 if (other == null) throw arrayOfValuesToLookForIsNull();
174 int sizeOfActual = sizeOf(actual);
175 int sizeOfOther = other.length;
176 if (sizeOfActual == sizeOfOther) return;
177 throw failures.failure(info, shouldHaveSameSizeAs(actual, sizeOfActual, sizeOfOther));
178 }
179
180 /**
181 * Assert that the actual {@code Iterable} has the same size as the other {@code Iterable}.
182 * @param info contains information about the assertion.
183 * @param actual the given {@code Iterable}.
184 * @param other the given {@code Iterable}.
185 * @throws AssertionError if the actual group is {@code null}.
186 * @throws AssertionError if the other group is {@code null}.
187 * @throws AssertionError if actual and other {@code Iterable} don't have the same size.
188 */
189 public void assertHasSameSizeAs(AssertionInfo info, Iterable<?> actual, Iterable<?> other) {
190 assertNotNull(info, actual);
191 checkNotNull(info, other);
192 int sizeOfActual = sizeOf(actual);
193 int sizeOfOther = sizeOf(other);
194 if (sizeOfActual == sizeOfOther) return;
195 throw failures.failure(info, shouldHaveSameSizeAs(actual, sizeOfActual, sizeOfOther));
196 }
197
198 /**
199 * Asserts that the given {@code Iterable} contains the given values, in any order.
200 * @param info contains information about the assertion.
201 * @param actual the given {@code Iterable}.
202 * @param values the values that are expected to be in the given {@code Iterable}.
203 * @throws NullPointerException if the array of values is {@code null}.
204 * @throws IllegalArgumentException if the array of values is empty.
205 * @throws AssertionError if the given {@code Iterable} is {@code null}.
206 * @throws AssertionError if the given {@code Iterable} does not contain the given values.
207 */
208 public void assertContains(AssertionInfo info, Iterable<?> actual, Object[] values) {
209 checkIsNotNullAndNotEmpty(values);
210 assertNotNull(info, actual);
211 Set<Object> notFound = new LinkedHashSet<Object>();
212 for (Object value : values)
213 if (!iterableContains(actual, value)) notFound.add(value);
214 if (notFound.isEmpty()) return;
215 throw failures.failure(info, shouldContain(actual, values, notFound, comparisonStrategy));
216 }
217
218 /**
219 * Delegates to {@link ComparisonStrategy#iterableContains(Iterable, Object)}
220 */
221 private boolean iterableContains(Iterable<?> actual, Object value) {
222 return comparisonStrategy.iterableContains(actual, value);
223 }
224
225 /**
226 * Delegates to {@link ComparisonStrategy#iterableRemoves(Iterable, Object)}
227 */
228 private void iterableRemoves(Iterable<?> actual, Object value) {
229 comparisonStrategy.iterableRemoves(actual, value);
230 }
231
232 /**
233 * Asserts that the given {@code Iterable} contains only the given values and nothing else, in any order.
234 * @param info contains information about the assertion.
235 * @param actual the given {@code Iterable}.
236 * @param values the values that are expected to be in the given {@code Iterable}.
237 * @throws NullPointerException if the array of values is {@code null}.
238 * @throws IllegalArgumentException if the array of values is empty.
239 * @throws AssertionError if the given {@code Iterable} is {@code null}.
240 * @throws AssertionError if the given {@code Iterable} does not contain the given values or if the given
241 * {@code Iterable} contains values that are not in the given array.
242 */
243 public void assertContainsOnly(AssertionInfo info, Iterable<?> actual, Object[] values) {
244 checkIsNotNullAndNotEmpty(values);
245 assertNotNull(info, actual);
246 Set<Object> notExpected = setFromIterable(actual);
247 Set<Object> notFound = containsOnly(notExpected, values);
248 if (notExpected.isEmpty() && notFound.isEmpty()) return;
249 throw failures.failure(info, shouldContainOnly(actual, values, notFound, notExpected, comparisonStrategy));
250 }
251
252 private Set<Object> containsOnly(Set<Object> actual, Object[] values) {
253 Set<Object> notFound = new LinkedHashSet<Object>();
254 for (Object o : set(values)) {
255 if (iterableContains(actual, o)) iterableRemoves(actual, o);
256 else notFound.add(o);
257 }
258 return notFound;
259 }
260
261 /**
262 * build a Set with that avoid duplicates <b>according to given comparison strategy</b>
263 * @param elements to feed the Set we want to build
264 * @return a Set without duplicates <b>according to given comparison strategy</b>
265 */
266 private Set<Object> set(Object... elements) {
267 if (elements == null) return null;
268 Set<Object> set = new HashSet<Object>();
269 for (Object e : elements) {
270 // only add is not already there
271 if (!iterableContains(set, e)) set.add(e);
272 }
273 return set;
274 }
275
276 /**
277 * build a Set with that avoid duplicates <b>according to given comparison strategy</b>
278 * @param iterable to feed the Set we want to build
279 * @return a Set without duplicates <b>according to given comparison strategy</b>
280 */
281 private Set<Object> setFromIterable(Iterable<?> iterable) {
282 if (iterable == null) return null;
283 Set<Object> set = new HashSet<Object>();
284 for (Object e : iterable) {
285 // only add is not already there
286 if (!iterableContains(set, e)) set.add(e);
287 }
288 return set;
289 }
290
291 /**
292 * Verifies that the given <code>{@link Iterable}</code> contains the given sequence of objects, without any other
293 * objects between them.
294 * @param info contains information about the assertion.
295 * @param actual the given {@code Iterable}.
296 * @param sequence the sequence of objects to look for.
297 * @throws AssertionError if the given {@code Iterable} is {@code null}.
298 * @throws NullPointerException if the given sequence is {@code null}.
299 * @throws IllegalArgumentException if the given sequence is empty.
300 * @throws AssertionError if the given {@code Iterable} does not contain the given sequence of objects.
301 */
302 public void assertContainsSequence(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
303 checkIsNotNullAndNotEmpty(sequence);
304 assertNotNull(info, actual);
305 List<?> actualAsList = list(actual);
306 for (int i = 0; i < actualAsList.size(); i++) {
307 // look for given sequence in actual starting from current index (i)
308 if (containsSequenceAtGivenIndex(actualAsList, sequence, i)) return;
309 }
310 throw actualDoesNotContainSequence(info, actual, sequence);
311 }
312
313 /**
314 * Verifies that the actual <code>Iterable</code> is a subset of values <code>Iterable</code>. <br/>
315 * Both actual and given iterable are treated as sets, therefore duplicates on either of them are ignored.
316 * @param info contains information about the assertion.
317 * @param actual the actual {@code Iterable}.
318 * @param values the {@code Iterable} that should contain all actual elements.
319 * @throws AssertionError if the actual {@code Iterable} is {@code null}.
320 * @throws NullPointerException if the given Iterable is {@code null}.
321 * @throws AssertionError if the actual {@code Iterable} is not subset of set <code>{@link Iterable}</code>
322 */
323 public void assertIsSubsetOf(AssertionInfo info, Iterable<?> actual, Iterable<?> values) {
324 assertNotNull(info, actual);
325 checkNotNull(info, values);
326 List<Object> extra = list();
327 for (Object actualElement : actual) {
328 if (!iterableContains(values, actualElement)) {
329 extra.add(actualElement);
330 }
331 }
332 if (extra.size() > 0) throw actualIsNotSubsetOfSet(info, actual, values, extra);
333 }
334
335 private static void checkNotNull(AssertionInfo info, Iterable<?> set) {
336 if (set == null) throw iterableToLookForIsNull();
337 }
338
339 private AssertionError actualIsNotSubsetOfSet(AssertionInfo info, Object actual, Iterable<?> set, Iterable<?> extra) {
340 return failures.failure(info, shouldBeSubsetOf(actual, set, extra, comparisonStrategy));
341 }
342
343 /**
344 * Return true if actualAsList contains exactly the given sequence at given starting index, false otherwise.
345 * @param actualAsList the list to look sequance in
346 * @param sequence the sequence to look for
347 * @param startingIndex the index of actual list at which we start looking for sequence.
348 * @return
349 */
350 private boolean containsSequenceAtGivenIndex(List<?> actualAsList, Object[] sequence, int startingIndex) {
351 // check that, starting from given index, actualAsList has enough remaining elements to contain sequence
352 if (actualAsList.size() - startingIndex < sequence.length) return false;
353 for (int i = 0; i < sequence.length; i++) {
354 if (!areEqual(actualAsList.get(startingIndex + i), sequence[i])) return false;
355 }
356 return true;
357 }
358
359 /**
360 * Delegates to {@link ComparisonStrategy#areEqual(Object, Object)}
361 */
362 private boolean areEqual(Object actual, Object other) {
363 return comparisonStrategy.areEqual(actual, other);
364 }
365
366 private AssertionError actualDoesNotContainSequence(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
367 return failures.failure(info, shouldContainSequence(actual, sequence, comparisonStrategy));
368 }
369
370 /**
371 * Asserts that the given {@code Iterable} does not contain the given values.
372 * @param info contains information about the assertion.
373 * @param actual the given {@code Iterable}.
374 * @param values the values that are expected not to be in the given {@code Iterable}.
375 * @throws NullPointerException if the array of values is {@code null}.
376 * @throws IllegalArgumentException if the array of values is empty.
377 * @throws AssertionError if the given {@code Iterable} is {@code null}.
378 * @throws AssertionError if the given {@code Iterable} contains any of given values.
379 */
380 public void assertDoesNotContain(AssertionInfo info, Iterable<?> actual, Object[] values) {
381 checkIsNotNullAndNotEmpty(values);
382 assertNotNull(info, actual);
383 Set<Object> found = new LinkedHashSet<Object>();
384 for (Object o : values)
385 if (iterableContains(actual, o)) found.add(o);
386 if (found.isEmpty()) return;
387 throw failures.failure(info, shouldNotContain(actual, values, found, comparisonStrategy));
388 }
389
390 /**
391 * Asserts that the given {@code Iterable} does not have duplicate values.
392 * @param info contains information about the assertion.
393 * @param actual the given {@code Iterable}.
394 * @throws NullPointerException if the array of values is {@code null}.
395 * @throws IllegalArgumentException if the array of values is empty.
396 * @throws AssertionError if the given {@code Iterable} is {@code null}.
397 * @throws AssertionError if the given {@code Iterable} contains duplicate values.
398 */
399 public void assertDoesNotHaveDuplicates(AssertionInfo info, Iterable<?> actual) {
400 assertNotNull(info, actual);
401 Iterable<?> duplicates = comparisonStrategy.duplicatesFrom(actual);
402 if (isEmpty(duplicates)) return;
403 throw failures.failure(info, shouldNotHaveDuplicates(actual, duplicates, comparisonStrategy));
404 }
405
406 /**
407 * Verifies that the given {@code Iterable} starts with the given sequence of objects, without any other objects
408 * between them. Similar to <code>{@link #assertContainsSequence(AssertionInfo, Iterable, Object[])}</code>, but it
409 * also verifies that the first element in the sequence is also the first element of the given {@code Iterable}.
410 * @param info contains information about the assertion.
411 * @param actual the given {@code Iterable}.
412 * @param sequence the sequence of objects to look for.
413 * @throws NullPointerException if the given argument is {@code null}.
414 * @throws IllegalArgumentException if the given argument is an empty array.
415 * @throws AssertionError if the given {@code Iterable} is {@code null}.
416 * @throws AssertionError if the given {@code Iterable} does not start with the given sequence of objects.
417 */
418 public void assertStartsWith(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
419 checkIsNotNullAndNotEmpty(sequence);
420 assertNotNull(info, actual);
421 int sequenceSize = sequence.length;
422 if (sizeOf(actual) < sequenceSize) throw actualDoesNotStartWithSequence(info, actual, sequence);
423 int i = 0;
424 for (Object o : actual) {
425 if (i >= sequenceSize) break;
426 if (areEqual(o, sequence[i++])) continue;
427 throw actualDoesNotStartWithSequence(info, actual, sequence);
428 }
429 }
430
431 private AssertionError actualDoesNotStartWithSequence(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
432 return failures.failure(info, shouldStartWith(actual, sequence, comparisonStrategy));
433 }
434
435 /**
436 * Verifies that the given {@code Iterable} ends with the given sequence of objects, without any other objects between
437 * them. Similar to <code>{@link #assertContainsSequence(AssertionInfo, Iterable, Object[])}</code>, but it also
438 * verifies that the last element in the sequence is also the last element of the given {@code Iterable}.
439 * @param info contains information about the assertion.
440 * @param actual the given {@code Iterable}.
441 * @param sequence the sequence of objects to look for.
442 * @throws NullPointerException if the given argument is {@code null}.
443 * @throws IllegalArgumentException if the given argument is an empty array.
444 * @throws AssertionError if the given {@code Iterable} is {@code null}.
445 * @throws AssertionError if the given {@code Iterable} does not end with the given sequence of objects.
446 */
447 public void assertEndsWith(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
448 checkIsNotNullAndNotEmpty(sequence);
449 assertNotNull(info, actual);
450 int sequenceSize = sequence.length;
451 int sizeOfActual = sizeOf(actual);
452 if (sizeOfActual < sequenceSize) throw actualDoesNotEndWithSequence(info, actual, sequence);
453 int start = sizeOfActual - sequenceSize;
454 int sequenceIndex = 0, indexOfActual = 0;
455 for (Object o : actual) {
456 if (indexOfActual++ < start) continue;
457 if (areEqual(o, sequence[sequenceIndex++])) continue;
458 throw actualDoesNotEndWithSequence(info, actual, sequence);
459 }
460 }
461
462 /**
463 * Asserts that the given {@code Iterable} contains at least a null element.
464 * @param info contains information about the assertion.
465 * @param actual the given {@code Iterable}.
466 * @throws AssertionError if the given {@code Iterable} is {@code null}.
467 * @throws AssertionError if the given {@code Iterable} does not contain at least a null element.
468 */
469 public void assertContainsNull(AssertionInfo info, Iterable<?> actual) {
470 assertNotNull(info, actual);
471 if (!iterableContains(actual, null)) throw failures.failure(info, shouldContainNull(actual));
472 }
473
474 /**
475 * Asserts that the given {@code Iterable} does not contain null elements.
476 * @param info contains information about the assertion.
477 * @param actual the given {@code Iterable}.
478 * @throws AssertionError if the given {@code Iterable} is {@code null}.
479 * @throws AssertionError if the given {@code Iterable} contains a null element.
480 */
481 public void assertDoesNotContainNull(AssertionInfo info, Iterable<?> actual) {
482 assertNotNull(info, actual);
483 if (iterableContains(actual, null)) throw failures.failure(info, shouldNotContainNull(actual));
484 }
485
486 /**
487 * Assert that each element of given {@code Iterable} satisfies the given condition.
488 * @param info contains information about the assertion.
489 * @param actual the given {@code Iterable}.
490 * @param condition the given {@code Condition}.
491 * @throws NullPointerException if the given condition is {@code null}.
492 * @throws AssertionError if a element cannot be cast to E.
493 * @throws AssertionError if one or more element not satisfy the given condition.
494 */
495 public <E> void assertAre(AssertionInfo info, Iterable<?> actual, Condition<E> condition) {
496 assertNotNull(info, actual);
497 conditions.assertIsNotNull(condition);
498 try {
499 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
500 if (notSatisfiesCondition.isEmpty()) return;
501 throw failures.failure(info, elementsShouldBe(actual, notSatisfiesCondition, condition));
502 } catch (ClassCastException e) {
503 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
504 }
505 }
506
507 /**
508 * Assert that each element of given {@code Iterable} not satisfies the given condition.
509 * @param info contains information about the assertion.
510 * @param actual the given {@code Iterable}.
511 * @param condition the given {@code Condition}.
512 * @throws NullPointerException if the given condition is {@code null}.
513 * @throws AssertionError if a element cannot be cast to E.
514 * @throws AssertionError if one or more element satisfy the given condition.
515 */
516 public <E> void assertAreNot(AssertionInfo info, Iterable<?> actual, Condition<E> condition) {
517 assertNotNull(info, actual);
518 conditions.assertIsNotNull(condition);
519 try {
520 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
521 if (satisfiesCondition.isEmpty()) return;
522 throw failures.failure(info, elementsShouldNotBe(actual, satisfiesCondition, condition));
523 } catch (ClassCastException e) {
524 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
525 }
526 }
527
528 /**
529 * Assert that each element of given {@code Iterable} satisfies the given condition.
530 * @param info contains information about the assertion.
531 * @param actual the given {@code Iterable}.
532 * @param condition the given {@code Condition}.
533 * @throws NullPointerException if the given condition is {@code null}.
534 * @throws AssertionError if a element cannot be cast to E.
535 * @throws AssertionError if one or more element not satisfy the given condition.
536 */
537 public <E> void assertHave(AssertionInfo info, Iterable<?> actual, Condition<E> condition) {
538 assertNotNull(info, actual);
539 conditions.assertIsNotNull(condition);
540 try {
541 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
542 if (notSatisfiesCondition.isEmpty()) return;
543 throw failures.failure(info, elementsShouldHave(actual, notSatisfiesCondition, condition));
544 } catch (ClassCastException e) {
545 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
546 }
547 }
548
549 /**
550 * Assert that each element of given {@code Iterable} not satisfies the given condition.
551 * @param info contains information about the assertion.
552 * @param actual the given {@code Iterable}.
553 * @param condition the given {@code Condition}.
554 * @throws NullPointerException if the given condition is {@code null}.
555 * @throws AssertionError if a element cannot be cast to E.
556 * @throws AssertionError if one or more element satisfy the given condition.
557 */
558 public <E> void assertDoNotHave(AssertionInfo info, Iterable<?> actual, Condition<E> condition) {
559 assertNotNull(info, actual);
560 conditions.assertIsNotNull(condition);
561 try {
562 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
563 if (satisfiesCondition.isEmpty()) return;
564 throw failures.failure(info, elementsShouldNotHave(actual, satisfiesCondition, condition));
565 } catch (ClassCastException e) {
566 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
567 }
568 }
569
570 /**
571 * Assert that there is <b>at least</b> <i>n</i> elements in the actual {@code Iterable} satisfying the given
572 * condition.
573 * @param info contains information about the assertion.
574 * @param actual the given {@code Iterable}.
575 * @param n the minimum number of times the condition should be verified.
576 * @param condition the given {@code Condition}.
577 * @throws NullPointerException if the given condition is {@code null}.
578 * @throws AssertionError if a element cannot be cast to E.
579 * @throws AssertionError if the number of elements satisfying the given condition is < n.
580 */
581 public <E> void assertAreAtLeast(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
582 assertNotNull(info, actual);
583 conditions.assertIsNotNull(condition);
584 try {
585 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
586 if (satisfiesCondition.size() >= n) return;
587 throw failures.failure(info, elementsShouldBeAtLeast(actual, n, condition));
588 } catch (ClassCastException e) {
589 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
590 }
591 }
592
593 /**
594 * Assert that there is <b>at least</b> <i>n</i> elements in the actual {@code Iterable} <b>not</b> satisfying the
595 * given condition.
596 * @param info contains information about the assertion.
597 * @param actual the given {@code Iterable}.
598 * @param n the number of times the condition should not be verified at least.
599 * @param condition the given {@code Condition}.
600 * @throws NullPointerException if the given condition is {@code null}.
601 * @throws AssertionError if a element cannot be cast to E.
602 * @throws AssertionError if the number of elements not satisfying the given condition is < n.
603 */
604 public <E> void assertAreNotAtLeast(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
605 assertNotNull(info, actual);
606 conditions.assertIsNotNull(condition);
607 try {
608 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
609 if (notSatisfiesCondition.size() >= n) return;
610 throw failures.failure(info, elementsShouldNotBeAtLeast(actual, n, condition));
611 } catch (ClassCastException e) {
612 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
613 }
614 }
615
616 /**
617 * Assert that there is <b>at most</b> <i>n</i> elements in the actual {@code Iterable} satisfying the given
618 * condition.
619 * @param info contains information about the assertion.
620 * @param actual the given {@code Iterable}.
621 * @param n the number of times the condition should be at most verified.
622 * @param condition the given {@code Condition}.
623 * @throws NullPointerException if the given condition is {@code null}.
624 * @throws AssertionError if a element cannot be cast to E.
625 * @throws AssertionError if the number of elements satisfying the given condition is > n.
626 */
627 public <E> void assertAreAtMost(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
628 assertNotNull(info, actual);
629 conditions.assertIsNotNull(condition);
630 try {
631 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
632 if (satisfiesCondition.size() <= n) return;
633 throw failures.failure(info, elementsShouldNotBeAtMost(actual, n, condition));
634 } catch (ClassCastException e) {
635 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
636 }
637 }
638
639 /**
640 * Verifies that there is <b>at most</b> <i>n</i> elements in the actual {@code Iterable} <b>not</b> satisfying the
641 * given condition.
642 * @param info contains information about the assertion.
643 * @param actual the given {@code Iterable}.
644 * @param n the number of times the condition should not be verified at most.
645 * @param condition the given {@code Condition}.
646 * @throws NullPointerException if the given condition is {@code null}.
647 * @throws AssertionError if a element cannot be cast to E.
648 * @throws AssertionError if the number of elements not satisfying the given condition is > n.
649 */
650 public <E> void assertAreNotAtMost(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
651 assertNotNull(info, actual);
652 conditions.assertIsNotNull(condition);
653 try {
654 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
655 if (notSatisfiesCondition.size() <= n) return;
656 throw failures.failure(info, elementsShouldNotBeAtMost(actual, n, condition));
657 } catch (ClassCastException e) {
658 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
659 }
660 }
661
662 /**
663 * Verifies that there is <b>exactly</b> <i>n</i> elements in the actual {@code Iterable} satisfying the given
664 * condition.
665 * @param info contains information about the assertion.
666 * @param actual the given {@code Iterable}.
667 * @param n the exact number of times the condition should be verified.
668 * @param condition the given {@code Condition}.
669 * @throws NullPointerException if the given condition is {@code null}.
670 * @throws AssertionError if a element cannot be cast to E.
671 * @throws AssertionError if the number of elements satisfying the given condition is ≠ n.
672 */
673 public <E> void assertAreExactly(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
674 assertNotNull(info, actual);
675 conditions.assertIsNotNull(condition);
676 try {
677 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
678 if (satisfiesCondition.size() == n) return;
679 throw failures.failure(info, elementsShouldBeExactly(actual, n, condition));
680 } catch (ClassCastException e) {
681 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
682 }
683 }
684
685 /**
686 * Verifies that there is <b>exactly</b> <i>n</i> elements in the actual {@code Iterable} <b>not</b> satisfying the
687 * given condition.
688 * @param info contains information about the assertion.
689 * @param actual the given {@code Iterable}.
690 * @param n the exact number of times the condition should not be verified.
691 * @param condition the given {@code Condition}.
692 * @throws NullPointerException if the given condition is {@code null}.
693 * @throws AssertionError if a element cannot be cast to E.
694 * @throws AssertionError if the number of elements not satisfying the given condition is ≠ n.
695 */
696 public <E> void assertAreNotExactly(AssertionInfo info, Iterable<?> actual, int n, Condition<E> condition) {
697 assertNotNull(info, actual);
698 conditions.assertIsNotNull(condition);
699 try {
700 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
701 if (notSatisfiesCondition.size() == n) return;
702 throw failures.failure(info, elementsShouldNotBeExactly(actual, n, condition));
703 } catch (ClassCastException e) {
704 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
705 }
706 }
707
708 /**
709 * An alias method of {@link #assertAreAtLeast(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent
710 * api (same logic, only error message differs).
711 */
712 public <E> void assertHaveAtLeast(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
713 assertNotNull(info, actual);
714 conditions.assertIsNotNull(condition);
715 try {
716 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
717 if (satisfiesCondition.size() >= times) return;
718 throw failures.failure(info, elementsShouldHaveAtLeast(actual, times, condition));
719 } catch (ClassCastException e) {
720 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
721 }
722 }
723
724 /**
725 * An alias method of {@link #assertAreNotAtLeast(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent
726 * api (same logic, only error message differs).
727 */
728 public <E> void assertDoNotHaveAtLeast(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
729 assertNotNull(info, actual);
730 conditions.assertIsNotNull(condition);
731 try {
732 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
733 if (notSatisfiesCondition.size() >= times) return;
734 throw failures.failure(info, elementsShouldNotHaveAtLeast(actual, times, condition));
735 } catch (ClassCastException e) {
736 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
737 }
738 }
739
740 /**
741 * An alias method of {@link #assertAreAtMost(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent api
742 * (same logic, only error message differs).
743 */
744 public <E> void assertHaveAtMost(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
745 assertNotNull(info, actual);
746 conditions.assertIsNotNull(condition);
747 try {
748 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
749 if (satisfiesCondition.size() <= times) return;
750 throw failures.failure(info, elementsShouldHaveAtMost(actual, times, condition));
751 } catch (ClassCastException e) {
752 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
753 }
754 }
755
756 /**
757 * An alias method of {@link #assertAreNotAtMost(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent
758 * api (same logic, only error message differs).
759 */
760 public <E> void assertDoNotHaveAtMost(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
761 assertNotNull(info, actual);
762 conditions.assertIsNotNull(condition);
763 try {
764 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
765 if (notSatisfiesCondition.size() <= times) return;
766 throw failures.failure(info, elementsShouldNotHaveAtMost(actual, times, condition));
767 } catch (ClassCastException e) {
768 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
769 }
770 }
771
772 /**
773 * An alias method of {@link #assertAreExactly(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent
774 * api (same logic, only error message differs).
775 */
776 public <E> void assertHaveExactly(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
777 assertNotNull(info, actual);
778 conditions.assertIsNotNull(condition);
779 try {
780 List<E> satisfiesCondition = satisfiesCondition(actual, condition);
781 if (satisfiesCondition.size() == times) return;
782 throw failures.failure(info, elementsShouldHaveExactly(actual, times, condition));
783 } catch (ClassCastException e) {
784 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
785 }
786 }
787
788 /**
789 * An alias method of {@link #assertAreNotExactly(AssertionInfo, Iterable, int, Condition)} to provide a richer fluent
790 * api (same logic, only error message differs).
791 */
792 public <E> void assertDoNotHaveExactly(AssertionInfo info, Iterable<?> actual, int times, Condition<E> condition) {
793 assertNotNull(info, actual);
794 conditions.assertIsNotNull(condition);
795 try {
796 List<E> notSatisfiesCondition = notSatisfiesCondition(actual, condition);
797 if (notSatisfiesCondition.size() == times) return;
798 throw failures.failure(info, elementsShouldNotHaveExactly(actual, times, condition));
799 } catch (ClassCastException e) {
800 throw failures.failure(info, shouldBeSameGenericBetweenIterableAndCondition(actual, condition));
801 }
802 }
803
804 private void checkIsNotNullAndNotEmpty(Object[] values) {
805 if (values == null) throw arrayOfValuesToLookForIsNull();
806 if (values.length == 0) throw arrayOfValuesToLookForIsEmpty();
807 }
808
809 private void assertNotNull(AssertionInfo info, Iterable<?> actual) {
810 Objects.instance().assertNotNull(info, actual);
811 }
812
813 private AssertionError actualDoesNotEndWithSequence(AssertionInfo info, Iterable<?> actual, Object[] sequence) {
814 return failures.failure(info, shouldEndWith(actual, sequence, comparisonStrategy));
815 }
816
817 @SuppressWarnings("unchecked")
818 private <E> List<E> notSatisfiesCondition(Iterable<?> actual, Condition<E> condition) {
819 List<E> notSatisfiesCondition = new LinkedList<E>();
820 for (Object o : actual) {
821 if (!condition.matches((E) o)) {
822 notSatisfiesCondition.add((E) o);
823 }
824 }
825 return notSatisfiesCondition;
826 }
827
828 @SuppressWarnings("unchecked")
829 private <E> List<E> satisfiesCondition(Iterable<?> actual, Condition<E> condition) {
830 List<E> satisfiesCondition = new LinkedList<E>();
831 for (Object o : actual) {
832 if (condition.matches((E) o)) {
833 satisfiesCondition.add((E) o);
834 }
835 }
836 return satisfiesCondition;
837 }
838
839 static public NullPointerException iterableToLookForIsNull() {
840 return new NullPointerException("The iterable to look for should not be null");
841 }
842
843 static public IllegalArgumentException iterableToLookForIsEmpty() {
844 return new IllegalArgumentException("The iterable to look for should not be empty");
845 }
846
847 }