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 }