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