diff --git a/MyTracks/src/com/google/android/apps/mytracks/ChartSettingsDialog.java b/MyTracks/src/com/google/android/apps/mytracks/ChartSettingsDialog.java index 3621917ea..14b22a8b2 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ChartSettingsDialog.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ChartSettingsDialog.java @@ -17,6 +17,7 @@ package com.google.android.apps.mytracks; import com.google.android.apps.mytracks.ChartView.Mode; import com.google.android.maps.mytracks.R; +import com.google.common.annotations.VisibleForTesting; import android.app.Dialog; import android.content.Context; @@ -118,4 +119,9 @@ public class ChartSettingsDialog extends Dialog { public void setOnClickListener(OnClickListener clickListener) { this.clickListener = clickListener; } -} + + @VisibleForTesting + CheckBox[] getSeries() { + return series; + } +} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java index 33beb643b..a13a61922 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java @@ -9,6 +9,7 @@ import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask; import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.stats.DoubleBuffer; +import com.google.android.apps.mytracks.stats.TripStatisticsBuilder; import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.apps.mytracks.util.StringUtils; @@ -216,10 +217,10 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); Location lastLocation = null; - // Limit the number of elevation readings. Ideally we would want around - // 250. + // For chart server, limit the number of elevation readings to 250. int elevationSamplingFrequency = Math.max(1, (int) (locationsCount / 250.0)); - double totalDistance = 0; + TripStatisticsBuilder tripStatisticsBuilder = new TripStatisticsBuilder( + track.getStatistics().getStartTime()); DoubleBuffer elevationBuffer = new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR); Vector distances = new Vector(); Vector elevations = new Vector(); @@ -230,9 +231,7 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { Location location = myTracksProviderUtils.createLocation(locationsCursor); locations.add(location); - int readCount = i + 1; - - if (readCount == 1) { + if (i == 0) { // Create a start marker String name = context.getString(R.string.marker_label_start, track.getName()); if (!createNewPoint(name, "", location, MARKER_TYPE_START)) { @@ -243,19 +242,19 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { // Add to the distances and elevations vectors if (LocationUtils.isValidLocation(location)) { + tripStatisticsBuilder.addLocation(location, location.getTime()); // All points go into the smoothing buffer elevationBuffer.setNext(metricUnits ? location.getAltitude() : location.getAltitude() * UnitConversions.M_TO_FT); - if (lastLocation != null) { - totalDistance += (double) lastLocation.distanceTo(location); - } - if (readCount % elevationSamplingFrequency == 0) { - distances.add(totalDistance); + if (i % elevationSamplingFrequency == 0) { + distances.add(tripStatisticsBuilder.getStatistics().getTotalDistance()); elevations.add(elevationBuffer.getAverage()); } + lastLocation = location; } // Upload periodically + int readCount = i + 1; if (readCount % MAX_POINTS_PER_UPLOAD == 0) { if (!prepareAndUploadPoints(track, locations, false)) { Log.d(TAG, "Unable to upload points"); @@ -264,7 +263,6 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { updateProgress(readCount, locationsCount); locations.clear(); } - lastLocation = location; } // Do a final upload with the remaining locations @@ -275,6 +273,8 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { // Create an end marker if (lastLocation != null) { + distances.add(tripStatisticsBuilder.getStatistics().getTotalDistance()); + elevations.add(elevationBuffer.getAverage()); StringUtils stringUtils = new StringUtils(context); track.setDescription("

" + track.getDescription() + "

" + stringUtils.generateTrackDescription(track, distances, elevations) + "

"); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java index 07cea1f91..467b1cf62 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java @@ -27,6 +27,7 @@ import com.google.android.apps.mytracks.io.gdata.maps.XmlMapsGDataParserFactory; import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask; import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.stats.DoubleBuffer; +import com.google.android.apps.mytracks.stats.TripStatisticsBuilder; import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.UnitConversions; @@ -253,9 +254,10 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); Location lastLocation = null; - // Limit the number of elevation readings to 250. + // For chart server, limit the number of elevation readings to 250. int elevationSamplingFrequency = Math.max(1, (int) (locationsCount / 250.0)); - double totalDistance = 0; + TripStatisticsBuilder tripStatisticsBuilder = new TripStatisticsBuilder( + track.getStatistics().getStartTime()); DoubleBuffer elevationBuffer = new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR); Vector distances = new Vector(); Vector elevations = new Vector(); @@ -266,9 +268,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { Location location = myTracksProviderUtils.createLocation(locationsCursor); locations.add(location); - int readCount = i + 1; - - if (readCount == 1) { + if (i == 0) { // Create a start marker if (!uploadMarker(context.getString(R.string.marker_label_start, track.getName()), "", START_ICON_URL, location)) { @@ -279,19 +279,19 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { // Add to the distances and elevations vectors if (LocationUtils.isValidLocation(location)) { + tripStatisticsBuilder.addLocation(location, location.getTime()); // All points go into the smoothing buffer elevationBuffer.setNext(metricUnits ? location.getAltitude() : location.getAltitude() * UnitConversions.M_TO_FT); - if (lastLocation != null) { - totalDistance += (double) lastLocation.distanceTo(location); - } - if (readCount % elevationSamplingFrequency == 0) { - distances.add(totalDistance); + if (i % elevationSamplingFrequency == 0) { + distances.add(tripStatisticsBuilder.getStatistics().getTotalDistance()); elevations.add(elevationBuffer.getAverage()); } + lastLocation = location; } // Upload periodically + int readCount = i + 1; if (readCount % MAX_POINTS_PER_UPLOAD == 0) { if (!prepareAndUploadPoints(track, locations, false)) { Log.d(TAG, "Unable to upload points"); @@ -300,7 +300,6 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { updateProgress(readCount, locationsCount); locations.clear(); } - lastLocation = location; } // Do a final upload with the remaining locations @@ -311,6 +310,8 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { // Create an end marker if (lastLocation != null) { + distances.add(tripStatisticsBuilder.getStatistics().getTotalDistance()); + elevations.add(elevationBuffer.getAverage()); StringUtils stringUtils = new StringUtils(context); track.setDescription("

" + track.getDescription() + "

" + stringUtils.generateTrackDescription(track, distances, elevations) + "

"); diff --git a/MyTracks/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptor.java b/MyTracks/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptor.java index c480f345e..003b52473 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptor.java +++ b/MyTracks/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptor.java @@ -22,34 +22,36 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.maps.mytracks.R; +import com.google.common.annotations.VisibleForTesting; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.util.Log; - /** * A dynamic speed path descriptor. - * + * * @author Vangelis S. */ -public class DynamicSpeedTrackPathDescriptor - implements TrackPathDescriptor, OnSharedPreferenceChangeListener { - +public class DynamicSpeedTrackPathDescriptor implements TrackPathDescriptor, + OnSharedPreferenceChangeListener { + private int slowSpeed; private int normalSpeed; private int speedMargin; private final int speedMarginDefault; private double averageMovingSpeed; private final Context context; - - public DynamicSpeedTrackPathDescriptor(Context context){ + @VisibleForTesting + static final int CRITICAL_DIFFERENCE_PERCENTAGE = 20; + + public DynamicSpeedTrackPathDescriptor(Context context) { this.context = context; - speedMarginDefault = Integer.parseInt( - context.getString(R.string.color_mode_dynamic_percentage_default)); - SharedPreferences prefs = context.getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + speedMarginDefault = Integer.parseInt(context + .getString(R.string.color_mode_dynamic_percentage_default)); + SharedPreferences prefs = context.getSharedPreferences(Constants.SETTINGS_NAME, + Context.MODE_PRIVATE); if (prefs == null) { speedMargin = speedMarginDefault; @@ -60,7 +62,8 @@ public class DynamicSpeedTrackPathDescriptor speedMargin = getSpeedMargin(prefs); } - private int getSpeedMargin(SharedPreferences sharedPreferences) { + @VisibleForTesting + int getSpeedMargin(SharedPreferences sharedPreferences) { try { return Integer.parseInt(sharedPreferences.getString( context.getString(R.string.track_color_mode_dynamic_speed_variation_key), @@ -72,34 +75,32 @@ public class DynamicSpeedTrackPathDescriptor /** * Get the slow speed calculated based on the % below the average speed. + * * @return The speed limit considered as slow. */ - public int getSlowSpeed() - { - slowSpeed = (int) (averageMovingSpeed - (averageMovingSpeed * speedMargin / 100)); + public int getSlowSpeed() { + slowSpeed = (int) (averageMovingSpeed - (averageMovingSpeed * speedMargin / 100)); return slowSpeed; } - + /** - * Get the medium speed calculated based on the % above the average speed. + * Gets the medium speed calculated based on the % above the average speed. + * * @return The speed limit considered as normal. */ - public int getNormalSpeed() - { - normalSpeed = (int) (averageMovingSpeed + (averageMovingSpeed * speedMargin / 100)); + public int getNormalSpeed() { + normalSpeed = (int) (averageMovingSpeed + (averageMovingSpeed * speedMargin / 100)); return normalSpeed; } - + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Log.d(TAG, "DynamicSpeedTrackPathDescriptor: onSharedPreferences changed " + key); - if (key == null - || !key.equals(context.getString(R.string.track_color_mode_dynamic_speed_variation_key))) { - return; - } - SharedPreferences prefs = context.getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - + if (key == null + || !key.equals(context.getString(R.string.track_color_mode_dynamic_speed_variation_key))) { return; } + SharedPreferences prefs = context.getSharedPreferences(Constants.SETTINGS_NAME, + Context.MODE_PRIVATE); + if (prefs == null) { speedMargin = speedMarginDefault; return; @@ -110,33 +111,69 @@ public class DynamicSpeedTrackPathDescriptor @Override public boolean needsRedraw() { - SharedPreferences prefs = context.getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(Constants.SETTINGS_NAME, + Context.MODE_PRIVATE); long currentTrackId = prefs.getLong(context.getString(R.string.selected_track_key), -1); - if(currentTrackId == -1) { - // Could not find track. - return false; + if (currentTrackId == -1) { + // Could not find track. + return false; } Track track = MyTracksProviderUtils.Factory.get(context).getTrack(currentTrackId); TripStatistics stats = track.getStatistics(); - double newaverageSpeed = (int) Math.floor(stats.getAverageMovingSpeed() * 3.6); - - if(averageMovingSpeed == 0) { - averageMovingSpeed = newaverageSpeed; - return true; - } - - double difference = Math.max(averageMovingSpeed, newaverageSpeed); + double newAverageMovingSpeed = (int) Math.floor(stats.getAverageMovingSpeed() * 3.6); - if (difference == 0.0) { - difference = 0.0; - } else { - difference = Math.abs(averageMovingSpeed - newaverageSpeed) / difference * 100; + return isDifferenceSignificant(averageMovingSpeed, newAverageMovingSpeed); + } + + /** + * Checks whether the old speed and the new speed differ significantly or not. + */ + public boolean isDifferenceSignificant(double oldAverageMovingSpeed, double newAverageMovingSpeed) { + if (oldAverageMovingSpeed == 0) { + if (newAverageMovingSpeed == 0) { + return false; + } else { + averageMovingSpeed = newAverageMovingSpeed; + return true; + } } - if(difference >= 20) { - averageMovingSpeed = newaverageSpeed; + + // Here, both oldAverageMovingSpeed and newAverageMovingSpeed are not zero. + double maxValue = Math.max(oldAverageMovingSpeed, newAverageMovingSpeed); + double differencePercentage = Math.abs(oldAverageMovingSpeed - newAverageMovingSpeed) + / maxValue * 100; + if (differencePercentage >= CRITICAL_DIFFERENCE_PERCENTAGE) { + averageMovingSpeed = newAverageMovingSpeed; return true; } return false; } + + /** + * Gets the value of variable speedMargin to check the result of test. + * @return the value of speedMargin. + */ + @VisibleForTesting + int getSpeedMargin() { + return speedMargin; + } + + /** + * Sets the value of newAverageMovingSpeed to test the method isDifferenceSignificant. + * @param newAverageMovingSpeed the value to set. + */ + @VisibleForTesting + void setAverageMovingSpeed(double newAverageMovingSpeed) { + averageMovingSpeed = newAverageMovingSpeed; + } + + /** + * Gets the value of averageMovingSpeed to check the result of test. + * + * @return the value of averageMovingSpeed + */ + @VisibleForTesting + double getAverageMovingSpeed() { + return averageMovingSpeed; + } } \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java index aca62f947..5e8e6ea8d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java @@ -97,8 +97,9 @@ public abstract class AntSensorManager extends SensorManager { if (DEBUGGING) { Log.d(TAG, "Received RX message " + messageToString(antMessage)); } - - handleMessage(antMessage); + if (getAntReceiver() != null) { + handleMessage(antMessage); + } } } }; diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java index d2e1e95aa..b83f4ef66 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java @@ -47,7 +47,7 @@ public class AntPreferenceTest extends AndroidTestCase { } }; assertEquals( - String.format(getContext().getString(R.string.settings_sensor_ant_paired), persistInt), + getContext().getString(R.string.settings_sensor_ant_paired, persistInt), antPreference.getSummary()); } -} +} \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/BootReceiverTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/BootReceiverTest.java new file mode 100644 index 000000000..9c70a7af6 --- /dev/null +++ b/MyTracksTest/src/com/google/android/apps/mytracks/BootReceiverTest.java @@ -0,0 +1,91 @@ +/* + * 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.services.TrackRecordingService; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.test.AndroidTestCase; + +import java.util.List; + +/** + * Tests for the BootReceiver. + * + * @author Youtao Liu + */ +public class BootReceiverTest extends AndroidTestCase { + private static final String SERVICE_NAME = "com.google.android.apps.mytracks.services.TrackRecordingService"; + + /** + * Tests the behavior when receive notification which is the phone boot. + */ + public void testOnReceive_startService() { + // Make sure no TrackRecordingService + Intent stopIntent = new Intent(getContext(), TrackRecordingService.class); + getContext().stopService(stopIntent); + assertFalse(isServiceExisted(getContext(), SERVICE_NAME)); + + BootReceiver bootReceiver = new BootReceiver(); + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_BOOT_COMPLETED); + bootReceiver.onReceive(getContext(), intent); + // Check if the service is started + assertTrue(isServiceExisted(getContext(), SERVICE_NAME)); + } + + /** + * Tests the behavior when receive notification which is not the phone boot. + */ + public void testOnReceive_noStartService() { + // Make sure no TrackRecordingService + Intent stopIntent = new Intent(getContext(), TrackRecordingService.class); + getContext().stopService(stopIntent); + assertFalse(isServiceExisted(getContext(), SERVICE_NAME)); + + BootReceiver bootReceiver = new BootReceiver(); + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_BUG_REPORT); + bootReceiver.onReceive(getContext(), intent); + // Check if the service is not started + assertFalse(isServiceExisted(getContext(), SERVICE_NAME)); + } + + /** + * Checks if a service is started in a context. + * + * @param context the context for checking a service + * @param serviceName the service name to find if existed + */ + private boolean isServiceExisted(Context context, String serviceName) { + ActivityManager activityManager = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + List serviceList = activityManager + .getRunningServices(Integer.MAX_VALUE); + for (int i = 0; i < serviceList.size(); i++) { + RunningServiceInfo serviceInfo = serviceList.get(i); + ComponentName componentName = serviceInfo.service; + if (componentName.getClassName().equals(serviceName)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/ChartSettingsDialogTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/ChartSettingsDialogTest.java new file mode 100644 index 000000000..fbe277c53 --- /dev/null +++ b/MyTracksTest/src/com/google/android/apps/mytracks/ChartSettingsDialogTest.java @@ -0,0 +1,82 @@ +/* + * 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 { + + 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)); + } + } +} \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptorTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptorTest.java new file mode 100644 index 000000000..ccbd0678a --- /dev/null +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/DynamicSpeedTrackPathDescriptorTest.java @@ -0,0 +1,176 @@ +/* + * 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.maps; + +import com.google.android.apps.mytracks.Constants; +import com.google.android.maps.mytracks.R; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.test.AndroidTestCase; + +/** + * Tests for the {@link DynamicSpeedTrackPathDescriptor}. + * + * @author Youtao Liu + */ +public class DynamicSpeedTrackPathDescriptorTest extends AndroidTestCase { + + private Context context; + private SharedPreferences sharedPreferences; + private Editor sharedPreferencesEditor; + + @Override + protected void setUp() throws Exception { + super.setUp(); + context = getContext(); + sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + sharedPreferencesEditor = sharedPreferences.edit(); + } + + /** + * Tests the method {@link DynamicSpeedTrackPathDescriptor#getSpeedMargin()} + * with zero, normal and illegal value. + */ + public void testGetSpeedMargin() { + String[] actuals = { "0", "50", "99", "" }; + // The default value of speedMargin is 25. + int[] expectations = { 0, 50, 99, 25 }; + // Test + for (int i = 0; i < expectations.length; i++) { + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_dynamic_speed_variation_key), actuals[i]); + sharedPreferencesEditor.commit(); + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + assertEquals(expectations[i], + dynamicSpeedTrackPathDescriptor.getSpeedMargin(sharedPreferences)); + } + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#OnSharedPreferenceChanged()} + * when the key is null. + */ + public void testOnSharedPreferenceChanged_nullKey() { + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin(sharedPreferences); + // Change value in shared preferences. + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_dynamic_speed_variation_key), + Integer.toString(speedMargin + 2)); + sharedPreferencesEditor.commit(); + + dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, null); + assertEquals(speedMargin, dynamicSpeedTrackPathDescriptor.getSpeedMargin()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#OnSharedPreferenceChanged()} + * when the key is not null, and not trackColorModeDynamicVariation. + */ + public void testOnSharedPreferenceChanged_otherKey() { + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin(sharedPreferences); + // Change value in shared preferences. + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_dynamic_speed_variation_key), + Integer.toString(speedMargin + 2)); + sharedPreferencesEditor.commit(); + + dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, "anyKey"); + assertEquals(speedMargin, dynamicSpeedTrackPathDescriptor.getSpeedMargin()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#OnSharedPreferenceChanged()} + * when the key is trackColorModeDynamicVariation. + */ + public void testOnSharedPreferenceChanged_trackColorModeDynamicVariationKey() { + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin(sharedPreferences); + // Change value in shared preferences. + sharedPreferencesEditor.putString( + "trackColorModeDynamicVariation", + Integer.toString(speedMargin + 2)); + sharedPreferencesEditor.commit(); + + dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, + "trackColorModeDynamicVariation"); + assertEquals(speedMargin + 2, dynamicSpeedTrackPathDescriptor.getSpeedMargin()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#OnSharedPreferenceChanged()} + * when the values of speedMargin is "". + */ + public void testOnSharedPreferenceChanged_emptyValue() { + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + // Change value in shared preferences + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_dynamic_speed_variation_key), ""); + sharedPreferencesEditor.commit(); + + dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, + context.getString(R.string.track_color_mode_dynamic_speed_variation_key)); + // The default value of speedMargin is 25. + assertEquals(25, dynamicSpeedTrackPathDescriptor.getSpeedMargin()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#NeedsRedraw()} by wrong track + * id. + */ + public void testNeedsRedraw_WrongTrackId() { + long trackId = -1; + sharedPreferencesEditor.putLong(context.getString(R.string.selected_track_key), trackId); + sharedPreferencesEditor.commit(); + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + assertEquals(false, dynamicSpeedTrackPathDescriptor.needsRedraw()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#NeedsRedraw()} by different + * averageMovingSpeed. + */ + public void testIsDiffereceSignificant() { + DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor( + context); + double[] averageMovingSpeeds = { 0, 30, 30, 30 }; + double[] newAverageMovingSpeed = { 20, 30, + // Difference is less than CRITICAL_DIFFERENCE_PERCENTAGE + 30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100) / 2), + // Difference is more than CRITICAL_DIFFERENCE_PERCENTAGE + 30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100.00) * 2) }; + boolean[] expectedValues = { true, false, false, true }; + double[] expectedAverageMovingSpeed = { 20, 30, 30, + 30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100.00) * 2) }; + // Test + for (int i = 0; i < newAverageMovingSpeed.length; i++) { + dynamicSpeedTrackPathDescriptor.setAverageMovingSpeed(averageMovingSpeeds[i]); + assertEquals(expectedValues[i], dynamicSpeedTrackPathDescriptor.isDifferenceSignificant( + averageMovingSpeeds[i], newAverageMovingSpeed[i])); + assertEquals(expectedAverageMovingSpeed[i], + dynamicSpeedTrackPathDescriptor.getAverageMovingSpeed()); + } + } +} \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/maps/FixedSpeedTrackPathDescriptorTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/maps/FixedSpeedTrackPathDescriptorTest.java new file mode 100644 index 000000000..7efc542fd --- /dev/null +++ b/MyTracksTest/src/com/google/android/apps/mytracks/maps/FixedSpeedTrackPathDescriptorTest.java @@ -0,0 +1,183 @@ +/* + * 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.maps; + +import com.google.android.apps.mytracks.Constants; +import com.google.android.maps.mytracks.R; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.test.AndroidTestCase; + +/** + * Tests for the {@link DynamicSpeedTrackPathDescriptor}. + * + * @author Youtao Liu + */ +public class FixedSpeedTrackPathDescriptorTest extends AndroidTestCase { + private Context context; + private SharedPreferences sharedPreferences; + private Editor sharedPreferencesEditor; + private int slowDefault; + private int normalDefault; + + @Override + protected void setUp() throws Exception { + super.setUp(); + context = getContext(); + sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + sharedPreferencesEditor = sharedPreferences.edit(); + // Get the default value + slowDefault = 9; + normalDefault = 15; + } + + /** + * Tests the initialization of slowSpeed and normalSpeed in + * {@link DynamicSpeedTrackPathDescriptor#DynamicSpeedTrackPathDescriptor(Context)} + * . + */ + public void testConstructor() { + String[] slowSpeedsInShPre = { "0", "1", "99", "" }; + int[] slowSpeedExpectations = { 0, 1, 99, slowDefault }; + String[] normalSpeedsInShPre = { "0", "1", "99", "" }; + int[] normalSpeedExpectations = { 0, 1, 99, normalDefault }; + for (int i = 0; i < slowSpeedsInShPre.length; i++) { + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), slowSpeedsInShPre[i]); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), + normalSpeedsInShPre[i]); + sharedPreferencesEditor.commit(); + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + assertEquals(slowSpeedExpectations[i], fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalSpeedExpectations[i], fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged()} + * when the key is null. + */ + public void testOnSharedPreferenceChanged_null_key() { + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed(); + int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed(); + // Change value in shared preferences + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), + Integer.toString(slowSpeed + 2)); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), + Integer.toString(normalSpeed + 2)); + sharedPreferencesEditor.commit(); + + fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, null); + assertEquals(slowSpeed, fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalSpeed, fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged()} + * when the key is not null, and not slowSpeed and not normalSpeed. + */ + public void testOnSharedPreferenceChanged_other_key() { + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed(); + int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed(); + // Change value in shared preferences + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), + Integer.toString(slowSpeed + 2)); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), + Integer.toString(normalSpeed + 2)); + sharedPreferencesEditor.commit(); + fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, "anyKey"); + assertEquals(slowSpeed, fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalSpeed, fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged()} + * when the key is slowSpeed. + */ + public void testOnSharedPreferenceChanged_slowSpeedKey() { + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed(); + int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed(); + // Change value in shared preferences + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), + Integer.toString(slowSpeed + 2)); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), + Integer.toString(normalSpeed + 2)); + sharedPreferencesEditor.commit(); + fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, + context.getString(R.string.track_color_mode_fixed_speed_slow_key)); + assertEquals(slowSpeed + 2, fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalSpeed + 2, fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged()} + * when the key is normalSpeed. + */ + public void testOnSharedPreferenceChanged_normalSpeedKey() { + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed(); + int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed(); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), + Integer.toString(slowSpeed + 4)); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), + Integer.toString(normalSpeed + 4)); + sharedPreferencesEditor.commit(); + + fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, + context.getString(R.string.track_color_mode_fixed_speed_medium_key)); + assertEquals(slowSpeed + 4, fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalSpeed + 4, fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } + + /** + * Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged()} + * when the values of slowSpeed and normalSpeed in SharedPreference is "". In + * such situation, the default value should get returned. + */ + public void testOnSharedPreferenceChanged_emptyValue() { + FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor( + context); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_slow_key), ""); + sharedPreferencesEditor.putString( + context.getString(R.string.track_color_mode_fixed_speed_medium_key), ""); + sharedPreferencesEditor.commit(); + + fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, + context.getString(R.string.track_color_mode_fixed_speed_medium_key)); + assertEquals(slowDefault, fixedSpeedTrackPathDescriptor.getSlowSpeed()); + assertEquals(normalDefault, fixedSpeedTrackPathDescriptor.getNormalSpeed()); + } +} \ No newline at end of file