forked from upstream-mirrors/OpenTracks
Adding tests and making minor reorg changes.
This commit is contained in:
@@ -219,6 +219,8 @@ public class TrackDataHub {
|
|||||||
listenerHandlerThread = new HandlerThread("trackDataContentThread");
|
listenerHandlerThread = new HandlerThread("trackDataContentThread");
|
||||||
listenerHandlerThread.start();
|
listenerHandlerThread.start();
|
||||||
listenerHandler = new Handler(listenerHandlerThread.getLooper());
|
listenerHandler = new Handler(listenerHandlerThread.getLooper());
|
||||||
|
|
||||||
|
resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -417,13 +419,6 @@ public class TrackDataHub {
|
|||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
listeners.unregisterTrackDataListener(listener);
|
listeners.unregisterTrackDataListener(listener);
|
||||||
|
|
||||||
if (!listeners.hasListeners()) {
|
|
||||||
// We lost our last listener, don't bother keeping the listener state.
|
|
||||||
// If any of the old listeners happens to be re-added, we'll use state from its
|
|
||||||
// old registration instead.
|
|
||||||
resetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't load any data or start internal listeners if start() hasn't been
|
// Don't load any data or start internal listeners if start() hasn't been
|
||||||
// called. When it is called, we'll do both things.
|
// called. When it is called, we'll do both things.
|
||||||
if (!started) return;
|
if (!started) return;
|
||||||
@@ -931,9 +926,7 @@ public class TrackDataHub {
|
|||||||
// a few of them (why miss the oportunity?).
|
// a few of them (why miss the oportunity?).
|
||||||
|
|
||||||
Log.i(TAG, "Resampling point set after " + numLoadedPoints + " points.");
|
Log.i(TAG, "Resampling point set after " + numLoadedPoints + " points.");
|
||||||
firstSeenLocationId = -1;
|
resetState();
|
||||||
lastSeenLocationId = -1;
|
|
||||||
numLoadedPoints = 0;
|
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
sampledListeners = getListenersFor(ListenerDataType.POINT_UPDATES);
|
sampledListeners = getListenersFor(ListenerDataType.POINT_UPDATES);
|
||||||
sampledOutListeners = getListenersFor(ListenerDataType.SAMPLED_OUT_POINT_UPDATES);
|
sampledOutListeners = getListenersFor(ListenerDataType.SAMPLED_OUT_POINT_UPDATES);
|
||||||
@@ -990,6 +983,9 @@ public class TrackDataHub {
|
|||||||
if (pointSamplingFrequency == -1) {
|
if (pointSamplingFrequency == -1) {
|
||||||
// Now we already have at least one point, calculate the sampling
|
// Now we already have at least one point, calculate the sampling
|
||||||
// frequency.
|
// frequency.
|
||||||
|
// It should be noted that a non-obvious consequence of this sampling is that
|
||||||
|
// no matter how many points we get in the newest batch, we'll never exceed
|
||||||
|
// MAX_DISPLAYED_TRACK_POINTS = 2 * TARGET_DISPLAYED_TRACK_POINTS before resampling.
|
||||||
long numTotalPoints = lastStoredLocationId - localFirstSeenLocationId;
|
long numTotalPoints = lastStoredLocationId - localFirstSeenLocationId;
|
||||||
pointSamplingFrequency =
|
pointSamplingFrequency =
|
||||||
(int) (1 + numTotalPoints / Constants.TARGET_DISPLAYED_TRACK_POINTS);
|
(int) (1 + numTotalPoints / Constants.TARGET_DISPLAYED_TRACK_POINTS);
|
||||||
|
|||||||
@@ -24,14 +24,8 @@ import static com.google.android.testing.mocking.AndroidMock.leq;
|
|||||||
import static com.google.android.testing.mocking.AndroidMock.same;
|
import static com.google.android.testing.mocking.AndroidMock.same;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.Constants;
|
import com.google.android.apps.mytracks.Constants;
|
||||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationFactory;
|
||||||
import com.google.android.apps.mytracks.content.Track;
|
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
|
||||||
import com.google.android.apps.mytracks.content.TrackDataListener;
|
|
||||||
import com.google.android.apps.mytracks.content.DataSourcesWrapper;
|
|
||||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
|
||||||
import com.google.android.apps.mytracks.content.Waypoint;
|
|
||||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
|
||||||
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
||||||
import com.google.android.apps.mytracks.content.TrackDataListener.ProviderState;
|
import com.google.android.apps.mytracks.content.TrackDataListener.ProviderState;
|
||||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||||
@@ -55,6 +49,8 @@ import android.test.mock.MockContentResolver;
|
|||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.easymock.Capture;
|
import org.easymock.Capture;
|
||||||
import org.easymock.IAnswer;
|
import org.easymock.IAnswer;
|
||||||
@@ -66,7 +62,7 @@ import org.easymock.IAnswer;
|
|||||||
*/
|
*/
|
||||||
public class TrackDataHubTest extends AndroidTestCase {
|
public class TrackDataHubTest extends AndroidTestCase {
|
||||||
|
|
||||||
private static final long TRACK_ID = 42;
|
private static final long TRACK_ID = 42L;
|
||||||
private MyTracksProviderUtils providerUtils;
|
private MyTracksProviderUtils providerUtils;
|
||||||
private TrackDataHub hub;
|
private TrackDataHub hub;
|
||||||
private TrackDataListeners listeners;
|
private TrackDataListeners listeners;
|
||||||
@@ -106,8 +102,8 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
listener1 = AndroidMock.createMock("listener1", TrackDataListener.class);
|
listener1 = AndroidMock.createStrictMock("listener1", TrackDataListener.class);
|
||||||
listener2 = AndroidMock.createMock("listener2", TrackDataListener.class);
|
listener2 = AndroidMock.createStrictMock("listener2", TrackDataListener.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,49 +142,48 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener1.onTrackUpdated(track);
|
listener1.onTrackUpdated(track);
|
||||||
listener2.onTrackUpdated(track);
|
listener2.onTrackUpdated(track);
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
replay();
|
||||||
|
|
||||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
||||||
hub.start();
|
hub.start();
|
||||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources);
|
|
||||||
|
|
||||||
ContentObserver observer = observerCapture.getValue();
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||||
|
|
||||||
// Now expect an update.
|
// Now expect an update.
|
||||||
listener1.onTrackUpdated(track);
|
listener1.onTrackUpdated(track);
|
||||||
listener2.onTrackUpdated(track);
|
listener2.onTrackUpdated(track);
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources);
|
replay();
|
||||||
|
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources);
|
|
||||||
|
|
||||||
// Unregister one, get another update.
|
// Unregister one, get another update.
|
||||||
|
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||||
listener2.onTrackUpdated(track);
|
listener2.onTrackUpdated(track);
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources);
|
replay();
|
||||||
|
|
||||||
hub.unregisterTrackDataListener(listener1);
|
hub.unregisterTrackDataListener(listener1);
|
||||||
|
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources);
|
|
||||||
|
|
||||||
// Unregister the other, expect internal unregistration
|
// Unregister the other, expect internal unregistration
|
||||||
dataSources.unregisterContentObserver(observer);
|
dataSources.unregisterContentObserver(observer);
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources);
|
replay();
|
||||||
|
|
||||||
hub.unregisterTrackDataListener(listener2);
|
hub.unregisterTrackDataListener(listener2);
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources);
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FixedSizeCursorAnswer implements IAnswer<Cursor> {
|
private static class FixedSizeCursorAnswer implements IAnswer<Cursor> {
|
||||||
@@ -208,6 +203,90 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FixedSizeLocationIterator implements LocationIterator {
|
||||||
|
private final long startId;
|
||||||
|
private final Location[] locs;
|
||||||
|
private final Set<Integer> splitIndexSet = new HashSet<Integer>();
|
||||||
|
private int currentIdx = -1;
|
||||||
|
|
||||||
|
public FixedSizeLocationIterator(long startId, int size) {
|
||||||
|
this(startId, size, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FixedSizeLocationIterator(long startId, int size, int... splitIndices) {
|
||||||
|
this.startId = startId;
|
||||||
|
this.locs = new Location[size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Location loc = new Location("gps");
|
||||||
|
loc.setLatitude(-15.0 + i / 1000.0);
|
||||||
|
loc.setLongitude(37 + i / 1000.0);
|
||||||
|
loc.setAltitude(i);
|
||||||
|
|
||||||
|
locs[i] = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitIndices != null) {
|
||||||
|
for (int splitIdx : splitIndices) {
|
||||||
|
splitIndexSet.add(splitIdx);
|
||||||
|
|
||||||
|
Location splitLoc = locs[splitIdx];
|
||||||
|
splitLoc.setLatitude(100.0);
|
||||||
|
splitLoc.setLongitude(200.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expectLocationsDelivered(TrackDataListener listener) {
|
||||||
|
for (int i = 0; i < locs.length; i++) {
|
||||||
|
if (splitIndexSet.contains(i)) {
|
||||||
|
listener.onSegmentSplit();
|
||||||
|
} else {
|
||||||
|
listener.onNewTrackPoint(locs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expectSampledLocationsDelivered(
|
||||||
|
TrackDataListener listener, int sampleFrequency, boolean includeSampledOut) {
|
||||||
|
for (int i = 0; i < locs.length; i++) {
|
||||||
|
if (splitIndexSet.contains(i)) {
|
||||||
|
listener.onSegmentSplit();
|
||||||
|
} else if (i % sampleFrequency == 0) {
|
||||||
|
listener.onNewTrackPoint(locs[i]);
|
||||||
|
} else if (includeSampledOut) {
|
||||||
|
listener.onSampledOutTrackPoint(locs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return currentIdx < (locs.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location next() {
|
||||||
|
currentIdx++;
|
||||||
|
return locs[currentIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLocationId() {
|
||||||
|
return startId + currentIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testWaypointListen() {
|
public void testWaypointListen() {
|
||||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
@@ -249,14 +328,13 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener2.onNewWaypoint(wpt2);
|
listener2.onNewWaypoint(wpt2);
|
||||||
listener2.onNewWaypointsDone();
|
listener2.onNewWaypointsDone();
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
replay();
|
||||||
|
|
||||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
||||||
hub.start();
|
hub.start();
|
||||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources, providerUtils);
|
|
||||||
|
|
||||||
ContentObserver observer = observerCapture.getValue();
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
|
||||||
@@ -280,12 +358,11 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener1.onNewWaypointsDone();
|
listener1.onNewWaypointsDone();
|
||||||
listener2.onNewWaypointsDone();
|
listener2.onNewWaypointsDone();
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources, providerUtils);
|
replay();
|
||||||
|
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources, providerUtils);
|
|
||||||
|
|
||||||
// Unregister one, get another update.
|
// Unregister one, get another update.
|
||||||
expect(providerUtils.getWaypointsCursor(
|
expect(providerUtils.getWaypointsCursor(
|
||||||
@@ -305,32 +382,335 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener2.onNewWaypoint(wpt4);
|
listener2.onNewWaypoint(wpt4);
|
||||||
listener2.onNewWaypointsDone();
|
listener2.onNewWaypointsDone();
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources, providerUtils);
|
replay();
|
||||||
|
|
||||||
hub.unregisterTrackDataListener(listener1);
|
hub.unregisterTrackDataListener(listener1);
|
||||||
|
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
verifyAndReset();
|
||||||
AndroidMock.reset(listener1, listener2, dataSources, providerUtils);
|
|
||||||
|
|
||||||
// Unregister the other, expect internal unregistration
|
// Unregister the other, expect internal unregistration
|
||||||
dataSources.unregisterContentObserver(observer);
|
dataSources.unregisterContentObserver(observer);
|
||||||
|
|
||||||
AndroidMock.replay(listener1, listener2, dataSources, providerUtils);
|
replay();
|
||||||
|
|
||||||
hub.unregisterTrackDataListener(listener2);
|
hub.unregisterTrackDataListener(listener2);
|
||||||
observer.onChange(false);
|
observer.onChange(false);
|
||||||
|
|
||||||
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPointsListen() {
|
public void testPointsListen() {
|
||||||
// TODO
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
|
.putLong("selectedTrack", TRACK_ID).commit();
|
||||||
|
|
||||||
|
expectStart();
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.start();
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Register a second listener - it will get the same points as the previous one
|
||||||
|
locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||||
|
|
||||||
|
listener2.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener2);
|
||||||
|
listener2.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.start();
|
||||||
|
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Deliver more points - should go to both listeners, without clearing.
|
||||||
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
|
||||||
|
locationIterator = new FixedSizeLocationIterator(11, 10, 1);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(11L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(20L);
|
||||||
|
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
locationIterator.expectLocationsDelivered(listener2);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
listener2.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
observer.onChange(false);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Unregister listener1, switch tracks to ensure data is cleared/reloaded.
|
||||||
|
locationIterator = new FixedSizeLocationIterator(101, 10);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID + 1), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID + 1)).andReturn(110L);
|
||||||
|
|
||||||
|
listener2.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener2);
|
||||||
|
listener2.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.unregisterTrackDataListener(listener1);
|
||||||
|
hub.loadTrack(TRACK_ID + 1);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPointsListen_resample() {
|
public void testPointsListen_beforeStart() {
|
||||||
// TODO
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointsListen_reRegister() {
|
||||||
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
|
.putLong("selectedTrack", TRACK_ID).commit();
|
||||||
|
|
||||||
|
expectStart();
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.start();
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Unregister
|
||||||
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
dataSources.unregisterContentObserver(observer);
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.unregisterTrackDataListener(listener1);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Register again, except only points since unregistered.
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
locationIterator = new FixedSizeLocationIterator(11, 10);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(11L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(20L);
|
||||||
|
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Deliver more points - should still be incremental.
|
||||||
|
locationIterator = new FixedSizeLocationIterator(21, 10, 1);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(21L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(30L);
|
||||||
|
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
observer.onChange(false);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointsListen_reRegisterTrackChanged() {
|
||||||
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
|
.putLong("selectedTrack", TRACK_ID).commit();
|
||||||
|
|
||||||
|
expectStart();
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.start();
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Unregister
|
||||||
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
dataSources.unregisterContentObserver(observer);
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.unregisterTrackDataListener(listener1);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Register again after track changed, expect all points.
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
locationIterator = new FixedSizeLocationIterator(1, 10);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID + 1), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID + 1)).andReturn(10L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.loadTrack(TRACK_ID + 1);
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointsListen_largeTrackSampling() {
|
||||||
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
|
.putLong("selectedTrack", TRACK_ID).commit();
|
||||||
|
|
||||||
|
expectStart();
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 20000, 4, 253, 700, 712);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(20000L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
listener2.clearTrackPoints();
|
||||||
|
locationIterator.expectSampledLocationsDelivered(listener1, 4, false);
|
||||||
|
locationIterator.expectSampledLocationsDelivered(listener2, 4, true);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
listener2.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.registerTrackDataListener(listener1,
|
||||||
|
EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
hub.registerTrackDataListener(listener2,
|
||||||
|
EnumSet.of(ListenerDataType.POINT_UPDATES, ListenerDataType.SAMPLED_OUT_POINT_UPDATES));
|
||||||
|
hub.start();
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointsListen_resampling() {
|
||||||
|
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||||
|
prefs.edit().putLong("recordingTrack", TRACK_ID)
|
||||||
|
.putLong("selectedTrack", TRACK_ID).commit();
|
||||||
|
|
||||||
|
expectStart();
|
||||||
|
dataSources.registerContentObserver(
|
||||||
|
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||||
|
|
||||||
|
// Deliver 3000 points (no sampling happens)
|
||||||
|
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 3000, 5);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(3000L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectLocationsDelivered(listener1);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
hub.start();
|
||||||
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Now deliver 3000 more (incrementally sampled)
|
||||||
|
ContentObserver observer = observerCapture.getValue();
|
||||||
|
locationIterator = new FixedSizeLocationIterator(3001, 3000);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(3001L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(6000L);
|
||||||
|
|
||||||
|
locationIterator.expectSampledLocationsDelivered(listener1, 2, false);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
observer.onChange(false);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
|
|
||||||
|
// Now another 3000 (triggers resampling)
|
||||||
|
locationIterator = new FixedSizeLocationIterator(1, 9000);
|
||||||
|
expect(providerUtils.getLocationIterator(
|
||||||
|
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||||
|
.andReturn(locationIterator);
|
||||||
|
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(9000L);
|
||||||
|
|
||||||
|
listener1.clearTrackPoints();
|
||||||
|
locationIterator.expectSampledLocationsDelivered(listener1, 2, false);
|
||||||
|
listener1.onNewTrackPointsDone();
|
||||||
|
|
||||||
|
replay();
|
||||||
|
|
||||||
|
observer.onChange(false);
|
||||||
|
|
||||||
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLocationListen() {
|
public void testLocationListen() {
|
||||||
@@ -338,6 +718,8 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testCompassListen() throws Exception {
|
public void testCompassListen() throws Exception {
|
||||||
|
AndroidMock.resetToDefault(listener1);
|
||||||
|
|
||||||
Sensor compass = newSensor();
|
Sensor compass = newSensor();
|
||||||
expect(dataSources.getSensor(Sensor.TYPE_ORIENTATION)).andReturn(compass);
|
expect(dataSources.getSensor(Sensor.TYPE_ORIENTATION)).andReturn(compass);
|
||||||
Capture<SensorEventListener> listenerCapture = new Capture<SensorEventListener>();
|
Capture<SensorEventListener> listenerCapture = new Capture<SensorEventListener>();
|
||||||
@@ -359,7 +741,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener1.onProviderStateChange(isA(ProviderState.class));
|
listener1.onProviderStateChange(isA(ProviderState.class));
|
||||||
AndroidMock.expectLastCall().anyTimes();
|
AndroidMock.expectLastCall().anyTimes();
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1);
|
replay();
|
||||||
|
|
||||||
hub.registerTrackDataListener(listener1,
|
hub.registerTrackDataListener(listener1,
|
||||||
EnumSet.of(ListenerDataType.COMPASS_UPDATES, ListenerDataType.LOCATION_UPDATES));
|
EnumSet.of(ListenerDataType.COMPASS_UPDATES, ListenerDataType.LOCATION_UPDATES));
|
||||||
@@ -370,8 +752,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
event.values[0] = 42.0f;
|
event.values[0] = 42.0f;
|
||||||
sensorListener.onSensorChanged(event);
|
sensorListener.onSensorChanged(event);
|
||||||
|
|
||||||
AndroidMock.verify(dataSources, providerUtils, listener1);
|
verifyAndReset();
|
||||||
AndroidMock.reset(dataSources, providerUtils, listener1);
|
|
||||||
|
|
||||||
// Expect the heading update to include declination.
|
// Expect the heading update to include declination.
|
||||||
listener1.onCurrentHeadingChanged(52.0);
|
listener1.onCurrentHeadingChanged(52.0);
|
||||||
@@ -382,7 +763,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
listener1.onCurrentLocationChanged(isA(Location.class));
|
listener1.onCurrentLocationChanged(isA(Location.class));
|
||||||
AndroidMock.expectLastCall().anyTimes();
|
AndroidMock.expectLastCall().anyTimes();
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1);
|
replay();
|
||||||
|
|
||||||
// Now try injecting a location update, triggering a declination update.
|
// Now try injecting a location update, triggering a declination update.
|
||||||
Location location = new Location("gps");
|
Location location = new Location("gps");
|
||||||
@@ -393,19 +774,18 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
locationListener.onLocationChanged(location);
|
locationListener.onLocationChanged(location);
|
||||||
sensorListener.onSensorChanged(event);
|
sensorListener.onSensorChanged(event);
|
||||||
|
|
||||||
AndroidMock.verify(dataSources, providerUtils, listener1);
|
verifyAndReset();
|
||||||
AndroidMock.reset(dataSources, providerUtils, listener1);
|
|
||||||
|
|
||||||
listener1.onCurrentHeadingChanged(52.0);
|
listener1.onCurrentHeadingChanged(52.0);
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1);
|
replay();
|
||||||
|
|
||||||
// Now try changing the known declination - it should still return the old declination, since
|
// Now try changing the known declination - it should still return the old declination, since
|
||||||
// updates only happen sparsely.
|
// updates only happen sparsely.
|
||||||
declination = 20.0f;
|
declination = 20.0f;
|
||||||
sensorListener.onSensorChanged(event);
|
sensorListener.onSensorChanged(event);
|
||||||
|
|
||||||
AndroidMock.verify(dataSources, providerUtils, listener1);
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sensor newSensor() throws Exception {
|
private Sensor newSensor() throws Exception {
|
||||||
@@ -438,19 +818,18 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
expect(listener1.onReportSpeedChanged(true)).andReturn(false);
|
expect(listener1.onReportSpeedChanged(true)).andReturn(false);
|
||||||
expect(listener2.onReportSpeedChanged(true)).andReturn(false);
|
expect(listener2.onReportSpeedChanged(true)).andReturn(false);
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
replay();
|
||||||
|
|
||||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
||||||
hub.start();
|
hub.start();
|
||||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
||||||
|
|
||||||
AndroidMock.verify(dataSources, providerUtils, listener1, listener2);
|
verifyAndReset();
|
||||||
AndroidMock.reset(dataSources, providerUtils, listener1, listener2);
|
|
||||||
|
|
||||||
expect(listener1.onReportSpeedChanged(false)).andReturn(false);
|
expect(listener1.onReportSpeedChanged(false)).andReturn(false);
|
||||||
expect(listener2.onReportSpeedChanged(false)).andReturn(false);
|
expect(listener2.onReportSpeedChanged(false)).andReturn(false);
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
replay();
|
||||||
|
|
||||||
prefs.edit()
|
prefs.edit()
|
||||||
.putBoolean(speedKey, false)
|
.putBoolean(speedKey, false)
|
||||||
@@ -464,29 +843,26 @@ public class TrackDataHubTest extends AndroidTestCase {
|
|||||||
expect(listener1.onUnitsChanged(false)).andReturn(false);
|
expect(listener1.onUnitsChanged(false)).andReturn(false);
|
||||||
expect(listener2.onUnitsChanged(false)).andReturn(false);
|
expect(listener2.onUnitsChanged(false)).andReturn(false);
|
||||||
|
|
||||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
replay();
|
||||||
|
|
||||||
prefs.edit()
|
prefs.edit()
|
||||||
.putBoolean(metricUnitsKey, false)
|
.putBoolean(metricUnitsKey, false)
|
||||||
.commit();
|
.commit();
|
||||||
listener.onSharedPreferenceChanged(prefs, metricUnitsKey);
|
listener.onSharedPreferenceChanged(prefs, metricUnitsKey);
|
||||||
|
|
||||||
AndroidMock.verify(dataSources, providerUtils, listener1, listener2);
|
verifyAndReset();
|
||||||
}
|
|
||||||
|
|
||||||
public void testFullListener() {
|
|
||||||
// TODO: test loading a track, getting updates, loading another, unloading
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRelisten() {
|
|
||||||
// TODO: test re-registering an old points listener
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRelisten_changed() {
|
|
||||||
// TODO: test register, get points, unregister, change track, register
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectStart() {
|
private void expectStart() {
|
||||||
dataSources.registerOnSharedPreferenceChangeListener(capture(preferenceListenerCapture));
|
dataSources.registerOnSharedPreferenceChangeListener(capture(preferenceListenerCapture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void replay() {
|
||||||
|
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAndReset() {
|
||||||
|
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
||||||
|
AndroidMock.reset(listener1, listener2, dataSources, providerUtils);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user