diff --git a/core/src/main/java/com/google/common/truth/IterableSubject.java b/core/src/main/java/com/google/common/truth/IterableSubject.java index 24757edcd..f02410533 100644 --- a/core/src/main/java/com/google/common/truth/IterableSubject.java +++ b/core/src/main/java/com/google/common/truth/IterableSubject.java @@ -298,22 +298,22 @@ public final Ordered containsAtLeastElementsIn(Iterable expectedIterable) { return failAtLeast(expected, missing); } - /* - * TODO(cpovirk): In the NotInOrder case, also include a Fact that shows _only_ the required - * elements (that is, without any extras) but in the order they were actually found. That should - * make it easier for users to compare the actual order of the required elements to the expected - * order. Or, if that's too much trouble, at least try to find a better title for the full - * actual iterable than the default of "but was," which may _sound_ like it should show only the - * required elements, rather than the full actual iterable. - */ return ordered ? IN_ORDER : new Ordered() { @Override public void inOrder() { - failWithActual( - simpleFact("required elements were all found, but order was wrong"), - fact("expected order for required elements", expected)); + ImmutableList.Builder facts = ImmutableList.builder(); + facts.add(simpleFact("required elements were all found, but order was wrong")); + facts.add(fact("expected order for required elements", expected)); + List actualOrder = Lists.newArrayList(IterableSubject.this.actual); + if (actualOrder.retainAll(expected)) { + facts.add(fact("but order was", actualOrder)); + facts.add(fullContents()); + failWithoutActual(facts.build()); + } else { + failWithActual(facts.build()); + } } }; } @@ -841,7 +841,9 @@ private void pairwiseCheck(String expectedFact, PairwiseChecker checker) { } } - /** @deprecated You probably meant to call {@link #containsNoneOf} instead. */ + /** + * @deprecated You probably meant to call {@link #containsNoneOf} instead. + */ @Override @Deprecated public void isNoneOf( @@ -849,7 +851,9 @@ public void isNoneOf( super.isNoneOf(first, second, rest); } - /** @deprecated You probably meant to call {@link #containsNoneIn} instead. */ + /** + * @deprecated You probably meant to call {@link #containsNoneIn} instead. + */ @Override @Deprecated public void isNotIn(Iterable iterable) { @@ -1955,8 +1959,7 @@ private final class Pairer { * Returns a {@link Pairing} of the given expected and actual values, or {@code null} if the * expected values are not uniquely keyed. */ - @Nullable - Pairing pair( + @Nullable Pairing pair( List expectedValues, List actualValues, Correspondence.ExceptionStore exceptions) { diff --git a/core/src/test/java/com/google/common/truth/IterableSubjectTest.java b/core/src/test/java/com/google/common/truth/IterableSubjectTest.java index beab5ff71..881a1f94d 100644 --- a/core/src/test/java/com/google/common/truth/IterableSubjectTest.java +++ b/core/src/test/java/com/google/common/truth/IterableSubjectTest.java @@ -390,6 +390,20 @@ public void iterableContainsAtLeastInOrderWithFailure() { "expected order for required elements", "but was"); assertFailureValue("expected order for required elements", "[null, 1, 3]"); + assertFailureValue("but was", "[1, null, 3]"); + } + + @Test + public void iterableContainsAtLeastInOrderWithFailureWithActualOrder() { + expectFailureWhenTestingThat(asList(1, 2, null, 3, 4)).containsAtLeast(null, 1, 3).inOrder(); + assertFailureKeys( + "required elements were all found, but order was wrong", + "expected order for required elements", + "but order was", + "full contents"); + assertFailureValue("expected order for required elements", "[null, 1, 3]"); + assertFailureValue("but order was", "[1, null, 3]"); + assertFailureValue("full contents", "[1, 2, null, 3, 4]"); } @Test