package org.gdg.frisbee.android.eventseries;
import android.location.Location;
import org.gdg.frisbee.android.BuildConfig;
import org.gdg.frisbee.android.api.model.Event;
import org.gdg.frisbee.android.app.BaseApp;
import org.gdg.frisbee.android.eventseries.EventAdapter.Item;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, application = BaseApp.class)
public class TaggedEventDistanceComparatorTest {
@Mock Event eventInMarch;
@Mock Event eventInApril;
@Mock Event eventInDecember;
private Location location;
@Before
public void setup() {
initMocks(this);
location = new Location("mock");
location.setLatitude(41d);
location.setLongitude(29d);
when(eventInMarch.getStart()).thenReturn(new DateTime(2014, 3, 1, 0, 0));
when(eventInApril.getStart()).thenReturn(new DateTime(2014, 4, 1, 0, 0));
when(eventInDecember.getStart()).thenReturn(new DateTime(2014, 12, 1, 0, 0));
}
@Test
public void givenUserHasNoLocation_thenComparatorShouldSortUsingDates() {
TaggedEventDistanceComparator comparator = new TaggedEventDistanceComparator(null);
Item eventInMarch = new Item(this.eventInMarch);
Item eventInApril = new Item(this.eventInApril);
Item eventInDecember = new Item(this.eventInDecember);
assertElementsOrderedLikeThis(comparator, eventInMarch, eventInApril, eventInDecember);
}
@Test
public void givenEventsWithNoLocation_thenComparatorShouldSortUsingDates() {
TaggedEventDistanceComparator comparator = new TaggedEventDistanceComparator(location);
Item eventInMarch = new Item(this.eventInMarch);
Item eventInApril = new Item(this.eventInApril);
Item eventInDecember = new Item(this.eventInDecember);
assertElementsOrderedLikeThis(comparator, eventInMarch, eventInApril, eventInDecember);
}
@Test
public void givenEventWithNoLocation_thenWithLocationShouldComeFirst() {
Item eventWithLocation = givenEventWithLocation(41, 29);
Item eventInMarch = new Item(this.eventInMarch);
TaggedEventDistanceComparator comparator = new TaggedEventDistanceComparator(location);
assertElementsOrderedLikeThis(comparator, eventWithLocation, eventInMarch);
}
@Test
public void shouldSortUsingLocation() {
Item eventWithMyLocation = givenEventWithLocation(41, 29);
Item eventWithFurtherLocation = givenEventWithLocation(42d, 30d);
TaggedEventDistanceComparator comparator = new TaggedEventDistanceComparator(location);
assertElementsOrderedLikeThis(comparator, eventWithMyLocation, eventWithFurtherLocation);
}
private static Item givenEventWithLocation(double lat, double lng) {
Event eventWithLocation = mock(Event.class);
when(eventWithLocation.getLatLng()).thenReturn(new Event.LatLng(lat, lng));
return new Item(eventWithLocation);
}
private static void assertElementsOrderedLikeThis(Comparator<? super Item> comparator, Item... elements) {
List<Item> expectedOrder = Arrays.asList(elements);
List<Item> shuffledAndSorted = new ArrayList<>(expectedOrder);
Collections.shuffle(shuffledAndSorted, new Random(0));
Collections.sort(shuffledAndSorted, comparator);
assertEquals(expectedOrder, shuffledAndSorted);
List<Item> reversedAndSorted = new ArrayList<>(expectedOrder);
Collections.reverse(reversedAndSorted);
Collections.sort(reversedAndSorted, comparator);
assertEquals(expectedOrder, reversedAndSorted);
}
}