Repository: assertj/assertj

Problem statement:
containsExactlyInAnyOrderElementsOf
#### Summary

Variation of `containsExactlyInAnyOrder` with an `Iterable` parameter.
The assertion is named `containsExactlyInAnyOrderElementsOf` for consistency with the API (ex `containsExactlyElementsOf`).

#### Example

```java
// an Iterable is used in the example but it would also work with an array
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya, vilya);
Iterable<Ring> elvesRingsSomeMissing = newArrayList(vilya, nenya, narya);
Iterable<Ring> elvesRingsDifferentOrder = newArrayList(nenya, narya, vilya, vilya);

 // assertion will pass
 assertThat(elvesRings).containsExactlyInAnyOrderElementsOf(elvesRingsDifferentOrder);

 // assertion will fail as vilya is contained twice in elvesRings.
 assertThat(elvesRings).containsExactlyInAnyOrderElementsOf(elvesRingsSomeMissing);
```

#### Java 8 specific ?

* NO  : create Pull Request from the `2.x` branch



containsExactlyInAnyOrderElementsOf
#### Summary

Variation of `containsExactlyInAnyOrder` with an `Iterable` parameter.
The assertion is named `containsExactlyInAnyOrderElementsOf` for consistency with the API (ex `containsExactlyElementsOf`).

#### Example

```java
// an Iterable is used in the example but it would also work with an array
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya, vilya);
Iterable<Ring> elvesRingsSomeMissing = newArrayList(vilya, nenya, narya);
Iterable<Ring> elvesRingsDifferentOrder = newArrayList(nenya, narya, vilya, vilya);

 // assertion will pass
 assertThat(elvesRings).containsExactlyInAnyOrderElementsOf(elvesRingsDifferentOrder);

 // assertion will fail as vilya is contained twice in elvesRings.
 assertThat(elvesRings).containsExactlyInAnyOrderElementsOf(elvesRingsSomeMissing);
```

#### Java 8 specific ?

* NO  : create Pull Request from the `2.x` branch





Hints:

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
@@ -222,6 +222,14 @@ public SELF containsExactlyInAnyOrder(@SuppressWarnings("unchecked") ELEMENT...
     return myself;
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public SELF containsExactlyInAnyOrderElementsOf(Iterable<? extends ELEMENT> values) {
+    return containsExactlyInAnyOrder(toArray(values));
+  }
+
   /**
    * {@inheritDoc}
    */
diff --git a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java
--- a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java
+++ b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java
@@ -358,6 +358,13 @@ public SELF containsExactlyInAnyOrder(@SuppressWarnings("unchecked") ELEMENT...
     arrays.assertContainsExactlyInAnyOrder(info, actual, values);
     return myself;
   }
+  /**
+   * {@inheritDoc
+   */
+  @Override
+  public SELF containsExactlyInAnyOrderElementsOf(Iterable<? extends ELEMENT> values) {
+    return containsExactlyInAnyOrder(toArray(values));
+  }
 
   /**
    * Same as {@link #containsExactly(Object...)} but handles the {@link Iterable} to array conversion : verifies that
diff --git a/src/main/java/org/assertj/core/api/AtomicReferenceArrayAssert.java b/src/main/java/org/assertj/core/api/AtomicReferenceArrayAssert.java
--- a/src/main/java/org/assertj/core/api/AtomicReferenceArrayAssert.java
+++ b/src/main/java/org/assertj/core/api/AtomicReferenceArrayAssert.java
@@ -439,6 +439,35 @@ public AtomicReferenceArrayAssert<T> containsExactlyInAnyOrder(@SuppressWarnings
     return myself;
   }
 
+  /**
+   * Verifies that the actual AtomicReferenceArray contains exactly the given values and nothing else, <b>in any order</b>.<br>
+   *
+   * <p>
+   * Example :
+   * <pre><code class='java'>
+   * AtomicReferenceArray&lt;Ring&gt; elvesRings = new AtomicReferenceArray(new Ring[]{vilya, nenya, narya, vilya});
+   * AtomicReferenceArray&lt;Ring&gt; elvesRingsSomeMissing = new AtomicReferenceArray(new Ring[]{vilya, nenya, narya});
+   * AtomicReferenceArray&lt;Ring&gt; elvesRingsDifferentOrder = new AtomicReferenceArray(new Ring[]{nenya, narya, vilya, vilya});
+   *
+   * // assertion will pass
+   * assertThat(elvesRings).containsExactlyInAnyOrder(elvesRingsDifferentOrder);
+   *
+   * // assertion will fail as vilya is contained twice in elvesRings.
+   * assertThat(elvesRings).containsExactlyInAnyOrder(elvesRingsSomeMissing);</code></pre>
+   *
+   * @param values the given values.
+   * @return {@code this} assertion object.
+   * @throws NullPointerException if the given argument is {@code null}.
+   * @throws AssertionError if the actual group is {@code null}.
+   * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group
+   *           contains some or none of the given values, or the actual group contains more values than the given ones.
+   * @since 2.9.0 / 3.9.0
+   */
+  @Override
+  public AtomicReferenceArrayAssert<T> containsExactlyInAnyOrderElementsOf(Iterable<? extends T> values) {
+    return containsExactlyInAnyOrder(toArray(values));
+  }
+
   /**
    * Same as {@link #containsExactly(Object...)} but handles the {@link Iterable} to array conversion : verifies that
    * actual contains all elements of the given {@code Iterable} and nothing else <b>in the same order</b>.
diff --git a/src/main/java/org/assertj/core/api/ObjectEnumerableAssert.java b/src/main/java/org/assertj/core/api/ObjectEnumerableAssert.java
--- a/src/main/java/org/assertj/core/api/ObjectEnumerableAssert.java
+++ b/src/main/java/org/assertj/core/api/ObjectEnumerableAssert.java
@@ -149,6 +149,32 @@ public interface ObjectEnumerableAssert<SELF extends ObjectEnumerableAssert<SELF
    */
   SELF containsExactlyInAnyOrder(@SuppressWarnings("unchecked") ELEMENT... values);
 
+  /**
+   * Verifies that the actual group contains exactly the given values and nothing else, <b>in any order</b>.<br>
+   *
+   * <p>
+   * Example :
+   * <pre><code class='java'> // an Iterable is used in the example but it would also work with an array
+   * Iterable&lt;Ring&gt; elvesRings = newArrayList(vilya, nenya, narya, vilya);
+   * Iterable&lt;Ring&gt; elvesRingsSomeMissing = newArrayList(vilya, nenya, narya);
+   * Iterable&lt;Ring&gt; elvesRingsDifferentOrder = newArrayList(nenya, narya, vilya, vilya);
+   *
+   * // assertion will pass
+   * assertThat(elvesRings).containsExactlyInAnyOrder(elvesRingsDifferentOrder);
+   *
+   * // assertion will fail as vilya is contained twice in elvesRings.
+   * assertThat(elvesRings).containsExactlyInAnyOrder(elvesRingsSomeMissing);</code></pre>
+   *
+   * @param values the given values.
+   * @return {@code this} assertion object.
+   * @throws NullPointerException if the given argument is {@code null}.
+   * @throws AssertionError if the actual group is {@code null}.
+   * @throws AssertionError if the actual group does not contain the given values, i.e. the actual group
+   *           contains some or none of the given values, or the actual group contains more values than the given ones.
+   * @since 2.9.0 / 3.9.0
+   */
+  SELF containsExactlyInAnyOrderElementsOf(Iterable<? extends ELEMENT> values);
+
   /**
    * Verifies that the actual group contains the given sequence in the correct order and <b>without extra values between the sequence values</b>.
    * <p> 


Test patch:
diff --git a/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java b/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java
new file mode 100644
--- /dev/null
+++ b/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java
@@ -0,0 +1,37 @@
+/**
+ * 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 2012-2017 the original author or authors.
+ */
+package org.assertj.core.api.atomic.referencearray;
+
+import static org.assertj.core.util.Lists.newArrayList;
+import static org.mockito.Mockito.verify;
+
+import org.assertj.core.api.AtomicReferenceArrayAssert;
+import org.assertj.core.api.AtomicReferenceArrayAssertBaseTest;
+
+/**
+ * Test for {@link AtomicReferenceArrayAssert#containsExactlyInAnyOrderElementsOf(Iterable)}
+ * @author Filip Hrisafov
+ */
+public class AtomicReferenceArrayAssert_containsExactlyInAnyOrderElementsOf_Test
+  extends AtomicReferenceArrayAssertBaseTest {
+
+  @Override
+  protected AtomicReferenceArrayAssert<Object> invoke_api_method() {
+    return assertions.containsExactlyInAnyOrderElementsOf(newArrayList("Yoda", "Luke"));
+  }
+
+  @Override
+  protected void verify_internal_effects() {
+    verify(arrays).assertContainsExactlyInAnyOrder(info(), internalArray(), new String[] { "Yoda", "Luke" });
+  }
+}
diff --git a/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_usingFieldByFieldElementComparator_Test.java b/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_usingFieldByFieldElementComparator_Test.java
--- a/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_usingFieldByFieldElementComparator_Test.java
+++ b/src/test/java/org/assertj/core/api/atomic/referencearray/AtomicReferenceArrayAssert_usingFieldByFieldElementComparator_Test.java
@@ -17,6 +17,7 @@
 import static org.assertj.core.test.AlwaysEqualComparator.ALWAY_EQUALS_STRING;
 import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
 import static org.assertj.core.util.Arrays.array;
+import static org.assertj.core.util.Lists.newArrayList;
 
 import java.util.Comparator;
 import java.util.Objects;
@@ -106,6 +107,14 @@ public void successful_containsExactlyInAnyOrder_assertion_using_field_by_field_
                                                                                       new Snake(15));
   }
 
+  @Test
+  public void successful_containsExactlyInAnyOrderElementsOf_assertion_using_field_by_field_element_comparator_with_heterogeneous_array() {
+    Snake snake = new Snake(15);
+    AtomicReferenceArray<Animal> array1 = new AtomicReferenceArray<>(array(new Bird("White"), snake, snake));
+    assertThat(array1).usingFieldByFieldElementComparator().containsExactlyInAnyOrderElementsOf(
+      newArrayList(new Snake(15), new Bird("White"), new Snake(15)));
+  }
+
   @Test
   public void successful_containsOnly_assertion_using_field_by_field_element_comparator_with_unordered_array() {
     Person goodObiwan = new Person("Obi-Wan", "Kenobi", "good man");
diff --git a/src/test/java/org/assertj/core/api/iterable/IterableAssert_containsExactlyInAnyOrderElementsOf_Test.java b/src/test/java/org/assertj/core/api/iterable/IterableAssert_containsExactlyInAnyOrderElementsOf_Test.java
new file mode 100644
--- /dev/null
+++ b/src/test/java/org/assertj/core/api/iterable/IterableAssert_containsExactlyInAnyOrderElementsOf_Test.java
@@ -0,0 +1,39 @@
+/**
+ * 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 2012-2017 the original author or authors.
+ */
+package org.assertj.core.api.iterable;
+
+import static org.mockito.Mockito.verify;
+
+import org.assertj.core.api.AbstractIterableAssert;
+import org.assertj.core.api.ConcreteIterableAssert;
+import org.assertj.core.api.IterableAssertBaseTest;
+import org.assertj.core.util.Lists;
+
+/**
+ * Tests for {@link AbstractIterableAssert#containsExactlyInAnyOrderElementsOf(Iterable)}.
+ *
+ * @author Filip Hrisafov
+ */
+public class IterableAssert_containsExactlyInAnyOrderElementsOf_Test extends IterableAssertBaseTest {
+
+  @Override
+  protected ConcreteIterableAssert<Object> invoke_api_method() {
+    return assertions.containsExactlyInAnyOrderElementsOf(Lists.newArrayList("Yoda", "Luke", "Yoda"));
+  }
+
+  @Override
+  protected void verify_internal_effects() {
+    Object[] values = { "Yoda", "Luke", "Yoda" };
+    verify(iterables).assertContainsExactlyInAnyOrder(getInfo(assertions), getActual(assertions), values);
+  }
+}
diff --git a/src/test/java/org/assertj/core/api/iterable/IterableAssert_usingFieldByFieldElementComparator_Test.java b/src/test/java/org/assertj/core/api/iterable/IterableAssert_usingFieldByFieldElementComparator_Test.java
--- a/src/test/java/org/assertj/core/api/iterable/IterableAssert_usingFieldByFieldElementComparator_Test.java
+++ b/src/test/java/org/assertj/core/api/iterable/IterableAssert_usingFieldByFieldElementComparator_Test.java
@@ -105,6 +105,14 @@ public void successful_containsExactlyInAnyOrder_assertion_using_field_by_field_
                                                                                      new Snake(15));
   }
 
+  @Test
+  public void successful_containsExactlyInAnyOrderElementsOf_assertion_using_field_by_field_element_comparator_with_heterogeneous_list() {
+    Snake snake = new Snake(15);
+    List<Animal> list1 = newArrayList(new Bird("White"), snake, snake);
+    assertThat(list1).usingFieldByFieldElementComparator().containsExactlyInAnyOrderElementsOf(
+      newArrayList(new Snake(15), new Bird("White"), new Snake(15)));
+  }
+
   @Test
   public void successful_containsOnly_assertion_using_field_by_field_element_comparator_with_unordered_list() {
     Person goodObiwan = new Person("Obi-Wan", "Kenobi", "good man");
diff --git a/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java b/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java
new file mode 100644
--- /dev/null
+++ b/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_containsExactlyInAnyOrderElementsOf_Test.java
@@ -0,0 +1,38 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ * <p>
+ * Copyright 2012-2017 the original author or authors.
+ */
+package org.assertj.core.api.objectarray;
+
+import static org.assertj.core.util.Lists.newArrayList;
+import static org.mockito.Mockito.verify;
+
+import org.assertj.core.api.ObjectArrayAssert;
+import org.assertj.core.api.ObjectArrayAssertBaseTest;
+
+/**
+ * Tests for {@link ObjectArrayAssert#containsExactlyInAnyOrderElementsOf(Iterable)}.
+ *
+ * @author Filip Hrisafov
+ */
+public class ObjectArrayAssert_containsExactlyInAnyOrderElementsOf_Test extends ObjectArrayAssertBaseTest {
+
+  @Override
+  protected ObjectArrayAssert<Object> invoke_api_method() {
+    return assertions.containsExactlyInAnyOrderElementsOf(newArrayList("Yoda", "Luke"));
+  }
+
+  @Override
+  protected void verify_internal_effects() {
+    verify(arrays)
+      .assertContainsExactlyInAnyOrder(getInfo(assertions), getActual(assertions), new String[] { "Yoda", "Luke" });
+  }
+}
diff --git a/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_usingFieldByFieldElementComparator_Test.java b/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_usingFieldByFieldElementComparator_Test.java
--- a/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_usingFieldByFieldElementComparator_Test.java
+++ b/src/test/java/org/assertj/core/api/objectarray/ObjectArrayAssert_usingFieldByFieldElementComparator_Test.java
@@ -15,6 +15,7 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.test.AlwaysEqualComparator.ALWAY_EQUALS_STRING;
 import static org.assertj.core.util.Arrays.array;
+import static org.assertj.core.util.Lists.newArrayList;
 
 import java.util.Comparator;
 import java.util.Objects;
@@ -102,6 +103,14 @@ public void successful_containsExactlyInAnyOrder_assertion_using_field_by_field_
                                                                                       new Snake(15));
   }
 
+  @Test
+  public void successful_containsExactlyInAnyOrderElementsOf_assertion_using_field_by_field_element_comparator_with_heterogeneous_array() {
+    Snake snake = new Snake(15);
+    Animal[] array1 = array(new Bird("White"), snake, snake);
+    assertThat(array1).usingFieldByFieldElementComparator().containsExactlyInAnyOrderElementsOf(
+      newArrayList(new Snake(15), new Bird("White"), new Snake(15)));
+  }
+
   @Test
   public void successful_containsOnly_assertion_using_field_by_field_element_comparator_with_unordered_array() {
     Person goodObiwan = new Person("Obi-Wan", "Kenobi", "good man");