package ch.difty.sipamato.paging;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import ch.difty.sipamato.lib.NullArgumentException;
import ch.difty.sipamato.paging.Sort.Direction;
import ch.difty.sipamato.paging.Sort.Order;

public class SortTest {

    private final List<Order> orders = new ArrayList<>(4);

    private Sort sort;

    @Before
    public void setUp() {
        orders.add(new Order(Direction.ASC, "a"));
        orders.add(new Order(Direction.DESC, "b"));
        orders.add(new Order(Direction.DESC, "c"));
        orders.add(new Order(Direction.ASC, "d"));

        sort = new Sort(orders);
    }

    @Test
    public void degenerateConstruction_withNullOrders_throws() {
        try {
            new Sort(null);
            fail("should have thrown exception");
        } catch (Exception ex) {
            assertThat(ex).isInstanceOf(NullArgumentException.class).hasMessage("orders must not be null.");
        }
    }

    @Test
    public void degenerateConstruction_withEmptyOrders_throws() {
        try {
            new Sort(Collections.emptyList());
            fail("should have thrown exception");
        } catch (Exception ex) {
            assertThat(ex).isInstanceOf(IllegalArgumentException.class).hasMessage("orders can't be empty.");
        }
    }

    @Test
    public void degenerateConstruction_withNullProperties_throws() {
        try {
            new Sort(Direction.ASC, (String[]) null);
            fail("should have thrown exception");
        } catch (Exception ex) {
            assertThat(ex).isInstanceOf(NullArgumentException.class).hasMessage("properties must not be null.");
        }
    }

    @Test
    public void degenerateConstruction_withEmptyProperties_throws() {
        try {
            new Sort(Direction.ASC, new String[] {});
            fail("should have thrown exception");
        } catch (Exception ex) {
            assertThat(ex).isInstanceOf(IllegalArgumentException.class).hasMessage("properties can't be empty.");
        }
    }

    private void assertProperties(Direction dir, String[] props) {
        final Sort sort = new Sort(dir, props);

        assertThat(sort.iterator()).hasSize(props.length);

        final Iterator<Order> it = sort.iterator();

        while (it.hasNext()) {
            final Order o = it.next();
            assertThat(o.getDirection()).isEqualTo(dir);
        }
    }

    @Test
    public void creatingSortForThreeAscendingProperties_returnsIteratorForAllThreeElementsWithAscendingOrder() {
        assertProperties(Direction.ASC, new String[] { "a", "b", "c" });
    }

    @Test
    public void cratingSortForFiveDescendingProperties_returnsIteratorForAllFiveElementsWithDescendingOrder() {
        assertProperties(Direction.DESC, new String[] { "a", "b", "c", "d", "e" });
    }

    @Test
    public void creatingSortForFourOrdersWithDifferentSortDirections() {

        final Iterator<Order> it = sort.iterator();
        assertOrder(it, Direction.ASC, "a");
        assertOrder(it, Direction.DESC, "b");
        assertOrder(it, Direction.DESC, "c");
        assertOrder(it, Direction.ASC, "d");
        assertThat(it.hasNext()).isFalse();
    }

    private void assertOrder(Iterator<Order> it, Direction dir, String p) {
        Order o = it.next();
        assertThat(o.getDirection()).isEqualTo(dir);
        assertThat(o.getProperty()).isEqualTo(p);
    }

    @Test
    public void gettingOrderFor_withNullProperty_returnsNull() {
        assertThat(sort.getOrderFor(null)).isNull();
    }

    @Test
    public void gettingOrderFor_nonExistingProperty_returnsNull() {
        String p = "x";
        assertThat(orders).extracting("property").doesNotContain(p);
        assertThat(sort.getOrderFor(p)).isNull();
    }

    @Test
    public void gettingOrderFor_existingProperty_returnsRespectiveOrder() {
        String p = "c";
        assertThat(orders).extracting("property").contains(p);
        assertThat(sort.getOrderFor(p).getProperty()).isEqualTo(p);
    }

    @Test
    public void directionAsc_isAscending() {
        assertThat(Direction.ASC.isAscending()).isTrue();
    }

    @Test
    public void directionDesc_isNotAscending() {
        assertThat(Direction.DESC.isAscending()).isFalse();
    }

    @Test
    public void orderWithNullDirection_isAscending() {
        assertThat(new Order(null, "foo").getDirection()).isEqualTo(Direction.ASC);
    }
}

@@ -4615,11 +4615,1433 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testingToString() %7B%0A        assertThat(sort.toString()).isEqualTo(%22a: ASC,b: DESC,c: DESC,d: ASC%22);%0A    %7D%0A%0A    @Test%0A    public void sortEqualityTests() %7B%0A        assertThat(sort.equals(null)).isFalse();%0A        assertThat(sort.equals(new String())).isFalse();%0A        assertThat(sort.equals(sort)).isTrue();%0A        assertThat(sort.equals(new Sort(orders))).isTrue();%0A%0A        List%3COrder%3E orders2 = new ArrayList%3C%3E();%0A        orders2.add(new Order(Direction.ASC, %22a%22));%0A        orders2.add(new Order(Direction.DESC, %22b%22));%0A        orders2.add(new Order(Direction.DESC, %22c%22));%0A        assertThat(sort.equals(new Sort(orders2))).isFalse();%0A        assertThat(sort.hashCode()).isNotEqualTo(new Sort(orders2).hashCode());%0A%0A        orders2.add(new Order(Direction.ASC, %22d%22));%0A        assertThat(sort.equals(new Sort(orders2))).isTrue();%0A        assertThat(sort.hashCode()).isEqualTo(new Sort(orders2).hashCode());%0A    %7D%0A%0A    @Test%0A    public void orerEqualityTests() %7B%0A        Order o1 = new Order(Direction.DESC, %22foo%22);%0A%0A        assertThat(o1.equals(null)).isFalse();%0A        assertThat(o1.equals(new String())).isFalse();%0A        assertThat(o1.equals(o1)).isTrue();%0A        assertThat(o1.equals(new Order(Direction.DESC, %22foo%22))).isTrue();%0A        assertThat(o1.equals(new Order(Direction.ASC, %22foo%22))).isFalse();%0A        assertThat(o1.equals(new Order(Direction.DESC, %22bar%22))).isFalse();%0A%0A    %7D
 %0A%7D%0A

Improve Sort test coverage