blob: f44f01b4dfbd2e094ad903e657721116e76622e3 [file] [log] [blame]
package com.xtremelabs.robolectric.shadows;
import android.app.Activity;
import android.graphics.Point;
import android.view.MotionEvent;
import android.view.View;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.xtremelabs.robolectric.WithTestDefaultsRunner;
import com.xtremelabs.robolectric.bytecode.AndroidTranslatorTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static com.xtremelabs.robolectric.shadows.ShadowMapView.toE6;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;
@RunWith(WithTestDefaultsRunner.class)
public class MapViewTest {
private MapView mapView;
private MyOverlay overlay1;
private MyOverlay overlay2;
private MotionEvent sourceEvent;
private MyOnTouchListener mapTouchListener;
@Before public void setUp() throws Exception {
mapView = new MapView(new Activity(), "foo");
overlay1 = new MyOverlay();
overlay2 = new MyOverlay();
mapTouchListener = new MyOnTouchListener();
mapView.getOverlays().add(overlay1);
mapView.getOverlays().add(overlay2);
mapView.setOnTouchListener(mapTouchListener);
sourceEvent = MotionEvent.obtain(0, 0, 0, 0, 0, 0);
}
@Test
public void shouldDispatchTouchEventsToOverlays() throws Exception {
mapView.dispatchTouchEvent(sourceEvent);
assertThat(overlay1.lastMotionEvent, sameInstance(sourceEvent));
assertThat(overlay2.lastMotionEvent, nullValue());
assertThat(mapTouchListener.lastMotionEvent, nullValue());
}
@Test
public void shouldDispatchTouchEventsToOverlaysUntilEventIsConsumed() throws Exception {
overlay1.shouldConsumeEvent = false;
overlay2.shouldConsumeEvent = true;
mapView.dispatchTouchEvent(sourceEvent);
assertThat(overlay1.lastMotionEvent, sameInstance(sourceEvent));
assertThat(overlay2.lastMotionEvent, sameInstance(sourceEvent));
assertThat(mapTouchListener.lastMotionEvent, nullValue());
}
@Test
public void shouldDispatchTouchEventsToMapViewIfNoOverlayConsumesEvent() throws Exception {
overlay1.shouldConsumeEvent = false;
overlay2.shouldConsumeEvent = false;
mapView.dispatchTouchEvent(sourceEvent);
assertThat(overlay1.lastMotionEvent, sameInstance(sourceEvent));
assertThat(overlay2.lastMotionEvent, sameInstance(sourceEvent));
assertThat(mapTouchListener.lastMotionEvent, sameInstance(sourceEvent));
}
@Test
public void dispatchTouchEvents_shouldDragMapByCorrectAmount() throws Exception {
initMapForDrag();
dispatchTouchEvent(MotionEvent.ACTION_DOWN, 10, 10);
dispatchTouchEvent(MotionEvent.ACTION_UP, 11, 11);
assertThat(mapView.getMapCenter(), equalTo(new GeoPoint(toE6(26), toE6(24))));
}
@Test
public void dispatchTouchEvents_shouldDragMapByCorrectAmountInMultipleSteps() throws Exception {
initMapForDrag();
dispatchTouchEvent(MotionEvent.ACTION_DOWN, 10, 10);
dispatchTouchEvent(MotionEvent.ACTION_MOVE, 11, 11);
dispatchTouchEvent(MotionEvent.ACTION_MOVE, 12, 12);
dispatchTouchEvent(MotionEvent.ACTION_UP, 11, 11);
assertThat(mapView.getMapCenter(), equalTo(new GeoPoint(toE6(26), toE6(24))));
}
@Test
public void dispatchTouchEvents_shouldMoveBackToCenterOnCancel() throws Exception {
initMapForDrag();
dispatchTouchEvent(MotionEvent.ACTION_DOWN, 10, 10);
dispatchTouchEvent(MotionEvent.ACTION_MOVE, 11, 11);
dispatchTouchEvent(MotionEvent.ACTION_MOVE, 12, 12);
dispatchTouchEvent(MotionEvent.ACTION_CANCEL, 11, 11);
assertThat(mapView.getMapCenter(), equalTo(new GeoPoint(toE6(25), toE6(25))));
}
private void initMapForDrag() {
mapView = new MapView(null, "");
mapView.layout(0, 0, 50, 50);
mapView.getController().setCenter(new GeoPoint(toE6(25), toE6(25)));
mapView.getController().zoomToSpan(toE6(50), toE6(50));
}
@Test
public void getProjection_fromPixels_shouldPerformCorrectTranslations() throws Exception {
int centerLat = 11;
int centerLng = 16;
int spanLat = 20;
int spanLng = 30;
mapView.getController().setCenter(new GeoPoint(toE6(centerLat), toE6(centerLng)));
mapView.getController().zoomToSpan(toE6(spanLat), toE6(spanLng));
mapView.layout(50, 60, 650, 460);
assertThat(mapView.getProjection().fromPixels(50, 60),
equalTo(new GeoPoint(toE6(21), toE6(1))));
assertThat(mapView.getProjection().fromPixels(350, 260),
equalTo(new GeoPoint(toE6(11), toE6(16))));
assertThat(mapView.getProjection().fromPixels(650, 460),
equalTo(new GeoPoint(toE6(1), toE6(31))));
}
@Test
public void getProjection_toPixels_shouldPerformCorrectTranslations() throws Exception {
int centerLat = 11;
int centerLng = 16;
int spanLat = 20;
int spanLng = 30;
mapView.getController().setCenter(new GeoPoint(toE6(centerLat), toE6(centerLng)));
mapView.getController().zoomToSpan(toE6(spanLat), toE6(spanLng));
mapView.layout(50, 60, 650, 460);
assertThat(mapView.getProjection().toPixels(new GeoPoint(toE6(21), toE6(1)), null),
equalTo(new Point(50, 60)));
assertThat(mapView.getProjection().toPixels(new GeoPoint(toE6(11), toE6(16)), null),
equalTo(new Point(350, 260)));
assertThat(mapView.getProjection().toPixels(new GeoPoint(toE6(1), toE6(31)), null),
equalTo(new Point(650, 460)));
}
private void dispatchTouchEvent(int action, int x, int y) {
mapView.dispatchTouchEvent(MotionEvent.obtain(0, 0, action, x, y, 0));
}
private static class MyOnTouchListener implements View.OnTouchListener {
private MotionEvent lastMotionEvent;
@Override public boolean onTouch(View v, MotionEvent event) {
lastMotionEvent = event;
return false;
}
}
private class MyOverlay extends AndroidTranslatorTest.ItemizedOverlayForTests {
private MotionEvent lastMotionEvent;
private boolean shouldConsumeEvent = true;
public MyOverlay() {
super(null);
}
@Override public boolean onTouchEvent(MotionEvent motionEvent, MapView mapView) {
lastMotionEvent = motionEvent;
return shouldConsumeEvent;
}
}
}