package org.mockito.internal.configuration.injection;

import org.junit.Test;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.fest.assertions.Assertions.assertThat;

@SuppressWarnings("unused")
public class FieldTypeAndNameComparatorTest {

    private Object objectA;
    private Object objectB;

    private Number numberA;
    private Number numberB;

    private Integer integerA;
    private Integer integerB;

    @Test
    public void when_same_type_the_order_is_based_on_field_name() throws Exception {
        assertThat(new PropertyAndSetterInjection.FieldTypeAndNameComparator().compare(field("objectA"), field("objectB"))).isEqualTo(-1);
        assertThat(new PropertyAndSetterInjection.FieldTypeAndNameComparator().compare(field("objectB"), field("objectA"))).isEqualTo(1);
        assertThat(new PropertyAndSetterInjection.FieldTypeAndNameComparator().compare(field("objectB"), field("objectB"))).isEqualTo(0);
    }

    @Test
    public void when_type_is_different_the_supertype_comes_last() throws Exception {
        assertThat(new PropertyAndSetterInjection.FieldTypeAndNameComparator().compare(field("numberA"), field("objectB"))).isEqualTo(-1);
        assertThat(new PropertyAndSetterInjection.FieldTypeAndNameComparator().compare(field("objectB"), field("numberA"))).isEqualTo(1);
    }

    @Test
    public void using_Collections_dot_sort() throws Exception {
        List<Field> unsortedFields = Arrays.asList(
                field("objectB"),
                field("integerB"),
                field("numberA"),
                field("numberB"),
                field("objectA"),
                field("integerA")
        );

        Collections.sort(unsortedFields, new PropertyAndSetterInjection.FieldTypeAndNameComparator());

        assertThat(unsortedFields).containsSequence(
                field("integerA"),
                field("integerB"),
                field("numberA"),
                field("numberB"),
                field("objectA"),
                field("objectB")
        );
    }


    @Test
    public void issue_352_order_was_different_between_JDK6_and_JDK7() throws Exception {
        List<Field> unsortedFields = Arrays.asList(
                field("objectB"),
                field("objectA")
        );

        Collections.sort(unsortedFields, new PropertyAndSetterInjection.FieldTypeAndNameComparator());

        assertThat(unsortedFields).containsSequence(
                field("objectA"),
                field("objectB")
        );
    }

    private Field field(String field) throws NoSuchFieldException {
        return getClass().getDeclaredField(field);
    }
}

@@ -162,24 +162,54 @@
 llections;%0D%0A
+import java.util.Comparator;%0D%0A
 import java.
@@ -356,24 +356,131 @@
 orTest %7B%0D%0A%0D%0A
+    private static Comparator%3CField%3E cmp = new PropertyAndSetterInjection.FieldTypeAndNameComparator();%0D%0A%0D%0A
     private 
@@ -771,67 +771,11 @@
 hat(
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 .com
@@ -855,67 +855,11 @@
 hat(
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 .com
@@ -938,67 +938,11 @@
 hat(
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 .com
@@ -1127,67 +1127,11 @@
 hat(
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 .com
@@ -1211,67 +1211,11 @@
 hat(
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 .com
@@ -1679,67 +1679,11 @@
 ds, 
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 );%0D%0A
@@ -2254,67 +2254,11 @@
 ds, 
-new PropertyAndSetterInjection.FieldTypeAndNameComparator()
+cmp
 );%0D%0A

Use a single instance of the comparator for testing.