Repository: assertj/assertj

Problem statement:
New Iterable assertion : doesNotContainAnyElementsOf(Iterable)
Exact signature :

``` java
public S doesNotContainAnyElementsOf(Iterable<? extends T> iterable)
```



Hints:
What the difference with the function :

``` java
  /**
   * Verifies that the actual group does not contain the given values.
   * 
   * @param values the given values.
   * @return {@code this} assertion object.
   * @throws NullPointerException if the given argument is {@code null}.
   * @throws IllegalArgumentException if the given argument is an empty array.
   * @throws AssertionError if the actual group is {@code null}.
   * @throws AssertionError if the actual group contains any of the given values.
   */
  S doesNotContain(T... values);
```

(why an another name if the function does the same things ?)

The assertion is almost the same, it is just handy for users not to have to convert the Iterable to an array.
I think though this valuable because it avoid users write boilerplate code.

yes, I understand the need, but why change the name ?

Well it can be confusing, when you call `doesNotContain(Iterable)` does it mean you assert that given Iterable is not present or its elements are not ? 
With `doesNotContainAnyElementsOf` I think there is no ambiguity.


Patch:
diff --git a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java
--- a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java
+++ b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java
@@ -126,12 +126,37 @@ public S containsSequence(T... sequence) {
     return myself;
   }
 
-  /** {@inheritDoc} */
   public S doesNotContain(T... values) {
     iterables.assertDoesNotContain(info, actual, values);
     return myself;
   }
 
+  /**
+   * Verifies that the actual group does not contain the given values.
+   * 
+   * <pre>
+   * // this assertion succeed :
+   * List&lt;String&gt; actual = new ArrayList(&quot;GIT&quot;, &quot;CSV&quot;, &quot;SOURCESAFE&quot;);
+   * List&lt;String&gt; values = new ArrayList(&quot;git&quot;, &quot;csv&quot;, &quot;subversion&quot;);
+   * assertThat(actual).doesNotContainAnyElementsOf(values);
+   * 
+   * // This one failed : 
+   * List&lt;String&gt; actual = new ArrayList(&quot;GIT&quot;, &quot;csv&quot;, &quot;SOURCESAFE&quot;);
+   * List&lt;String&gt; values = new ArrayList(&quot;git&quot;, &quot;csv&quot;, &quot;subversion&quot;);
+   * assertThat(actual).doesNotContainAnyElementsOf(values);
+   * 
+   * @param values the given values.
+   * @return {@code this} assertion object.
+   * @throws NullPointerException if the given argument is {@code null}.
+   * @throws IllegalArgumentException if the given argument is an empty iterable.
+   * @throws AssertionError if the actual group is {@code null}.
+   * @throws AssertionError if the actual group contains any of the given values.
+   */
+  public S doesNotContainAnyElementsOf(Iterable<? extends T> iterable) {
+    iterables.assertDoesNotContainAnyElementsOf(info, actual, iterable);
+    return myself;
+  }
+
   /** {@inheritDoc} */
   public S doesNotHaveDuplicates() {
     iterables.assertDoesNotHaveDuplicates(info, actual);
diff --git a/src/main/java/org/assertj/core/internal/CommonErrors.java b/src/main/java/org/assertj/core/internal/CommonErrors.java
--- a/src/main/java/org/assertj/core/internal/CommonErrors.java
+++ b/src/main/java/org/assertj/core/internal/CommonErrors.java
@@ -1,14 +1,14 @@
 /*
  * Created on Nov 24, 2010
  * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
- * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
  * 
  * Copyright @2010-2011 the original author or authors.
  */
@@ -16,7 +16,8 @@
 
 /**
  * @author Alex Ruiz
- * TODO : merge/use with ErrorMessages !
+ * 
+ *         TODO : merge/use with ErrorMessages !
  */
 public final class CommonErrors {
 
@@ -28,9 +29,18 @@ static NullPointerException iterableToLookForIsNull() {
     return new NullPointerException("The iterable to look for should not be null");
   }
 
+  static NullPointerException iterableOfValuesForIsNull() {
+    return new NullPointerException("The iterable of values to look for should not be null");
+  }
+
   static IllegalArgumentException arrayOfValuesToLookForIsEmpty() {
     return new IllegalArgumentException("The array of values to look for should not be empty");
   }
 
-  private CommonErrors() {}
+  static IllegalArgumentException iterableOfValuesToLookForIsEmpty() {
+    return new IllegalArgumentException("The iterable of values to look for should not be empty");
+  }
+
+  private CommonErrors() {
+  }
 }
diff --git a/src/main/java/org/assertj/core/internal/CommonValidations.java b/src/main/java/org/assertj/core/internal/CommonValidations.java
--- a/src/main/java/org/assertj/core/internal/CommonValidations.java
+++ b/src/main/java/org/assertj/core/internal/CommonValidations.java
@@ -16,6 +16,8 @@
 
 import static org.assertj.core.internal.CommonErrors.arrayOfValuesToLookForIsEmpty;
 import static org.assertj.core.internal.CommonErrors.arrayOfValuesToLookForIsNull;
+import static org.assertj.core.internal.CommonErrors.iterableOfValuesForIsNull;
+import static org.assertj.core.internal.CommonErrors.iterableOfValuesToLookForIsEmpty;
 
 import org.assertj.core.data.Index;
 import org.assertj.core.data.Offset;
@@ -49,15 +51,30 @@ static void checkIsNotEmpty(Object[] values) {
     }
   }
 
+  static void checkIsNotEmpty(Iterable<?> iterable) {
+    if (!iterable.iterator().hasNext()) {
+      throw iterableOfValuesToLookForIsEmpty();
+    }
+  }
+
   static void checkIsNotNull(Object[] values) {
     if (values == null) throw arrayOfValuesToLookForIsNull();
   }
 
+  static void checkIsNotNull(Iterable<?> iterable) {
+    if (iterable == null) throw iterableOfValuesForIsNull();
+  }
+
   static void checkIsNotNullAndNotEmpty(Object[] values) {
     checkIsNotNull(values);
     checkIsNotEmpty(values);
   }
 
+  static void checkIsNotNullAndNotEmpty(Iterable<?> iterable) {
+    checkIsNotNull(iterable);
+    checkIsNotEmpty(iterable);
+  }
+
   static void failIfEmptySinceActualIsNotEmpty(Object[] values) {
     if (values.length == 0) {
       throw new AssertionError("actual is not empty");
diff --git a/src/main/java/org/assertj/core/internal/Iterables.java b/src/main/java/org/assertj/core/internal/Iterables.java
--- a/src/main/java/org/assertj/core/internal/Iterables.java
+++ b/src/main/java/org/assertj/core/internal/Iterables.java
@@ -460,6 +460,23 @@ public void assertDoesNotContain(AssertionInfo info, Iterable<?> actual, Object[
     throw failures.failure(info, shouldNotContain(actual, values, found, comparisonStrategy));
   }
 
+  /**
+   * Asserts that the given {@code Iterable} does not contain the given values.
+   * 
+   * @param info contains information about the assertion.
+   * @param actual the given {@code Iterable}.
+   * @param values the values that are expected not to be in the given {@code Iterable}.
+   * @throws NullPointerException if the array of values is {@code null}.
+   * @throws IllegalArgumentException if the array of values is empty.
+   * @throws AssertionError if the given {@code Iterable} is {@code null}.
+   * @throws AssertionError if the given {@code Iterable} contains any of given values.
+   */
+  public <T> void assertDoesNotContainAnyElementsOf(AssertionInfo info, Iterable<T> actual, Iterable<? extends T> iterable) {
+    checkIsNotNullAndNotEmpty(iterable);
+    List<T> values = newArrayList(iterable);
+    assertDoesNotContain(info, actual, values.toArray());
+  }
+
   /**
    * Asserts that the given {@code Iterable} does not have duplicate values.
    * 


Test patch:
diff --git a/src/test/java/org/assertj/core/api/iterable/IterableAssert_doesNotContainAnyElementsOf_Test.java b/src/test/java/org/assertj/core/api/iterable/IterableAssert_doesNotContainAnyElementsOf_Test.java
new file mode 100644
--- /dev/null
+++ b/src/test/java/org/assertj/core/api/iterable/IterableAssert_doesNotContainAnyElementsOf_Test.java
@@ -0,0 +1,42 @@
+/*
+ * Created on May 7, 2013
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ * 
+ * Copyright @2010-2011 the original author or authors.
+ */
+package org.assertj.core.api.iterable;
+
+import org.assertj.core.api.AbstractIterableAssert;
+import org.assertj.core.api.ConcreteIterableAssert;
+import org.assertj.core.api.IterableAssertBaseTest;
+
+import static org.mockito.Mockito.verify;
+import static org.assertj.core.util.Lists.newArrayList;
+
+/**
+ * Tests for <code>{@link AbstractIterableAssert#doesNotContainAnyElementsOf(Iterable)}</code>.
+ * 
+ * @author William Delanoue
+ */
+public class IterableAssert_doesNotContainAnyElementsOf_Test extends IterableAssertBaseTest {
+
+  private final Iterable<String> values = newArrayList("Yoda", "Luke");
+
+  @Override
+  protected ConcreteIterableAssert<Object> invoke_api_method() {
+    return assertions.doesNotContainAnyElementsOf(values);
+  }
+
+  @Override
+  protected void verify_internal_effects() {
+    verify(iterables).assertDoesNotContainAnyElementsOf(getInfo(assertions), getActual(assertions), values);
+  }
+}
diff --git a/src/test/java/org/assertj/core/internal/iterables/Iterables_assertDoesNotContainAnyElementsOf_Test.java b/src/test/java/org/assertj/core/internal/iterables/Iterables_assertDoesNotContainAnyElementsOf_Test.java
new file mode 100644
--- /dev/null
+++ b/src/test/java/org/assertj/core/internal/iterables/Iterables_assertDoesNotContainAnyElementsOf_Test.java
@@ -0,0 +1,118 @@
+/*
+ * Created on Oct 12, 2010
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ * 
+ * Copyright @2010-2011 the original author or authors.
+ */
+package org.assertj.core.internal.iterables;
+
+import static java.util.Collections.emptyList;
+import static org.assertj.core.error.ShouldNotContain.shouldNotContain;
+import static org.assertj.core.test.ErrorMessages.*;
+import static org.assertj.core.test.TestData.someInfo;
+import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
+import static org.assertj.core.util.FailureMessages.actualIsNull;
+import static org.assertj.core.util.Lists.newArrayList;
+import static org.assertj.core.util.Sets.newLinkedHashSet;
+
+import static org.mockito.Mockito.verify;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.assertj.core.api.AssertionInfo;
+import org.assertj.core.internal.Iterables;
+import org.assertj.core.internal.IterablesBaseTest;
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link Iterables#assertDoesNotContainAnyElementsOf(AssertionInfo, Iterable, Iterable)}</code>.
+ * 
+ * @author Alex Ruiz
+ * @author Joel Costigliola
+ * @author William Delanoue
+ */
+public class Iterables_assertDoesNotContainAnyElementsOf_Test extends IterablesBaseTest {
+
+  private static List<String> actual = newArrayList("Luke", "Yoda", "Leia");;
+
+  @Test
+  public void should_pass_if_actual_does_not_contain_given_values() {
+    iterables.assertDoesNotContainAnyElementsOf(someInfo(), actual, newArrayList("Han"));
+  }
+
+  @Test
+  public void should_pass_if_actual_does_not_contain_given_values_even_if_duplicated() {
+    iterables.assertDoesNotContainAnyElementsOf(someInfo(), actual, newArrayList("Han", "Han", "Anakin"));
+  }
+
+  @Test
+  public void should_throw_error_if_array_of_values_to_look_for_is_empty() {
+    thrown.expectIllegalArgumentException(iterableValuesToLookForIsEmpty());
+    iterables.assertDoesNotContainAnyElementsOf(someInfo(), actual, Collections.<String>emptyList());
+  }
+
+  @Test
+  public void should_throw_error_if_array_of_values_to_look_for_is_null() {
+    thrown.expectNullPointerException(iterableValuesToLookForIsNull());
+    iterables.assertDoesNotContainAnyElementsOf(someInfo(), emptyList(), null);
+  }
+
+  @Test
+  public void should_fail_if_actual_is_null() {
+    thrown.expectAssertionError(actualIsNull());
+    iterables.assertDoesNotContainAnyElementsOf(someInfo(), null, newArrayList("Yoda"));
+  }
+
+  @Test
+  public void should_fail_if_actual_contains_given_values() {
+    AssertionInfo info = someInfo();
+    List<String> expected = newArrayList("Luke", "Yoda", "Han");
+    try {
+      iterables.assertDoesNotContainAnyElementsOf(info, actual, expected);
+    } catch (AssertionError e) {
+      verify(failures).failure(info, shouldNotContain(actual, expected.toArray(), newLinkedHashSet("Luke", "Yoda")));
+      return;
+    }
+    failBecauseExpectedAssertionErrorWasNotThrown();
+  }
+
+  // ------------------------------------------------------------------------------------------------------------------
+  // tests using a custom comparison strategy
+  // ------------------------------------------------------------------------------------------------------------------
+
+  @Test
+  public void should_pass_if_actual_does_not_contain_given_values_according_to_custom_comparison_strategy() {
+    iterablesWithCaseInsensitiveComparisonStrategy.assertDoesNotContainAnyElementsOf(someInfo(), actual,
+        newArrayList("Han"));
+  }
+
+  @Test
+  public void should_pass_if_actual_does_not_contain_given_values_even_if_duplicated_according_to_custom_comparison_strategy() {
+    iterablesWithCaseInsensitiveComparisonStrategy.assertDoesNotContainAnyElementsOf(someInfo(), actual,
+        newArrayList("Han", "Han", "Anakin"));
+  }
+
+  @Test
+  public void should_fail_if_actual_contains_given_values_according_to_custom_comparison_strategy() {
+    AssertionInfo info = someInfo();
+    List<String> expected = newArrayList("LuKe", "YODA", "Han");
+    try {
+      iterablesWithCaseInsensitiveComparisonStrategy.assertDoesNotContainAnyElementsOf(info, actual, expected);
+    } catch (AssertionError e) {
+      verify(failures).failure(info,
+          shouldNotContain(actual, expected.toArray(), newLinkedHashSet("LuKe", "YODA"), comparisonStrategy));
+      return;
+    }
+    failBecauseExpectedAssertionErrorWasNotThrown();
+  }
+
+}
diff --git a/src/test/java/org/assertj/core/test/ErrorMessages.java b/src/test/java/org/assertj/core/test/ErrorMessages.java
--- a/src/test/java/org/assertj/core/test/ErrorMessages.java
+++ b/src/test/java/org/assertj/core/test/ErrorMessages.java
@@ -84,6 +84,14 @@ public static String valuesToLookForIsNull() {
     return "The array of values to look for should not be null";
   }
 
+  public static String iterableValuesToLookForIsEmpty() {
+    return "The iterable of values to look for should not be empty";
+  }
+
+  public static String iterableValuesToLookForIsNull() {
+    return "The iterable of values to look for should not be null";
+  }
+
   public static String dateToCompareActualWithIsNull() {
     return "The date to compare actual with should not be null";
   }