This question is related to "Comparison method violates its general contract!" - TimSort and GridLayout and several other similar "general contract violation" questions. My question is particularly related to Ceekay's answer at the bottom of the page about "How to test the TimSort implementation". In my case I have fixed the application bug that brought me here which was due to a symmetry violation, but I am having trouble creating a unit test to expose that violation (if the fix is commented out or unfixed in future).
public class TickNumber implements Comparable<TickNumber> {
protected String zone;
protected String track;
}
public class GisTickNumber extends TickNumber implements Comparable<TickNumber> {
private String suffix;
}
I've left out all the implementation details, but basically a Tick number is a 4 digit number where the first two digits are the zone and the second two digits are the track. GisTickNumbers can have alpha characters in the zone and or track fields, and they can optionally have an alpha suffix of one or two characters. Valid ticks are all integers in the range [0000, 9999]
(even when represented as Strings). All valid Tick numbers are valid Gis Tick numbers, but valid Gis Ticks can also look like A912, R123, 0123G, A346*
.
My symmetry violation was that in the GisTick compareTo
, I was accounting for the possible suffix, but in the plain Tick compareTo
I was not accounting for it. Thus, if 'this' was a 0000
Tick and 'that' was a 0000*
Gis Tick, 0000.compareTo(0000*)
would return 0. While if 'this' was a 0000*
Gis Tick and 'that' was a 0000
Tick, 0000*.compareTo(0000)
would return 1. A clear symmetry violation (once the shrouds pulled back)
According to Ceekay in an answer to the linked question,
- Create a list with 32 or more objects.
- Within that list, there needs to [be] two or more runs.
- Each run must contain 3 or more objects.
Once you meet those [three] criteria you can begin testing for this failure.
I believe I have set up such a list of TickNumber (and GisTickNumber) objects for my unit test, but I can't seem to get the test to fail. Even though the list has over 100 objects, more than two runs, and each run contains about 10 objects. So, my question is what other characteristics does the list of objects under test need to satisfy in order for a call to Collections.sort(testList)
to fail due to "general (symmetry) contract violation"?
- and yes, I commented out the fix before I ran the unit test that I was expecting to fail.