merge heads

This commit is contained in:
Jimmy Shih
2012-04-06 10:54:22 -07:00
parent 79fde1c118
commit f5085b208d
319 changed files with 6180 additions and 5754 deletions
+1 -2
View File
@@ -9,8 +9,7 @@
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/MyTracks"/>
<classpathentry kind="lib" path="libs/AndroidMockGenerator.jar"/>
<classpathentry kind="lib" path="libs/robotium-solo-3.1.jar"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
+33 -11
View File
@@ -1,14 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.maps.mytracks.test"
android:versionCode="1"
android:versionName="1.0"
android:debuggable="true">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@android:drawable/sym_def_app_icon"
android:label="My Tracks Tests">
<uses-library android:name="android.test.runner" />
</application>
<instrumentation android:targetPackage="com.google.android.maps.mytracks"
android:name="android.test.InstrumentationTestRunner" />
package="com.google.android.maps.mytracks.test"
android:versionCode="1"
android:versionName="1.0" >
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.google.android.maps.mytracks" />
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="15" />
<application
android:icon="@android:drawable/sym_def_app_icon"
android:label="My Tracks Tests" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
Binary file not shown.
@@ -20,12 +20,10 @@ import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import com.jayway.android.robotium.solo.Solo;
import android.app.Instrumentation;
import android.location.Location;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ZoomControls;
@@ -38,21 +36,13 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
private Instrumentation instrumentation;
private ChartActivity chartActivity;
private Solo solo;
private View zoomIn;
private View zoomOut;
private int currentZoomLevel;
private static final String LOCATION_PROVIDER = "gps";
private static final double INITIAL_LONGTITUDE = 22;
private static final double INITIAL_LATITUDE = 22;
private static final double INITIAL_ALTITUDE = 22;
private static final float INITIAL_ACCURACY = 5;
private static final float INITIAL_SPEED = 10;
private static final float INITIAL_BEARING = 3.0f;
// 10 is same with the default value in ChartView
private static final int MAX_ZOOM_LEVEL = 10;
private static final int MIN_ZOOM_LEVEL = 1;
private final int MAX_ZOOM_LEVEL = 10;
private final int MIN_ZOOM_LEVEL = 1;
// The ratio from meter/second to kilometer/hour, the conversion is 60 * 60 /
// 1000 = 3.6.
private final double METER_PER_SECOND_TO_KILOMETER_PER_HOUR = 3.6;
@@ -71,7 +61,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
}
/**
* Tests {@link ChartActivity#zoomIn()} and {@link ChartActivity#zoomOut()}.
* Tests zooming in and zooming out.
*/
public void testZoomInAndZoomOut() {
currentZoomLevel = chartActivity.getChartView().getZoomLevel();
@@ -111,33 +101,12 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
assertEquals(false, zoomOut.isEnabled());
}
/**
* There are two parts in this test. Tests
* {@link ChartActivity#onCreateDialog(int)} which includes the logic to create
* {@link ChartSettingsDialog}.
*/
public void testCreateSettingDialog() {
solo = new Solo(instrumentation, chartActivity);
// Part1, tests {@link ChartActivity#onCreateOptionsMenu()}. Check if
// optional menu is created.
assertNull(chartActivity.getChartSettingsMenuItem());
sendKeys(KeyEvent.KEYCODE_MENU);
assertNotNull(chartActivity.getChartSettingsMenuItem());
// Part2, tests {@link ChartActivity#onOptionsItemSelected()}. Clicks on the
// "Chart settings", and then verify that the dialog contains the
// "By distance" text.
solo.clickOnText(chartActivity.getString(R.string.menu_chart_view_chart_settings));
instrumentation.waitForIdleSync();
assertTrue(solo.searchText(chartActivity.getString(R.string.chart_settings_by_distance)));
}
/**
* Tests the logic to get the incorrect values of sensor in {@link
* ChartActivity#fillDataPoint(Location, double[])}.
*/
public void testFillDataPoint_sensorIncorrect() {
MyTracksLocation myTracksLocation = getMyTracksLocation();
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
// No input.
double[] point = fillDataPointTestHelper(myTracksLocation, false);
assertEquals(Double.NaN, point[3]);
@@ -169,7 +138,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
* ChartActivity#fillDataPoint(Location, double[])}.
*/
public void testFillDataPoint_sensorCorrect() {
MyTracksLocation myTracksLocation = getMyTracksLocation();
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
// No input.
double[] point = fillDataPointTestHelper(myTracksLocation, false);
assertEquals(Double.NaN, point[3]);
@@ -203,17 +172,17 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
// By distance.
chartActivity.getChartView().setMode(ChartView.Mode.BY_DISTANCE);
// Resets last location and writes first location.
MyTracksLocation myTracksLocation1 = getMyTracksLocation();
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
double[] point = fillDataPointTestHelper(myTracksLocation1, true);
assertEquals(0.0, point[0]);
// The second is a same location, just different time.
MyTracksLocation myTracksLocation2 = getMyTracksLocation();
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
point = fillDataPointTestHelper(myTracksLocation2, false);
assertEquals(0.0, point[0]);
// The third location is a new location, and use metric.
MyTracksLocation myTracksLocation3 = getMyTracksLocation();
MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation();
myTracksLocation3.setLatitude(23);
point = fillDataPointTestHelper(myTracksLocation3, false);
// Computes the distance between Latitude 22 and 23.
@@ -224,7 +193,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
assertEquals(distance1 / KILOMETER_TO_METER, point[0]);
// The fourth location is a new location, and use metric.
MyTracksLocation myTracksLocation4 = getMyTracksLocation();
MyTracksLocation myTracksLocation4 = TrackStubUtils.createMyTracksLocation();
myTracksLocation4.setLatitude(24);
point = fillDataPointTestHelper(myTracksLocation4, false);
// Computes the distance between Latitude 23 and 24.
@@ -244,12 +213,12 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
chartActivity.onUnitsChanged(false);
// The first is a same location, just different time.
MyTracksLocation myTracksLocation1 = getMyTracksLocation();
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
double[] point = fillDataPointTestHelper(myTracksLocation1, true);
assertEquals(0.0, point[0]);
// The second location is a new location, and use imperial.
MyTracksLocation myTracksLocation2 = getMyTracksLocation();
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
myTracksLocation2.setLatitude(23);
point = fillDataPointTestHelper(myTracksLocation2, false);
/*
@@ -263,7 +232,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
assertEquals(distance1 / KILOMETER_TO_METER, point[0]);
// The third location is a new location, and use imperial.
MyTracksLocation myTracksLocation3 = getMyTracksLocation();
MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation();
myTracksLocation3.setLatitude(24);
point = fillDataPointTestHelper(myTracksLocation3, false);
/*
@@ -283,11 +252,11 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
public void testFillDataPoint_time() {
// By time
chartActivity.getChartView().setMode(ChartView.Mode.BY_TIME);
MyTracksLocation myTracksLocation1 = getMyTracksLocation();
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
double[] point = fillDataPointTestHelper(myTracksLocation1, true);
assertEquals(0.0, point[0]);
long timeSpan = 222;
MyTracksLocation myTracksLocation2 = getMyTracksLocation();
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
myTracksLocation2.setTime(myTracksLocation1.getTime() + timeSpan);
point = fillDataPointTestHelper(myTracksLocation2, false);
assertEquals((double) timeSpan, point[0]);
@@ -295,29 +264,29 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
/**
* Tests the logic to get the value of elevation in
* {@link ChartActivity#fillDataPoint} by one and two points.
* {@link ChartActivity#fillDataPoint(Location, double[])} by one and two points.
*/
public void testFillDataPoint_elevation() {
MyTracksLocation myTracksLocation1 = getMyTracksLocation();
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
/*
* At first, clear old points of elevation, so give true to the second
* parameter. Then only one value INITIALLONGTITUDE in buffer.
*/
double[] point = fillDataPointTestHelper(myTracksLocation1, true);
assertEquals(INITIAL_ALTITUDE, point[1]);
assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point[1]);
/*
* Send another value to buffer, now there are two values, INITIALALTITUDE
* and INITIALALTITUDE * 2.
*/
MyTracksLocation myTracksLocation2 = getMyTracksLocation();
myTracksLocation2.setAltitude(INITIAL_ALTITUDE * 2);
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
myTracksLocation2.setAltitude(TrackStubUtils.INITIAL_ALTITUDE * 2);
point = fillDataPointTestHelper(myTracksLocation2, false);
assertEquals((INITIAL_ALTITUDE + INITIAL_ALTITUDE * 2) / 2.0, point[1]);
assertEquals((TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0, point[1]);
}
/**
* Tests the logic to get the value of speed in
* {@link ChartActivity#fillDataPoint}. In this test, firstly remove all
* {@link ChartActivity#fillDataPoint(Location, double[])}. In this test, firstly remove all
* points in memory, and then fill in two points one by one. The speed values
* of these points are 129, 130.
*/
@@ -328,7 +297,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
* At first, clear old points of speed, so give true to the second
* parameter. It will not be filled in to the speed buffer.
*/
MyTracksLocation myTracksLocation1 = getMyTracksLocation();
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
myTracksLocation1.setSpeed(129);
double[] point = fillDataPointTestHelper(myTracksLocation1, true);
assertEquals(0.0, point[2]);
@@ -337,7 +306,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
* Tests the logic when both metricUnits and reportSpeed are true.This
* location will be filled into speed buffer.
*/
MyTracksLocation myTracksLocation2 = getMyTracksLocation();
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
// Add a time span here to make sure the second point is valid, the value
// 222 here is doesn't matter.
myTracksLocation2.setTime(myTracksLocation1.getTime() + 222);
@@ -352,7 +321,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
public void testFillDataPoint_speedImperial() {
// Setups to use imperial.
chartActivity.onUnitsChanged(false);
MyTracksLocation myTracksLocation = getMyTracksLocation();
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
myTracksLocation.setSpeed(132);
double[] point = fillDataPointTestHelper(myTracksLocation, true);
assertEquals(132.0 * METER_PER_SECOND_TO_KILOMETER_PER_HOUR * UnitConversions.KM_TO_MI,
@@ -365,7 +334,7 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
public void testFillDataPoint_pace_nonZeroSpeed() {
// Setups reportSpeed to false.
chartActivity.onReportSpeedChanged(false);
MyTracksLocation myTracksLocation = getMyTracksLocation();
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
myTracksLocation.setSpeed(134);
double[] point = fillDataPointTestHelper(myTracksLocation, true);
assertEquals(HOURS_PER_UNIT / (134.0 * METER_PER_SECOND_TO_KILOMETER_PER_HOUR), point[2]);
@@ -379,38 +348,17 @@ public class ChartActivityTest extends ActivityInstrumentationTestCase2<ChartAct
public void testFillDataPoint_pace_zeroSpeed() {
// Setups reportSpeed to false.
chartActivity.onReportSpeedChanged(false);
MyTracksLocation myTracksLocation = getMyTracksLocation();
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
myTracksLocation.setSpeed(0);
double[] point = fillDataPointTestHelper(myTracksLocation, true);
assertEquals(Double.NaN, point[2]);
}
/**
* Simulates a MyTracksLocation for test.
*
* @return a simulated location.
*/
private MyTracksLocation getMyTracksLocation() {
// Initial Location
Location loc = new Location(LOCATION_PROVIDER);
loc.setLongitude(INITIAL_LONGTITUDE);
loc.setLatitude(INITIAL_LATITUDE);
loc.setAltitude(INITIAL_ALTITUDE);
loc.setAccuracy(INITIAL_ACCURACY);
loc.setSpeed(INITIAL_SPEED);
loc.setTime(System.currentTimeMillis());
loc.setBearing(INITIAL_BEARING);
SensorDataSet sd = SensorDataSet.newBuilder().build();
MyTracksLocation myTracksLocation = new MyTracksLocation(loc, sd);
return myTracksLocation;
}
/**
* Helper method to test fillDataPoint.
*
* @param location location to fill
* @param operation a flag to do some operations
* @param isNeedClear true to clear the track points
* @return data of this location
*/
private double[] fillDataPointTestHelper(Location location, boolean isNeedClear) {
@@ -1,82 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.ChartView.Mode;
import com.google.android.maps.mytracks.R;
import android.test.ActivityInstrumentationTestCase2;
/**
* Tests the {@link ChartSettingsDialog}.
*
* @author Youtao Liu
*/
public class ChartSettingsDialogTest extends ActivityInstrumentationTestCase2<ChartActivity> {
private ChartSettingsDialog chartSettingsDialog;
public ChartSettingsDialogTest() {
super(ChartActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
chartSettingsDialog = new ChartSettingsDialog(getActivity());
chartSettingsDialog.show();
}
/**
* Tests the {@link ChartSettingsDialog#setMode} and check the result by
* {@link ChartSettingsDialog#getMode}. Gets all modes of Mode, then set and
* get each mode.
*/
public void testSetMode() {
Mode[] modes = Mode.values();
for (Mode mode : modes) {
chartSettingsDialog.setMode(mode);
assertEquals(mode, chartSettingsDialog.getMode());
}
}
/**
* Tests the {@link ChartSettingsDialog#setDisplaySpeed}.
*/
public void testSetDisplaySpeed() {
chartSettingsDialog.setDisplaySpeed(true);
assertEquals(getActivity().getString(R.string.stat_speed),
chartSettingsDialog.getSeries()[ChartView.SPEED_SERIES].getText());
chartSettingsDialog.setDisplaySpeed(false);
assertEquals(getActivity().getString(R.string.stat_pace),
chartSettingsDialog.getSeries()[ChartView.SPEED_SERIES].getText());
}
/**
* Tests the {@link ChartSettingsDialog#setSeriesEnabled} and check the result
* by {@link ChartSettingsDialog#isSeriesEnabled}.
*/
public void testSetSeriesEnabled() {
for (int i = 0; i < ChartView.NUM_SERIES; i++) {
chartSettingsDialog.setSeriesEnabled(i, true);
assertEquals(true, chartSettingsDialog.getSeries()[i].isChecked());
assertEquals(true, chartSettingsDialog.isSeriesEnabled(i));
chartSettingsDialog.setSeriesEnabled(i, false);
assertEquals(false, chartSettingsDialog.getSeries()[i].isChecked());
assertEquals(false, chartSettingsDialog.isSeriesEnabled(i));
}
}
}
@@ -19,31 +19,28 @@ import com.google.android.apps.mytracks.services.ServiceUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.Instrumentation.ActivityMonitor;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.Button;
import java.io.File;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* A unit test for {@link MyTracks} activity.
* A unit test for {@link TrackDetailActivity}.
*
* @author Bartlomiej Niechwiej
*/
public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
public class TrackDetailActivityTest extends ActivityInstrumentationTestCase2<TrackDetailActivity>{
private SharedPreferences sharedPreferences;
private TrackRecordingServiceConnection serviceConnection;
public MyTracksTest() {
super(MyTracks.class);
public TrackDetailActivityTest() {
super(TrackDetailActivity.class);
}
@Override
@@ -59,10 +56,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
// Check if not recording.
assertFalse(isRecording());
assertEquals(-1, getRecordingTrackId());
long selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
assertEquals(-1, getRecordingTrackId());
}
public void testInitialization_viewActionWithNoData() {
@@ -75,10 +69,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
// Check if not recording.
assertFalse(isRecording());
assertEquals(-1, getRecordingTrackId());
long selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
assertEquals(-1, getRecordingTrackId());
}
public void testInitialization_viewActionWithValidData() throws Exception {
@@ -97,10 +88,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
// Check if not recording.
assertFalse(isRecording());
assertEquals(-1, getRecordingTrackId());
long selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
// TODO: Finish this test.
}
@@ -117,75 +105,10 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
// Check if not recording.
assertFalse(isRecording());
assertEquals(-1, getRecordingTrackId());
long selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
// TODO: Finish this test.
}
public void testRecording_startAndStop() throws Exception {
assertInitialized();
// Check if not recording.
clearSelectedAndRecordingTracks();
waitForIdle();
assertFalse(isRecording());
assertEquals(-1, getRecordingTrackId());
long selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
// Start a new track.
getActivity().startRecording();
serviceConnection.bindIfRunning();
long recordingTrackId = awaitRecordingStatus(5000, true);
assertTrue(recordingTrackId >= 0);
// Wait until we are done and make sure that selectedTrack = recordingTrack.
waitForIdle();
assertEquals(recordingTrackId, getSharedPreferences().getLong(
getActivity().getString(R.string.recording_track_key), -1));
selectedTrackId = getSharedPreferences().getLong(
getActivity().getString(R.string.selected_track_key), -1);
assertEquals(recordingTrackId, selectedTrackId);
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
// Watch for MyTracksDetails activity.
ActivityMonitor monitor = getInstrumentation().addMonitor(
TrackDetail.class.getName(), null, false);
// Now, stop the track and make sure that it is still selected, but
// no longer recording.
getActivity().stopRecording();
// Check if we got back MyTracksDetails activity.
Activity activity = getInstrumentation().waitForMonitor(monitor);
assertTrue(activity instanceof TrackDetail);
// TODO: Update track name and other properties and test if they were
// properly saved.
// Simulate a click on Save button.
final Button save = (Button) activity.findViewById(R.id.track_detail_save);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
save.performClick();
}
});
// Check the remaining properties.
recordingTrackId = awaitRecordingStatus(5000, false);
assertEquals(-1, recordingTrackId);
assertEquals(recordingTrackId, getRecordingTrackId());
assertEquals(recordingTrackId, getSharedPreferences().getLong(
getActivity().getString(R.string.recording_track_key), -1));
// Make sure this is the same track as the last recording track ID.
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
}
private void assertInitialized() {
assertNotNull(getActivity());
@@ -0,0 +1,90 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Track;
import android.location.Location;
/**
* Commons utilities for creating stubs of track, location. The class will be
* enriched if needs more similar stubs for test.
*
* @author Youtao Liu
*/
public class TrackStubUtils {
static final String LOCATION_PROVIDER = "gps";
public static final double INITIAL_LATITUDE = 22;
public static final double INITIAL_LONGITUDE = 22;
public static final double INITIAL_ALTITUDE = 22;
static final float INITIAL_ACCURACY = 5;
static final float INITIAL_SPEED = 10;
static final float INITIAL_BEARING = 3.0f;
// Used to change the value of latitude, longitude, and altitude.
static final double DIFFERENCE = 0.01;
/**
* Gets a a {@link Track} stub with specified number of locations.
*
* @param numberOfLocations the number of locations for the track
* @return a track stub.
*/
public static Track createTrack(int numberOfLocations) {
Track track = new Track();
for (int i = 0; i < numberOfLocations; i++) {
track.addLocation(createMyTracksLocation(INITIAL_LATITUDE + i * DIFFERENCE, INITIAL_LONGITUDE
+ i * DIFFERENCE, INITIAL_ALTITUDE + i * DIFFERENCE));
}
return track;
}
/**
* Create a MyTracks location with default values.
*
* @return a track stub.
*/
public static MyTracksLocation createMyTracksLocation() {
return createMyTracksLocation(INITIAL_LATITUDE, INITIAL_LONGITUDE, INITIAL_ALTITUDE);
}
/**
* Creates a {@link MyTracksLocation} stub with specified values.
*
* @return a MyTracksLocation stub.
*/
public static MyTracksLocation createMyTracksLocation(double latitude, double longitude,
double altitude) {
// Initial Location
Location loc = new Location(LOCATION_PROVIDER);
loc.setLatitude(latitude);
loc.setLongitude(longitude);
loc.setAltitude(altitude);
loc.setAccuracy(INITIAL_ACCURACY);
loc.setSpeed(INITIAL_SPEED);
loc.setTime(System.currentTimeMillis());
loc.setBearing(INITIAL_BEARING);
SensorDataSet sd = SensorDataSet.newBuilder().build();
MyTracksLocation myTracksLocation = new MyTracksLocation(loc, sd);
return myTracksLocation;
}
}
@@ -17,7 +17,6 @@
package com.google.android.apps.mytracks.content;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import android.test.AndroidTestCase;
@@ -138,10 +137,7 @@ public class DescriptionGeneratorImplTest extends AndroidTestCase {
*/
public void testWriteSpeed() {
StringBuilder builder = new StringBuilder();
Pair<Double, Double> speed = descriptionGenerator.writeSpeed(
1.1, builder, R.string.description_average_speed, "\n");
assertEquals(3.96, speed.first);
assertEquals(3.96 * UnitConversions.KM_TO_MI, speed.second);
descriptionGenerator.writeSpeed(1.1, builder, R.string.description_average_speed, "\n");
assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString());
}
@@ -116,8 +116,8 @@ public class SendDocsUtilsTest extends AndroidTestCase {
+ "<gsx:name><![CDATA[trackName]]></gsx:name>"
+ "<gsx:description><![CDATA[trackDescription]]></gsx:description>" + "<gsx:date><![CDATA["
+ StringUtils.formatDateTime(getContext(), TIME) + "]]></gsx:date>"
+ "<gsx:totaltime><![CDATA[00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[00:04]]></gsx:movingtime>"
+ "<gsx:totaltime><![CDATA[0:00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[0:00:04]]></gsx:movingtime>"
+ "<gsx:distance><![CDATA[20.00]]></gsx:distance>"
+ "<gsx:distanceunit><![CDATA[km]]></gsx:distanceunit>"
+ "<gsx:averagespeed><![CDATA[14,400.00]]></gsx:averagespeed>"
@@ -144,8 +144,8 @@ public class SendDocsUtilsTest extends AndroidTestCase {
+ "<gsx:name><![CDATA[trackName]]></gsx:name>"
+ "<gsx:description><![CDATA[trackDescription]]></gsx:description>" + "<gsx:date><![CDATA["
+ StringUtils.formatDateTime(getContext(), TIME) + "]]></gsx:date>"
+ "<gsx:totaltime><![CDATA[00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[00:04]]></gsx:movingtime>"
+ "<gsx:totaltime><![CDATA[0:00:05]]></gsx:totaltime>"
+ "<gsx:movingtime><![CDATA[0:00:04]]></gsx:movingtime>"
+ "<gsx:distance><![CDATA[12.43]]></gsx:distance>"
+ "<gsx:distanceunit><![CDATA[mi]]></gsx:distanceunit>"
+ "<gsx:averagespeed><![CDATA[8,947.75]]></gsx:averagespeed>"
@@ -36,21 +36,21 @@ public class CsvTrackWriterTest extends TrackFormatWriterTest {
"Accuracy (m)", "Speed (m/s)", "Time");
String expectedMarker1 = getExpectedLine(WAYPOINT1_NAME, WAYPOINT1_CATEGORY,
WAYPOINT1_DESCRIPTION, "1.0", "-1.0", "10.0", "100.0", "1,000", "10,000",
"1970-01-01T00:01:40Z");
"1970-01-01T00:01:40.000Z");
String expectedMarker2 = getExpectedLine(WAYPOINT2_NAME, WAYPOINT2_CATEGORY,
WAYPOINT2_DESCRIPTION, "2.0", "-2.0", "20.0", "200.0", "2,000", "20,000",
"1970-01-01T00:03:20Z");
"1970-01-01T00:03:20.000Z");
String expectedPointHeader = getExpectedLine("Segment", "Point", "Latitude (deg)",
"Longitude (deg)", "Altitude (m)", "Bearing (deg)", "Accuracy (m)", "Speed (m/s)", "Time",
"Power (W)", "Cadence (rpm)", "Heart rate (bpm)", "Battery level (%)");
String expectedPoint1 = getExpectedLine("1", "1", "0.0", "0.0", "0.0", "0.0", "0", "0",
"1970-01-01T00:00:00Z", "100.0", "200.0", "300.0", "400.0");
"1970-01-01T00:00:00.000Z", "100.0", "200.0", "300.0", "400.0");
String expectedPoint2 = getExpectedLine("1", "2", "1.0", "-1.0", "10.0", "100.0", "1,000",
"10,000", "1970-01-01T00:01:40Z", "101.0", "201.0", "301.0", "401.0");
"10,000", "1970-01-01T00:01:40.000Z", "101.0", "201.0", "301.0", "401.0");
String expectedPoint3 = getExpectedLine("2", "1", "2.0", "-2.0", "20.0", "200.0", "2,000",
"20,000", "1970-01-01T00:03:20Z", "102.0", "202.0", "302.0", "402.0");
"20,000", "1970-01-01T00:03:20.000Z", "102.0", "202.0", "302.0", "402.0");
String expectedPoint4 = getExpectedLine("2", "2", "3.0", "-3.0", "30.0", "300.0", "3,000",
"30,000", "1970-01-01T00:05:00Z", "103.0", "203.0", "303.0", "403.0");
"30,000", "1970-01-01T00:05:00.000Z", "103.0", "203.0", "303.0", "403.0");
String expected = expectedTrackHeader + expectedTrack + "\n"
+ expectedMarkerHeader + expectedMarker1 + expectedMarker2 + "\n"
+ expectedPointHeader + expectedPoint1 + expectedPoint2 + expectedPoint3 + expectedPoint4;
@@ -38,23 +38,23 @@ public class GpxTrackWriterTest extends TrackFormatWriterTest {
assertEquals(TRACK_DESCRIPTION, getChildTextValue(trackTag, "desc"));
List<Element> segmentTags = getChildElements(trackTag, "trkseg", 2);
List<Element> segPointTags = getChildElements(segmentTags.get(0), "trkpt", 2);
assertTagMatchesLocation(segPointTags.get(0), "0", "0", "1970-01-01T00:00:00Z", "0");
assertTagMatchesLocation(segPointTags.get(1), "1", "-1", "1970-01-01T00:01:40Z", "10");
assertTagMatchesLocation(segPointTags.get(0), "0", "0", "1970-01-01T00:00:00.000Z", "0");
assertTagMatchesLocation(segPointTags.get(1), "1", "-1", "1970-01-01T00:01:40.000Z", "10");
segPointTags = getChildElements(segmentTags.get(1), "trkpt", 2);
assertTagMatchesLocation(segPointTags.get(0), "2", "-2", "1970-01-01T00:03:20Z", "20");
assertTagMatchesLocation(segPointTags.get(1), "3", "-3", "1970-01-01T00:05:00Z", "30");
assertTagMatchesLocation(segPointTags.get(0), "2", "-2", "1970-01-01T00:03:20.000Z", "20");
assertTagMatchesLocation(segPointTags.get(1), "3", "-3", "1970-01-01T00:05:00.000Z", "30");
List<Element> waypointTags = getChildElements(gpxTag, "wpt", 2);
Element wptTag = waypointTags.get(0);
assertEquals(WAYPOINT1_NAME, getChildTextValue(wptTag, "name"));
assertEquals(WAYPOINT1_DESCRIPTION, getChildTextValue(wptTag, "desc"));
assertTagMatchesLocation(wptTag, "1", "-1", "1970-01-01T00:01:40Z", "10");
assertTagMatchesLocation(wptTag, "1", "-1", "1970-01-01T00:01:40.000Z", "10");
wptTag = waypointTags.get(1);
assertEquals(WAYPOINT2_NAME, getChildTextValue(wptTag, "name"));
assertEquals(WAYPOINT2_DESCRIPTION, getChildTextValue(wptTag, "desc"));
assertTagMatchesLocation(wptTag, "2", "-2", "1970-01-01T00:03:20Z", "20");
assertTagMatchesLocation(wptTag, "2", "-2", "1970-01-01T00:03:20.000Z", "20");
}
/**
@@ -19,21 +19,14 @@ import java.io.File;
/**
* A simple, fake {@link TrackWriter} subclass with all methods mocked out.
* Tests are expected to override {@link #writeTrack} and/or
* {@link #writeTrackAsync}, at the very least.
* Tests are expected to override {@link #writeTrack}.
*
* @author Matthew Simmons
*
*/
public class MockTrackWriter implements TrackWriter {
public OnCompletionListener onCompletionListener;
public OnWriteListener onWriteListener;
@Override
public void setOnCompletionListener(OnCompletionListener onCompletionListener) {
this.onCompletionListener = onCompletionListener;
}
@Override
public void setOnWriteListener(OnWriteListener onWriteListener) {
this.onWriteListener = onWriteListener;
@@ -49,11 +42,6 @@ public class MockTrackWriter implements TrackWriter {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void writeTrackAsync() {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void writeTrack() {
throw new UnsupportedOperationException("not implemented");
@@ -11,7 +11,6 @@ import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.location.Location;
@@ -25,7 +24,6 @@ import java.io.FileNotFoundException;
import java.io.OutputStream;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.easymock.IArgumentMatcher;
import org.easymock.IMocksControl;
@@ -171,13 +169,7 @@ public class TrackWriterTest extends AndroidTestCase {
writer = new WriteTracksTrackWriter(getContext(), providerUtils, track,
formatWriter, true);
// Expect the completion listener to be run
TrackWriter.OnCompletionListener completionListener
= mocksControl.createMock(TrackWriter.OnCompletionListener.class);
completionListener.onComplete();
mocksControl.replay();
writer.setOnCompletionListener(completionListener);
writer.writeTrack();
assertEquals(1, writeDocumentCalls);
@@ -185,54 +177,11 @@ public class TrackWriterTest extends AndroidTestCase {
mocksControl.verify();
}
public void testWriteTrack_cancelled() throws Exception {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
writer = new OpenFileTrackWriter(
getContext(), providerUtils, track, formatWriter, stream, true);
formatWriter.prepare(track, stream);
final Location[] locs = {
new Location("fake0"),
new Location("fake1"),
};
fillLocations(locs);
assertEquals(locs.length, providerUtils.bulkInsertTrackPoints(locs, locs.length, TRACK_ID));
formatWriter.writeHeader();
formatWriter.writeBeginTrack(locEq(locs[0]));
formatWriter.writeOpenSegment();
formatWriter.writeLocation(locEq(locs[0]));
//EasyMock.expectLastCall().andThrow(new InterruptedException());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
throw new InterruptedException();
}
});
mocksControl.replay();
writer.writeTrack();
mocksControl.verify();
assertFalse(writer.wasSuccess());
assertEquals(R.string.sd_card_canceled, writer.getErrorMessage());
}
public void testWriteTrack_openFails() {
writer = new WriteTracksTrackWriter(getContext(), providerUtils, track,
formatWriter, false);
// Expect the completion listener to be run
TrackWriter.OnCompletionListener completionListener
= mocksControl.createMock(TrackWriter.OnCompletionListener.class);
completionListener.onComplete();
mocksControl.replay();
writer.setOnCompletionListener(completionListener);
writer.writeTrack();
assertEquals(0, writeDocumentCalls);
@@ -316,8 +265,10 @@ public class TrackWriterTest extends AndroidTestCase {
formatWriter.writeHeader();
// Expect reading/writing of the waypoints (except the first)
formatWriter.writeBeginWaypoints();
formatWriter.writeWaypoint(wptEq(wps[1]));
formatWriter.writeWaypoint(wptEq(wps[2]));
formatWriter.writeEndWaypoints();
// Begin the track
formatWriter.writeBeginTrack(locEq(locs[0]));
@@ -1,90 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.file;
import android.app.ProgressDialog;
import android.test.ActivityInstrumentationTestCase2;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
/**
* Tests {@link WriteProgressController}.
*
* @author Matthew Simmons
*/
public class WriteProgressControllerTest extends ActivityInstrumentationTestCase2<SaveActivity> {
public WriteProgressControllerTest() {
super(SaveActivity.class);
}
private static void assertProgress(ProgressDialog dialog, int expectedProgress,
int expectedMax) {
assertEquals(expectedProgress, dialog.getProgress());
assertEquals(expectedMax, dialog.getMax());
}
public void testSimple() throws Exception {
final AtomicReference<ProgressDialog> dialogRef = new AtomicReference<ProgressDialog>();
final AtomicReference<Boolean> controllerDoneRef = new AtomicReference<Boolean>();
final Semaphore writerDone = new Semaphore(0);
TrackWriter mockWriter = new MockTrackWriter() {
@Override
public void writeTrackAsync() {
onWriteListener.onWrite(1000, 10000);
assertProgress(dialogRef.get(), 1000, 10000);
onCompletionListener.onComplete();
writerDone.release();
}
};
final WriteProgressController controller = new WriteProgressController(
getActivity(), mockWriter, SaveActivity.PROGRESS_DIALOG);
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
@Override
public void onComplete() {
controllerDoneRef.set(true);
}
});
/*
* The WriteProgressController constructor calls the mockWriter's
* setOnCompletionListener method with a listener that dismisses the
* progress dialog. However, this unit test only tests the
* WriteProgressController and doesn't actually show any progress dialog.
* Thus after the WriteProgressController is setup, we need to call the
* mockWriter's setOnCompletionListener method again with an listener that
* doesn't dismiss dialog.
*/
mockWriter.setOnCompletionListener(new TrackWriter.OnCompletionListener() {
@Override
public void onComplete() {
controller.getOnCompletionListener().onComplete();
}
});
dialogRef.set(controller.createProgressDialog());
controller.startWrite();
// wait for the writer to finish
writerDone.acquire();
assertTrue(controllerDoneRef.get());
}
}
@@ -0,0 +1,199 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.maps;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
import android.accounts.Account;
import android.test.AndroidTestCase;
import java.util.ArrayList;
/**
* Tests {@link ChooseMapAsyncTask}.
*
* @author Youtao Liu
*/
public class ChooseMapAsyncTaskTest extends AndroidTestCase {
private ChooseMapActivity chooseMapActivityMock;
private Account account;
private static final String ACCOUNT_NAME = "AccountName";
private static final String ACCOUNT_TYPE = "AccountType";
private boolean getMapsStatus = false;
public class ChooseMapAsyncTaskMock extends ChooseMapAsyncTask {
public ChooseMapAsyncTaskMock(ChooseMapActivity activity, Account account) {
super(activity, account);
}
/**
* Creates this method to override {@link ChooseMapAsyncTask#getMaps()}.
*
* @return mock the return value of getMaps().
*/
@Override
boolean getMaps() {
return getMapsStatus;
}
}
/**
* Tests {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
* task is completed. Makes sure it calls
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
* .
*/
public void testSetActivity_completed() {
setup();
chooseMapActivityMock.onAsyncTaskCompleted(false, null, null);
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
chooseMapAsyncTask.setCompleted(true);
chooseMapAsyncTask.setActivity(chooseMapActivityMock);
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Test {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
* task is not completed. Makes sure
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
* is not invoked.
*/
public void testSetActivity_notCompleted() {
setup();
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
chooseMapAsyncTask.setCompleted(false);
chooseMapAsyncTask.setActivity(chooseMapActivityMock);
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
* activity is null. Makes sure
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
* is not invoked.
*/
public void testSetActivity_nullActivity() {
setup();
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
chooseMapAsyncTask.setCompleted(true);
chooseMapAsyncTask.setActivity(null);
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests the method {@link ChooseMapAsyncTask#onPostExecute(Boolean)} when the
* result is true. Makes sure
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
* is invoked.
*/
public void testOnPostExecute_trueResult() {
setup();
chooseMapActivityMock.onAsyncTaskCompleted(true, null, null);
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
chooseMapAsyncTask.onPostExecute(true);
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests the method {@link ChooseMapAsyncTask#onPostExecute(Boolean)} when the
* result is false. Makes sure
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
* is invoked.
*/
public void testOnPostExecute_falseResult() {
setup();
chooseMapActivityMock.onAsyncTaskCompleted(false, null, null);
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
chooseMapAsyncTask.onPostExecute(false);
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure can
* not retry again after have retried once and failed.
*/
public void testRetryUpload() throws Exception {
setup();
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
chooseMapActivityMock, account);
chooseMapAsyncTaskTMock.setCanRetry(false);
getMapsStatus = true;
assertFalse(chooseMapAsyncTaskTMock.retryUpload());
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure can
* retry after get maps failed and never retry before.
*/
public void testRetryUpload_retryOnce() throws Exception {
setup();
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
chooseMapActivityMock, account);
chooseMapAsyncTaskTMock.setCanRetry(true);
getMapsStatus = false;
assertFalse(chooseMapAsyncTaskTMock.retryUpload());
// Can only retry once.
assertFalse(chooseMapAsyncTaskTMock.getCanRetry());
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure will
* not retry after get maps successfully.
*/
public void testRetryUpload_successGetMaps() throws Exception {
setup();
AndroidMock.replay(chooseMapActivityMock);
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
chooseMapActivityMock, account);
chooseMapAsyncTaskTMock.setCanRetry(true);
getMapsStatus = true;
assertTrue(chooseMapAsyncTaskTMock.retryUpload());
// Can only retry once.
assertFalse(chooseMapAsyncTaskTMock.getCanRetry());
AndroidMock.verify(chooseMapActivityMock);
}
/**
* Initials setup for test.
*/
void setup() {
setupChooseMapActivityMock();
account = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
}
/**
* Create a mock object of ChooseMapActivity.
*/
@UsesMocks(ChooseMapActivity.class)
private void setupChooseMapActivityMock() {
chooseMapActivityMock = AndroidMock.createMock(ChooseMapActivity.class);
// This is used in the constructor of ChooseMapAsyncTask.
AndroidMock.expect(chooseMapActivityMock.getApplicationContext()).andReturn(getContext()).anyTimes();
}
}
@@ -0,0 +1,356 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.maps;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.TrackStubUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.gdata.maps.MapsGDataConverter;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
import android.accounts.Account;
import android.database.Cursor;
import android.location.Location;
import android.test.AndroidTestCase;
import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
/**
* Tests {@link SendMapsAsyncTask}.
*
* @author Youtao Liu
*/
public class SendMapsAsyncTaskTest extends AndroidTestCase {
private static final long TRACK_ID = 1;
private static final String MAP_ID = "MapID_1";
// Records the run times of {@link SendMapsAsyncTaskMock#uploadMarker(String,
// String, String, Location)}
private int uploadMarkerCounter = 0;
// Records the run times of {@link
// SendMapsAsyncTaskMock#prepareAndUploadPoints(Track, List<Location>,
// boolean)}
private int prepareAndUploadPointsCounter = 0;
private SendMapsActivity sendMapsActivityMock;
private MyTracksProviderUtils myTracksProviderUtilsMock;
private SendRequest sendRequest;
private class SendMapsAsyncTaskMock extends SendMapsAsyncTask {
private boolean[] uploadMarkerResult = { false, false };
private boolean prepareAndUploadPointsResult = false;
private SendMapsAsyncTaskMock(SendMapsActivity activity, long trackId, Account account,
String chooseMapId, MyTracksProviderUtils myTracksProviderUtils) {
super(activity, trackId, account, chooseMapId, myTracksProviderUtils);
}
@Override
boolean uploadMarker(String title, String description, String iconUrl, Location location) {
int runTimes = uploadMarkerCounter++;
return uploadMarkerResult[runTimes];
}
@Override
boolean prepareAndUploadPoints(Track track, List<Location> locations, boolean lastBatch) {
prepareAndUploadPointsCounter++;
return prepareAndUploadPointsResult;
}
}
@Override
@UsesMocks({ SendMapsActivity.class, MyTracksProviderUtils.class })
protected void setUp() throws Exception {
super.setUp();
uploadMarkerCounter = 0;
prepareAndUploadPointsCounter = 0;
sendMapsActivityMock = AndroidMock.createMock(SendMapsActivity.class);
myTracksProviderUtilsMock = AndroidMock.createMock(MyTracksProviderUtils.class);
sendRequest = new SendRequest(TRACK_ID, false, true, false);
AndroidMock.expect(sendMapsActivityMock.getApplicationContext()).andReturn(getContext());
}
/**
* Tests the method {@link SendMapsAsyncTask#saveResult()}and makes sure the
* track is updated.
*/
public void testSaveResult() {
Track track = TrackStubUtils.createTrack(1);
track.setMapId(null);
AndroidMock.expect(myTracksProviderUtilsMock.getTrack(TRACK_ID)).andReturn(track);
myTracksProviderUtilsMock.updateTrack(track);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), sendRequest.getMapId(),
myTracksProviderUtilsMock);
sendMapsAsyncTask.saveResult();
assertEquals(sendRequest.getMapId(), track.getMapId());
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
}
/**
* Tests {@link SendMapsAsyncTask#fetchSendMapId(Track)} when chooseMapId is
* null and makes sure it returns false.
*/
public void testFetchSendMapId_nullMapID() {
Track track = TrackStubUtils.createTrack(1);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
// Makes chooseMapId to null.
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), null, myTracksProviderUtilsMock);
// Returns false for an exception would be thrown.
assertFalse(sendMapsAsyncTask.fetchSendMapId(track));
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#fetchSendMapId(Track)} when
* chooseMapId is not null. And makes sure it returns false.
*/
public void testFetchSendMapId_notNullMapID() {
Track track = TrackStubUtils.createTrack(1);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
assertTrue(sendMapsAsyncTask.fetchSendMapId(track));
assertEquals(MAP_ID, sendMapsAsyncTask.getMapId());
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
* cursor is null. And makes sure it returns false.
*/
public void testUploadAllTrackPoints_nullCursor() {
Track track = TrackStubUtils.createTrack(1);
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
.andReturn(null);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
* uploads the first marker is failed.
*/
@UsesMocks(Cursor.class)
public void testUploadAllTrackPoints_uploadFirstMarkerFailed() {
Track track = TrackStubUtils.createTrack(1);
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
cursorMock.close();
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock)).andReturn(
new Location("1"));
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
.andReturn(cursorMock);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
sendMapsAsyncTask.uploadMarkerResult[0] = false;
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
assertEquals(1, uploadMarkerCounter);
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
* uploads the two markers is successful but failed when
* prepareAndUploadPoints.
*/
@UsesMocks(Cursor.class)
public void testUploadAllTrackPoints_prepareAndUploadPointsFailed() {
Track track = TrackStubUtils.createTrack(1);
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
cursorMock.close();
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
.andReturn(new Location("1")).times(2);
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
.andReturn(cursorMock);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
// For will be failed when run prepareAndUploadPoints, it no require to
// set uploadMarkerResult[1].
sendMapsAsyncTask.uploadMarkerResult[0] = true;
sendMapsAsyncTask.prepareAndUploadPointsResult = false;
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
assertEquals(1, uploadMarkerCounter);
assertEquals(1, prepareAndUploadPointsCounter);
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
* uploads the last marker is failed.
*/
@UsesMocks(Cursor.class)
public void testUploadAllTrackPoints_uploadLastMarkerFailed() {
Track track = TrackStubUtils.createTrack(1);
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
cursorMock.close();
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
.andReturn(new Location("1")).times(2);
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
.andReturn(cursorMock);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
sendMapsAsyncTask.uploadMarkerResult[0] = true;
sendMapsAsyncTask.uploadMarkerResult[1] = false;
sendMapsAsyncTask.prepareAndUploadPointsResult = true;
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
assertEquals(2, uploadMarkerCounter);
assertEquals(1, prepareAndUploadPointsCounter);
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
* return true.
*/
@UsesMocks(Cursor.class)
public void testUploadAllTrackPoints_success() {
Track track = TrackStubUtils.createTrack(1);
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
cursorMock.close();
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
.andReturn(new Location("1")).times(2);
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
.andReturn(cursorMock);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
sendMapsAsyncTask.uploadMarkerResult[0] = true;
sendMapsAsyncTask.uploadMarkerResult[1] = true;
sendMapsAsyncTask.prepareAndUploadPointsResult = true;
assertTrue(sendMapsAsyncTask.uploadAllTrackPoints(track));
assertEquals(2, uploadMarkerCounter);
assertEquals(1, prepareAndUploadPointsCounter);
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()} when cursor is
* null.
*/
@UsesMocks(Cursor.class)
public void testUploadWaypoints_nullCursor() {
AndroidMock.expect(
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(null);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
assertTrue(sendMapsAsyncTask.uploadWaypoints());
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()} when there is
* only one point.
*/
@UsesMocks(Cursor.class)
public void testUploadWaypoints_onePoint() {
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
AndroidMock.expect(cursorMock.moveToFirst()).andReturn(true);
// Only one point, so next is null.
AndroidMock.expect(cursorMock.moveToNext()).andReturn(false);
cursorMock.close();
AndroidMock.expect(
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(cursorMock);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
assertTrue(sendMapsAsyncTask.uploadWaypoints());
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()}. Makes sure a cursor is created and
* a way point is created with such cursor.
*
* @throws XmlPullParserException
*/
@UsesMocks(Cursor.class)
public void testUploadWaypoints() throws XmlPullParserException {
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
MapsGDataConverter mapsGDataConverterMock = new MapsGDataConverter();
AndroidMock.expect(cursorMock.moveToFirst()).andReturn(true);
AndroidMock.expect(cursorMock.moveToNext()).andReturn(true);
cursorMock.close();
AndroidMock.expect(
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(cursorMock);
Waypoint waypoint = new Waypoint();
waypoint.setLocation(TrackStubUtils.createMyTracksLocation());
AndroidMock.expect(myTracksProviderUtilsMock.createWaypoint(cursorMock)).andReturn(waypoint)
.times(1);
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
sendMapsAsyncTask.setMapsGDataConverter(mapsGDataConverterMock);
// Would be failed for there is no source for uploading.
assertFalse(sendMapsAsyncTask.uploadWaypoints());
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
}
/**
* Tests the method {@link SendMapsAsyncTask#getPercentage(int, int)}.
*/
public void testCountPercentage() {
assertEquals(SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN, SendMapsAsyncTask.getPercentage(0, 5));
assertEquals(SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MAX,
SendMapsAsyncTask.getPercentage(50, 50));
assertEquals(
(int) ((double) 5
/ 11
* (SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MAX - SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN) + SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN),
SendMapsAsyncTask.getPercentage(5, 11));
}
}
@@ -171,7 +171,7 @@ public class SendRequestTest extends AndroidTestCase {
}
/**
* Tests {@link SendRequest#SendRequest(Parcel in)} when all values are true.
* Tests SendRequest.CREATOR.createFromParcel when all values are true.
*/
public void testCreateFromParcel_true() {
Parcel sourceParcel = Parcel.obtain();
@@ -208,7 +208,7 @@ public class SendRequestTest extends AndroidTestCase {
}
/**
* Tests {@link SendRequest#SendRequest(Parcel in)} when all values are false.
* Tests SendRequest.CREATOR.createFromParcel when all values are false.
*/
public void testCreateFromParcel_false() {
Parcel sourceParcel = Parcel.obtain();
@@ -0,0 +1,140 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
/**
* Tests the {@link SendToGoogleUtils}.
*
* @author Youtao Liu
*/
import com.google.android.apps.mytracks.TrackStubUtils;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Track;
import android.location.Location;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
public class SendToGoogleUtilsTest extends TestCase {
private final static long TRACK_ID = 1L;
private final static String TRACK_CATEGORY = "trackCategory";
private final static String TRACK_NAME = "trackName";
private final static double DIFFERENCE = 0.02;
private final static double INVALID_LATITUDE = 91;
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is only one location in a segment.
*/
public void testPrepareTrackSegment_onlyOneLocation() {
Track trackStub = TrackStubUtils.createTrack(1);
assertFalse(SendToGoogleUtils.prepareTrackSegment(trackStub, null));
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, ArrayList)} when there
* is no stop time.
*/
public void testPrepareTrackSegment_noStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
assertEquals(-1L, trackStub.getStatistics().getStopTime());
ArrayList<Track> tracksArray = new ArrayList<Track>();
assertTrue(SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray));
assertEquals(trackStub, tracksArray.get(0));
// The stop time should be the time of last location
assertEquals(trackStub.getLocations().get(1).getTime(), trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
* when there is stop time.
*/
public void testPrepareTrackSegment_hasStopTime() {
Track trackStub = TrackStubUtils.createTrack(2);
// Gives a margin to make sure the this time will be not same with the last
// location in the track.
long stopTime = System.currentTimeMillis() + 1000;
trackStub.getStatistics().setStopTime(stopTime);
ArrayList<Track> tracksArray = new ArrayList<Track>();
SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray);
assertEquals(trackStub, tracksArray.get(0));
assertEquals(stopTime, trackStub.getStatistics().getStopTime());
}
/**
* Tests the method
* {@link SendToGoogleUtils#prepareLocations(Track, java.util.List)} .
*/
public void testPrepareLocations() {
Track trackStub = TrackStubUtils.createTrack(2);
trackStub.setId(TRACK_ID);
trackStub.setName(TRACK_NAME);
trackStub.setCategory(TRACK_CATEGORY);
List<Location> locationsArray = new ArrayList<Location>();
// Adds 100 location to List.
for (int i = 0; i < 100; i++) {
// Use this variable as a flag to make all points in the track can be kept
// after run the LocationUtils#decimate(Track, double) with
// Ramer–Douglas–Peucker algorithm.
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (i % 2 == 0) {
latitude -= DIFFERENCE * (i % 10);
}
// Inserts 9 points which have wrong latitude, so would have 10 segments.
if (i % 10 == 0 && i > 0) {
MyTracksLocation location = TrackStubUtils.createMyTracksLocation();
location.setLatitude(INVALID_LATITUDE);
locationsArray.add(location);
} else {
locationsArray.add(TrackStubUtils.createMyTracksLocation(latitude,
TrackStubUtils.INITIAL_LONGITUDE + DIFFERENCE * (i % 10),
TrackStubUtils.INITIAL_ALTITUDE + DIFFERENCE * (i % 10)));
}
}
ArrayList<Track> result = SendToGoogleUtils.prepareLocations(trackStub, locationsArray);
assertEquals(10, result.size());
// Checks all segments.
for (int i = 0; i < 10; i++) {
Track segmentOne = result.get(i);
assertEquals(TRACK_ID, segmentOne.getId());
assertEquals(TRACK_NAME, segmentOne.getName());
assertEquals(TRACK_CATEGORY, segmentOne.getCategory());
}
// Checks all locations in the first segment.
for (int j = 0; j < 9; j++) {
double latitude = TrackStubUtils.INITIAL_LATITUDE;
if (j % 2 == 0) {
latitude -= DIFFERENCE * (j % 10);
}
Location oneLocation = result.get(0).getLocations().get(j);
assertEquals(TrackStubUtils.createMyTracksLocation().getAltitude() + DIFFERENCE * (j % 10),
oneLocation.getAltitude());
assertEquals(latitude, oneLocation.getLatitude());
assertEquals(TrackStubUtils.createMyTracksLocation().getLongitude() + DIFFERENCE * (j % 10),
oneLocation.getLongitude());
}
}
}
@@ -0,0 +1,169 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.maps.mytracks.R;
import com.jayway.android.robotium.solo.Solo;
import android.app.Instrumentation;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Tests the {@link UploadResultActivity}.
*
* @author Youtao Liu
*/
public class UploadResultActivityTest extends
ActivityInstrumentationTestCase2<UploadResultActivity> {
private Instrumentation instrumentation;
private UploadResultActivity uploadResultActivity;
private Solo solo;
@Override
protected void setUp() throws Exception {
super.setUp();
instrumentation = getInstrumentation();
solo = new Solo(instrumentation);
}
/**
* This method is necessary for ActivityInstrumentationTestCase2.
*/
public UploadResultActivityTest() {
super(UploadResultActivity.class);
}
/**
* Checks the display of dialog when send to all and all sends are successful.
*/
public void testAllSuccess() {
initialActivity(true, true, true, true, true, true);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
assertFalse(stringHashSet
.contains(uploadResultActivity.getString(R.string.generic_error_title)));
assertFalse(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
}
/**
* Checks the display of dialog when send to all and all sends are failed.
*/
public void testAllFailed() {
// Send all kinds but all failed.
initialActivity(true, true, true, false, false, false);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains((Object) uploadResultActivity
.getString(R.string.generic_error_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
}
/**
* Checks the display of dialog when match following items:
* <ul>
* <li>Only send to Maps and Docs.</li>
* <li>Send to Maps successful.</li>
* <li>Send to Docs failed.</li>
* </ul>
*/
public void testPartialSuccess() {
initialActivity(true, false, true, true, false, false);
HashSet<String> stringHashSet = new HashSet<String>();
ArrayList<View> view = solo.getViews();
for (View oneView : view) {
if (oneView instanceof TextView && oneView.isShown()) {
stringHashSet.add((String) ((TextView) oneView).getText());
}
}
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.generic_error_title)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_fusion_tables)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.generic_success_title)));
assertFalse(stringHashSet.contains(uploadResultActivity
.getString(R.string.send_google_success_footer)));
}
/**
* Initial a {@link SendRequest} and then initials a activity to be tested.
*
* @param isSendMaps
* @param isSendFusionTables
* @param isSendDocs
* @param isMapsSuccess
* @param isFusionTablesSuccess
* @param isDocsSuccess
*/
private void initialActivity(boolean isSendMaps, boolean isSendFusionTables, boolean isSendDocs,
boolean isMapsSuccess, boolean isFusionTablesSuccess, boolean isDocsSuccess) {
Intent intent = new Intent();
SendRequest sendRequest = new SendRequest(1L, true, true, true);
sendRequest.setSendMaps(isSendMaps);
sendRequest.setSendFusionTables(isSendFusionTables);
sendRequest.setSendDocs(isSendDocs);
sendRequest.setMapsSuccess(isMapsSuccess);
sendRequest.setFusionTablesSuccess(isFusionTablesSuccess);
sendRequest.setDocsSuccess(isDocsSuccess);
intent.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
setActivityIntent(intent);
uploadResultActivity = this.getActivity();
}
}
@@ -24,7 +24,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
@@ -50,10 +49,7 @@ public class UploadServiceChooserActivityTest extends
}
/**
* Tests the logic to control display all send options. This test cover code
* in method {@link UploadServiceChooserActivity#onCreateDialog(int)},
* {@link UploadServiceChooserActivity#updateStateBySendRequest()} and
* {@link UploadServiceChooserActivity#updateStateBySelection()}.
* Tests the logic to display all options.
*/
public void testOnCreateDialog_displayAll() {
// Initials activity to display all send items.
@@ -62,7 +58,6 @@ public class UploadServiceChooserActivityTest extends
assertTrue(getMapsCheckBox().isShown());
assertTrue(getFusionTablesCheckBox().isShown());
assertTrue(getDocsCheckBox().isShown());
assertTrue(getCancelButton().isEnabled());
// Clicks to disable all send items.
uploadServiceChooserActivity.runOnUiThread(new Runnable() {
@@ -82,25 +77,19 @@ public class UploadServiceChooserActivityTest extends
assertTrue(getMapsCheckBox().isShown());
assertTrue(getFusionTablesCheckBox().isShown());
assertTrue(getDocsCheckBox().isShown());
assertTrue(getCancelButton().isEnabled());
assertFalse(getNewMapRadioButton().isShown());
assertFalse(getExistingMapRadioButton().isShown());
assertFalse(getSendButton().isEnabled());
}
/**
* Tests the logic to check the send to Google Maps option. This test cover
* code in method {@link UploadServiceChooserActivity#onCreateDialog(int)},
* {@link UploadServiceChooserActivity#updateStateBySendRequest()} and
* {@link UploadServiceChooserActivity#updateStateBySelection()}.
* Tests the logic to display only the "Send to Google Maps" option.
*/
public void testOnCreateDialog_displayOne() {
// Initials activity to display all send items.
initialActivity(true, false, false);
instrumentation.waitForIdleSync();
assertTrue(getMapsCheckBox().isShown());
assertTrue(getCancelButton().isEnabled());
// Clicks to enable this items.
uploadServiceChooserActivity.runOnUiThread(new Runnable() {
@@ -114,23 +103,16 @@ public class UploadServiceChooserActivityTest extends
assertTrue(getMapsCheckBox().isShown());
assertTrue(getNewMapRadioButton().isShown());
assertTrue(getExistingMapRadioButton().isShown());
assertTrue(getSendButton().isEnabled());
assertTrue(getCancelButton().isEnabled());
}
/**
* Tests the logic to control display none. This test cover code in method
* {@link UploadServiceChooserActivity#onCreateDialog(int)},
* {@link UploadServiceChooserActivity#updateStateBySendRequest()} and
* {@link UploadServiceChooserActivity#updateStateBySelection()}.
* Tests the logic to display no option.
*/
public void testOnCreateDialog_displayNone() {
initialActivity(false, false, false);
assertFalse(getMapsCheckBox().isShown());
assertFalse(getFusionTablesCheckBox().isShown());
assertFalse(getDocsCheckBox().isShown());
assertFalse(getSendButton().isEnabled());
assertTrue(getCancelButton().isEnabled());
}
/**
@@ -193,11 +175,8 @@ public class UploadServiceChooserActivityTest extends
/**
* Tests the logic of saveState when click send button. This test cover code
* in method {@link UploadServiceChooserActivity#saveState()},
* {@link UploadServiceChooserActivity#initState()} ,
* {@link UploadServiceChooserActivity#sendMaps()},
* {@link UploadServiceChooserActivity#sendFusionTables()}, and
* {@link UploadServiceChooserActivity#sendDocs()}.
* in method {@link UploadServiceChooserActivity#initState()} and
* {@link UploadServiceChooserActivity#saveState()},
*/
public void testOnCreateDialog_saveState() {
initialActivity(true, true, true);
@@ -228,12 +207,8 @@ public class UploadServiceChooserActivityTest extends
/**
* Tests the logic of startNextActivity when click send button. This test
* cover code in method
* {@link UploadServiceChooserActivity#startNextActivity()} ,
* {@link UploadServiceChooserActivity#initState()} ,
* {@link UploadServiceChooserActivity#sendMaps()},
* {@link UploadServiceChooserActivity#sendFusionTables()}, and
* {@link UploadServiceChooserActivity#sendDocs()}.
* cover code in method {@link UploadServiceChooserActivity#initState()} and
* {@link UploadServiceChooserActivity#startNextActivity()}.
*/
public void testOnCreateDialog_startNextActivity() {
initialActivity(true, true, true);
@@ -275,35 +250,26 @@ public class UploadServiceChooserActivityTest extends
uploadServiceChooserActivity = this.getActivity();
}
private Button getSendButton() {
return (Button) uploadServiceChooserActivity.getDialog()
.findViewById(R.id.send_google_send_now);
}
Button getCancelButton() {
return (Button) uploadServiceChooserActivity.getDialog().findViewById(R.id.send_google_cancel);
}
private CheckBox getMapsCheckBox() {
return (CheckBox) uploadServiceChooserActivity.getDialog().findViewById(R.id.send_google_maps);
return (CheckBox) uploadServiceChooserActivity.getAlertDialog().findViewById(R.id.send_google_maps);
}
private CheckBox getFusionTablesCheckBox() {
return (CheckBox) uploadServiceChooserActivity.getDialog().findViewById(
return (CheckBox) uploadServiceChooserActivity.getAlertDialog().findViewById(
R.id.send_google_fusion_tables);
}
private CheckBox getDocsCheckBox() {
return (CheckBox) uploadServiceChooserActivity.getDialog().findViewById(R.id.send_google_docs);
return (CheckBox) uploadServiceChooserActivity.getAlertDialog().findViewById(R.id.send_google_docs);
}
private RadioButton getNewMapRadioButton() {
return (RadioButton) uploadServiceChooserActivity.getDialog().findViewById(
return (RadioButton) uploadServiceChooserActivity.getAlertDialog().findViewById(
R.id.send_google_new_map);
}
private RadioButton getExistingMapRadioButton() {
return (RadioButton) uploadServiceChooserActivity.getDialog().findViewById(
return (RadioButton) uploadServiceChooserActivity.getAlertDialog().findViewById(
R.id.send_google_existing_map);
}
}
@@ -20,8 +20,6 @@ import com.google.android.apps.mytracks.Constants;
import android.os.Environment;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
@@ -31,76 +29,81 @@ import junit.framework.TestCase;
* @author Rodrigo Damazio
*/
public class FileUtilsTest extends TestCase {
private FileUtils fileUtils;
private Set<String> existingFiles;
@Override
protected void setUp() throws Exception {
super.setUp();
existingFiles = new HashSet<String>();
fileUtils = new FileUtils() {
@Override
protected boolean fileExists(File directory, String fullName) {
return existingFiles.contains(fullName);
}
};
}
/**
* Tests {@link FileUtils#buildExternalDirectoryPath(String...)}.
*/
public void testBuildExternalDirectoryPath() {
String expectedName = Environment.getExternalStorageDirectory()
+ File.separator
+ Constants.SDCARD_TOP_DIR
+ File.separator
+ "a"
+ File.separator
+ "b"
+ File.separator
String expectedName = Environment.getExternalStorageDirectory() + File.separator
+ Constants.SDCARD_TOP_DIR + File.separator + "a" + File.separator + "b" + File.separator
+ "c";
String dirName = fileUtils.buildExternalDirectoryPath("a", "b", "c");
String dirName = FileUtils.buildExternalDirectoryPath("a", "b", "c");
assertEquals(expectedName, dirName);
}
/**
* Tests sanitize filename.
* Tests {@link FileUtils#buildUniqueFileName(File, String, String)} when the
* file is new.
*/
public void testBuildUniqueFileName_new() {
String filename = FileUtils.buildUniqueFileName(new File("/dir"), "Filename", "ext");
assertEquals("Filename.ext", filename);
}
/**
* Tests {@link FileUtils#buildUniqueFileName(File, String, String)} when the
* file exists already.
*/
public void testBuildUniqueFileName_exist() {
// Expect "/default.prop" to exist on the phone/emulator
String filename = FileUtils.buildUniqueFileName(new File("/"), "default", "prop");
assertEquals("default(1).prop", filename);
}
/**
* Tests {@link FileUtils#sanitizeFileName(String)} with special characters.
* Verifies that they are sanitized.
*/
public void testSanitizeFileName() {
String name = "Swim\10ming-^across:/the/ pacific (ocean).";
String expected = "Swim_ming-^across_the_ pacific (ocean)_";
assertEquals(expected, fileUtils.sanitizeFileName(name));
assertEquals(expected, FileUtils.sanitizeFileName(name));
}
/**
* Tests characters in other languages, like Chinese and Russian, are allowed.
* Tests {@link FileUtils#sanitizeFileName(String)} with i18n characters (in
* Chinese and Russian). Verifies that they are allowed.
*/
public void testSanitizeFileName_i18n() {
String name = "您好-привет";
String expected = "您好-привет";
assertEquals(expected, fileUtils.sanitizeFileName(name));
assertEquals(expected, FileUtils.sanitizeFileName(name));
}
/**
* Tests special FAT32 characters are allowed.
* Tests {@link FileUtils#sanitizeFileName(String)} with special FAT32
* characters. Verifies that they are allowed.
*/
public void testSanitizeFileName_special_characters() {
String name = "$%'-_@~`!(){}^#&+,;=[] ";
String expected = "$%'-_@~`!(){}^#&+,;=[] ";
assertEquals(expected, fileUtils.sanitizeFileName(name));
assertEquals(expected, FileUtils.sanitizeFileName(name));
}
/**
* Testing collapsing multiple underscores characters.
* Tests {@link FileUtils#sanitizeFileName(String)} with multiple escaped
* characters in a row. Verifies that they are collapsed into one underscore.
*/
public void testSanitizeFileName_collapse() {
String name = "hello//there";
String expected = "hello_there";
assertEquals(expected, fileUtils.sanitizeFileName(name));
assertEquals(expected, FileUtils.sanitizeFileName(name));
}
/**
* Tests {@link FileUtils#truncateFileName(File, String, String)}. Verifies
* the a long file name is truncated.
*/
public void testTruncateFileName() {
File directory = new File("/dir1/dir2/");
String suffix = ".gpx";
@@ -109,36 +112,12 @@ public class FileUtilsTest extends TestCase {
name[i] = 'a';
}
String nameString = new String(name);
String truncated = fileUtils.truncateFileName(directory, nameString, suffix);
String truncated = FileUtils.truncateFileName(directory, nameString, suffix);
for (int i = 0; i < truncated.length(); i++) {
assertEquals('a', truncated.charAt(i));
}
assertEquals(FileUtils.MAX_FAT32_PATH_LENGTH,
new File(directory, truncated + suffix).getPath().length());
}
public void testBuildUniqueFileName_someExist() {
existingFiles = new HashSet<String>();
existingFiles.add("Filename.ext");
existingFiles.add("Filename(1).ext");
existingFiles.add("Filename(2).ext");
existingFiles.add("Filename(3).ext");
existingFiles.add("Filename(4).ext");
String filename = fileUtils.buildUniqueFileName(new File("/dir/"), "Filename", "ext");
assertEquals("Filename(5).ext", filename);
}
public void testBuildUniqueFileName_oneExists() {
existingFiles.add("Filename.ext");
String filename = fileUtils.buildUniqueFileName(new File("/dir/"), "Filename", "ext");
assertEquals("Filename(1).ext", filename);
}
public void testBuildUniqueFileName_noneExists() {
String filename = fileUtils.buildUniqueFileName(new File("/dir/"), "Filename", "ext");
assertEquals("Filename.ext", filename);
}
}