0

I just implemented my own Insertion sort and trying to verify functionalities including stability.

For a given list of unsorted elements, I'm trying to verify my code against Collections#sort(List) method.

List<E> unsorted = ...; // <E extends Comparable<? super E>>

List<E> sorted1 = new ArrayList<>(unsorted);
Collections.sort(sorted1);

List<E> sorted2 = new ArrayList<>(unsorted);
MyInsertionSort.sort(sorted2);

I found AbstractIterableAssert#containsExactlyElementsOf method.

        assertThat(sorted2)
                .isSorted()
                .isSortedAccordingTo(Comparator.naturalOrder())
                .containsExactlyElementsOf(sorted1)
        ;

I ended up while tracing the method to the point calling Comparator#compare.

Is the containsExactlyElementsOf method covers the stability?

Or is there any other method should I add for the stability?

Supplement

Let us say we have following unsorted list. (I used the mapToObj for a testing purpuse.)

List<Integer> unsorted = IntStream.of(2, 0, 0, 3, 1)
        .mapToObj(Integer::new)
        .collect(Collectors.toList());

I produced a base result.

// might be stable
List<Integer> sorted1 = Collections.sort(new ArrayList<>(unsorted));

And produced my result.

// should be stable
List<Integer> sorted2 = MyInsertionSort.sort(new ArrayList<>(unsorted));

Both lists might be sorted and it's easy to be asserted as described above.

Now say the logic is not well and the stability is broken.

Collections.swap(sorted2, 0, 1); // swap first two zeros from 0, 0, 1, 2, 3

How can I assert, which should fails, that not all elements in sorted2 are same with each elements of sorted1?

Without following simple loop?

for (int i = 0; i < sorted2.size(); i++) {
    assertThat(sorted2.get(i))
            .isSameAs(sorted1.get(i));
}
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184

2 Answers2

1

I'm not sure I can confirm/find any way.

I just tried following simple loop.

for (int i = 0; i < sorted2.size(); i++) {
    assertThat(sorted2.get(i))
            .isSameAs(sorted1.get(i));
}

As issued and answered on https://github.com/assertj/assertj-core/issues/2365#issuecomment-939681420

Anyone can do this.

 assertThat(sorted2)
                .isSorted()
                .isSortedAccordingTo(Comparator.naturalOrder())
                .usingElementComparator((o1, o2) -> o1 == o2 ? 0 : -1)
                .containsExactlyElementsOf(sorted1) // should fail and it does
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
0

You can use hasSameElementsAs() method from AssertJ. This method ignores the duplicates and validates both has same elements assertThat(firstCollection).hasSameElementsAs(secondCollection); It is advised to validate the size first when we go for this method.

If you dont worry about the order then we can use containsExactlyInAnyOrder().

  • 1
    https://dzone.com/articles/assertj-and-collections-introduction this link might help you – Ravichandran M Oct 10 '21 at 06:28
  • I'm afraid the [`hasSameElementsAs`](https://www.javadoc.io/static/org.assertj/assertj-core/3.21.0/org/assertj/core/api/AbstractIterableAssert.html#hasSameElementsAs(java.lang.Iterable)) also calls `comparator#compare`. – Jin Kwon Oct 10 '21 at 07:32