Fix comments on 4d928853455e

This commit is contained in:
Jimmy Shih
2012-02-22 16:19:10 -08:00
parent 719b7c2414
commit 8fc43ff3fb
3 changed files with 304 additions and 66 deletions
@@ -21,6 +21,7 @@ import com.google.android.apps.mytracks.util.ChartURLGenerator;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions; import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
import android.content.Context; import android.content.Context;
import android.util.Pair; import android.util.Pair;
@@ -46,29 +47,30 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
@Override @Override
public String generateTrackDescription( public String generateTrackDescription(
Track track, Vector<Double> distances, Vector<Double> elevations) { Track track, Vector<Double> distances, Vector<Double> elevations) {
StringBuffer buffer = new StringBuffer(); StringBuilder builder = new StringBuilder();
// Created by // Created by
String url = context.getString(R.string.my_tracks_web_url); String url = context.getString(R.string.my_tracks_web_url);
buffer.append(context.getString( builder.append(context.getString(
R.string.send_google_by_my_tracks, "<a href='http://" + url + "'>", "</a>")); R.string.send_google_by_my_tracks, "<a href='http://" + url + "'>", "</a>"));
buffer.append("<p>"); builder.append("<p>");
buffer.append(generateTripStatisticsDescription(track.getStatistics(), true)); builder.append(generateTripStatisticsDescription(track.getStatistics(), true));
// Activity type // Activity type
String trackCategory = track.getCategory(); String trackCategory = track.getCategory();
String category = trackCategory != null && trackCategory.length() > 0 ? trackCategory String category = trackCategory != null && trackCategory.length() > 0 ? trackCategory
: context.getString(R.string.value_unknown); : context.getString(R.string.value_unknown);
buffer.append(context.getString(R.string.description_activity_type, category)); builder.append(context.getString(R.string.description_activity_type, category));
buffer.append(HTML_LINE_BREAK); builder.append(HTML_LINE_BREAK);
// Elevation chart // Elevation chart
if (distances != null && elevations != null) { if (distances != null && elevations != null) {
buffer.append("<img border=\"0\" src=\"" builder.append("<img border=\"0\" src=\""
+ ChartURLGenerator.getChartUrl(distances, elevations, track, context) + "\"/>"); + ChartURLGenerator.getChartUrl(distances, elevations, track, context) + "\"/>");
builder.append(HTML_LINE_BREAK);
} }
return buffer.toString(); return builder.toString();
} }
@Override @Override
@@ -80,117 +82,115 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
* Generates a description for a {@link TripStatistics}. * Generates a description for a {@link TripStatistics}.
* *
* @param stats the trip statistics * @param stats the trip statistics
* @param html true to use <br> for line break instead of \n * @param html true to use "<br>" for line break instead of "\n"
*/ */
private String generateTripStatisticsDescription(TripStatistics stats, boolean html) { private String generateTripStatisticsDescription(TripStatistics stats, boolean html) {
String lineBreak = html ? HTML_LINE_BREAK : TEXT_LINE_BREAK; String lineBreak = html ? HTML_LINE_BREAK : TEXT_LINE_BREAK;
StringBuffer buffer = new StringBuffer(); StringBuilder builder = new StringBuilder();
// Total distance // Total distance
writeDistance(stats.getTotalDistance(), buffer, R.string.description_total_distance); writeDistance(
buffer.append(lineBreak); stats.getTotalDistance(), builder, R.string.description_total_distance, lineBreak);
// Total time // Total time
writeTime(stats.getTotalTime(), buffer, R.string.description_total_time); writeTime(stats.getTotalTime(), builder, R.string.description_total_time, lineBreak);
buffer.append(lineBreak);
// Moving time // Moving time
writeTime(stats.getMovingTime(), buffer, R.string.description_moving_time); writeTime(stats.getMovingTime(), builder, R.string.description_moving_time, lineBreak);
buffer.append(lineBreak);
// Average speed // Average speed
Pair<Double, Double> averageSpeed = writeSpeed( Pair<Double, Double> averageSpeed = writeSpeed(
stats.getAverageSpeed(), buffer, R.string.description_average_speed); stats.getAverageSpeed(), builder, R.string.description_average_speed, lineBreak);
buffer.append(lineBreak);
// Average moving speed // Average moving speed
Pair<Double, Double> averageMovingSpeed = writeSpeed( Pair<Double, Double> averageMovingSpeed = writeSpeed(stats.getAverageMovingSpeed(), builder,
stats.getAverageMovingSpeed(), buffer, R.string.description_average_moving_speed); R.string.description_average_moving_speed, lineBreak);
buffer.append(lineBreak);
// Max speed // Max speed
Pair<Double, Double> maxSpeed = writeSpeed( Pair<Double, Double> maxSpeed = writeSpeed(
stats.getMaxSpeed(), buffer, R.string.description_max_speed); stats.getMaxSpeed(), builder, R.string.description_max_speed, lineBreak);
buffer.append(lineBreak);
// Average pace // Average pace
writePace(averageSpeed, buffer, R.string.description_average_pace); writePace(averageSpeed, builder, R.string.description_average_pace, lineBreak);
buffer.append(lineBreak);
// Average moving pace // Average moving pace
writePace(averageMovingSpeed, buffer, R.string.description_average_moving_pace); writePace(averageMovingSpeed, builder, R.string.description_average_moving_pace, lineBreak);
buffer.append(lineBreak);
// Min pace // Min pace
writePace(maxSpeed, buffer, R.string.description_min_pace); writePace(maxSpeed, builder, R.string.description_min_pace, lineBreak);
buffer.append(lineBreak);
// Max elevation // Max elevation
writeElevation(stats.getMaxElevation(), buffer, R.string.description_max_elevation); writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak);
buffer.append(lineBreak);
// Min elevation // Min elevation
writeElevation(stats.getMinElevation(), buffer, R.string.description_min_elevation); writeElevation(stats.getMinElevation(), builder, R.string.description_min_elevation, lineBreak);
buffer.append(lineBreak);
// Elevation gain // Elevation gain
writeElevation(stats.getTotalElevationGain(), buffer, R.string.description_elevation_gain); writeElevation(
buffer.append(lineBreak); stats.getTotalElevationGain(), builder, R.string.description_elevation_gain, lineBreak);
// Max grade // Max grade
writeGrade(stats.getMaxGrade(), buffer, R.string.description_max_grade); writeGrade(stats.getMaxGrade(), builder, R.string.description_max_grade, lineBreak);
buffer.append(lineBreak);
// Min grade // Min grade
writeGrade(stats.getMinGrade(), buffer, R.string.description_min_grade); writeGrade(stats.getMinGrade(), builder, R.string.description_min_grade, lineBreak);
buffer.append(lineBreak);
// Recorded time // Recorded time
buffer.append( builder.append(
context.getString(R.string.description_recorded_time, context.getString(R.string.description_recorded_time,
StringUtils.formatDateTime(context, stats.getStartTime()))); StringUtils.formatDateTime(context, stats.getStartTime())));
buffer.append(lineBreak); builder.append(lineBreak);
return buffer.toString(); return builder.toString();
} }
/** /**
* Writes distance. * Writes distance.
* *
* @param distance distance in meters * @param distance distance in meters
* @param buffer buffer to write distance * @param builder StringBuilder to append distance
* @param resId resource id of distance string * @param resId resource id of distance string
* @param lineBreak line break string
*/ */
private void writeDistance(double distance, StringBuffer buffer, int resId) { @VisibleForTesting
void writeDistance(double distance, StringBuilder builder, int resId, String lineBreak) {
double distanceInKm = distance * UnitConversions.M_TO_KM; double distanceInKm = distance * UnitConversions.M_TO_KM;
double distanceInMi = distanceInKm * UnitConversions.KM_TO_MI; double distanceInMi = distanceInKm * UnitConversions.KM_TO_MI;
buffer.append(context.getString(resId, distanceInKm, distanceInMi)); builder.append(context.getString(resId, distanceInKm, distanceInMi));
builder.append(lineBreak);
} }
/** /**
* Writes time. * Writes time.
* *
* @param time time in milliseconds. * @param time time in milliseconds.
* @param buffer buffer to write time * @param builder StringBuilder to append time
* @param resId resource id of time string * @param resId resource id of time string
* @param lineBreak line break string
*/ */
private void writeTime(long time, StringBuffer buffer, int resId) { @VisibleForTesting
buffer.append(context.getString(resId, StringUtils.formatElapsedTime(time))); void writeTime(long time, StringBuilder builder, int resId, String lineBreak) {
builder.append(context.getString(resId, StringUtils.formatElapsedTime(time)));
builder.append(lineBreak);
} }
/** /**
* Writes speed. * Writes speed.
* *
* @param speed speed in meters per second * @param speed speed in meters per second
* @param buffer buffer to write speed * @param builder StringBuilder to append speed
* @param resId resource id of speed string * @param resId resource id of speed string
*@return a pair of speed, first in kilometers per hour, second in miles per * @param lineBreak line break string
* @return a pair of speed, first in kilometers per hour, second in miles per
* hour. * hour.
*/ */
private Pair<Double, Double> writeSpeed(double speed, StringBuffer buffer, int resId) { @VisibleForTesting
Pair<Double, Double> writeSpeed(
double speed, StringBuilder builder, int resId, String lineBreak) {
double speedInKmHr = speed * UnitConversions.MS_TO_KMH; double speedInKmHr = speed * UnitConversions.MS_TO_KMH;
double speedInMiHr = speedInKmHr * UnitConversions.KM_TO_MI; double speedInMiHr = speedInKmHr * UnitConversions.KM_TO_MI;
buffer.append(context.getString(resId, speedInKmHr, speedInMiHr)); builder.append(context.getString(resId, speedInKmHr, speedInMiHr));
builder.append(lineBreak);
return Pair.create(speedInKmHr, speedInMiHr); return Pair.create(speedInKmHr, speedInMiHr);
} }
@@ -199,39 +199,50 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
* *
* @param speed a pair of speed, first in kilometers per hour, second in miles * @param speed a pair of speed, first in kilometers per hour, second in miles
* per hour * per hour
* @param buffer buffer to write pace * @param builder StringBuilder to append pace
* @param resId resource id of pace string * @param resId resource id of pace string
* @param lineBreak line break string
*/ */
private void writePace(Pair<Double, Double> speed, StringBuffer buffer, int resId) { @VisibleForTesting
void writePace(
Pair<Double, Double> speed, StringBuilder builder, int resId, String lineBreak) {
double paceInMinKm = getPace(speed.first); double paceInMinKm = getPace(speed.first);
double paceInMinMi = getPace(speed.second); double paceInMinMi = getPace(speed.second);
buffer.append(context.getString(resId, paceInMinKm, paceInMinMi)); builder.append(context.getString(resId, paceInMinKm, paceInMinMi));
builder.append(lineBreak);
} }
/** /**
* Writes elevation. * Writes elevation.
* *
* @param elevation elevation in meters * @param elevation elevation in meters
* @param buffer buffer to write elevation * @param builder StringBuilder to append elevation
* @param resId resource id of elevation string * @param resId resource id of elevation string
* @param lineBreak line break string
*/ */
private void writeElevation(double elevation, StringBuffer buffer, int resId) { @VisibleForTesting
void writeElevation(
double elevation, StringBuilder builder, int resId, String lineBreak) {
long elevationInM = Math.round(elevation); long elevationInM = Math.round(elevation);
long elevationInFt = Math.round(elevation * UnitConversions.M_TO_FT); long elevationInFt = Math.round(elevation * UnitConversions.M_TO_FT);
buffer.append(context.getString(resId, elevationInM, elevationInFt)); builder.append(context.getString(resId, elevationInM, elevationInFt));
builder.append(lineBreak);
} }
/** /**
* Writes grade. * Writes grade.
* *
* @param grade grade in fraction * @param grade grade in fraction
* @param buffer buffer to write grade * @param builder StringBuilder to append grade
* @param resId resource id grade string * @param resId resource id grade string
* @param lineBreak line break string
*/ */
private void writeGrade(double grade, StringBuffer buffer, int resId) { @VisibleForTesting
long gradeInPercent = Double.isNaN(grade) || Double.isInfinite(grade) void writeGrade(double grade, StringBuilder builder, int resId, String lineBreak) {
? 0L : Math.round(grade * 100); long gradeInPercent = Double.isNaN(grade) || Double.isInfinite(grade) ? 0L
buffer.append(context.getString(resId, gradeInPercent)); : Math.round(grade * 100);
builder.append(context.getString(resId, gradeInPercent));
builder.append(lineBreak);
} }
/** /**
@@ -239,7 +250,8 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
* *
* @param speed speed in hours * @param speed speed in hours
*/ */
private double getPace(double speed) { @VisibleForTesting
double getPace(double speed) {
return speed == 0 ? 0.0 : 60.0 / speed; // convert from hours to minutes return speed == 0 ? 0.0 : 60.0 / speed; // convert from hours to minutes
} }
} }
@@ -0,0 +1,213 @@
/*
* 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.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;
import android.util.Pair;
/**
* Tests for {@link DescriptionGeneratorImpl}.
*
* @author Jimmy Shih
*/
public class DescriptionGeneratorImplTest extends AndroidTestCase {
private DescriptionGeneratorImpl descriptionGenerator;
@Override
protected void setUp() throws Exception {
descriptionGenerator = new DescriptionGeneratorImpl(getContext());
}
/**
* Tests {@link DescriptionGeneratorImpl#generateTrackDescription(Track,
* java.util.Vector, java.util.Vector)}.
*/
public void testGenerateTrackDescription() {
Track track = new Track();
TripStatistics stats = new TripStatistics();
stats.setTotalDistance(20000);
stats.setTotalTime(600000);
stats.setMovingTime(300000);
stats.setMaxSpeed(100);
stats.setMaxElevation(550);
stats.setMinElevation(-500);
stats.setTotalElevationGain(6000);
stats.setMaxGrade(0.42);
stats.setMinGrade(0.11);
stats.setStartTime(1288721514000L);
track.setStatistics(stats);
track.setCategory("hiking");
String expected = "Created by"
+ " <a href='http://www.google.com/mobile/mytracks'>My Tracks</a> on Android.<p>"
+ "Total distance: 20.00 km (12.4 mi)<br>"
+ "Total time: 10:00<br>"
+ "Moving time: 05:00<br>"
+ "Average speed: 120.00 km/h (74.6 mi/h)<br>"
+ "Average moving speed: 240.00 km/h (149.1 mi/h)<br>"
+ "Max speed: 360.00 km/h (223.7 mi/h)<br>"
+ "Average pace: 0.50 min/km (0.8 min/mi)<br>"
+ "Average moving pace: 0.25 min/km (0.4 min/mi)<br>"
+ "Min pace: 0.17 min/km (0.3 min/mi)<br>"
+ "Max elevation: 550 m (1804 ft)<br>"
+ "Min elevation: -500 m (-1640 ft)<br>"
+ "Elevation gain: 6000 m (19685 ft)<br>"
+ "Max grade: 42 %<br>"
+ "Min grade: 11 %<br>"
+ "Recorded: 11/2/2010 11:11 AM<br>"
+ "Activity type: hiking<br>";
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, null, null));
}
/**
* Tests {@link DescriptionGeneratorImpl#generateWaypointDescription(Waypoint)}.
*/
public void testGenerateWaypointDescription() {
Waypoint waypoint = new Waypoint();
TripStatistics stats = new TripStatistics();
stats.setTotalDistance(20000);
stats.setTotalTime(600000);
stats.setMovingTime(300000);
stats.setMaxSpeed(100);
stats.setMaxElevation(550);
stats.setMinElevation(-500);
stats.setTotalElevationGain(6000);
stats.setMaxGrade(0.42);
stats.setMinGrade(0.11);
stats.setStartTime(1288721514000L);
waypoint.setStatistics(stats);
String expected = "Total distance: 20.00 km (12.4 mi)\n"
+ "Total time: 10:00\n"
+ "Moving time: 05:00\n"
+ "Average speed: 120.00 km/h (74.6 mi/h)\n"
+ "Average moving speed: 240.00 km/h (149.1 mi/h)\n"
+ "Max speed: 360.00 km/h (223.7 mi/h)\n"
+ "Average pace: 0.50 min/km (0.8 min/mi)\n"
+ "Average moving pace: 0.25 min/km (0.4 min/mi)\n"
+ "Min pace: 0.17 min/km (0.3 min/mi)\n"
+ "Max elevation: 550 m (1804 ft)\n"
+ "Min elevation: -500 m (-1640 ft)\n"
+ "Elevation gain: 6000 m (19685 ft)\n"
+ "Max grade: 42 %\n"
+ "Min grade: 11 %\n"
+ "Recorded: 11/2/2010 11:11 AM\n";
assertEquals(expected, descriptionGenerator.generateWaypointDescription(waypoint));
}
/**
* Tests {@link DescriptionGeneratorImpl#writeDistance(double, StringBuilder,
* int, String)}.
*/
public void testWriteDistance() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeDistance(1100, builder, R.string.description_total_distance, "<br>");
assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeTime(long, StringBuilder, int,
* String)}.
*/
public void testWriteTime() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeTime(1000, builder, R.string.description_total_time, "<br>");
assertEquals("Total time: 00:01<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeSpeed(double, StringBuilder,
* int, String)}.
*/
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);
assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeElevation(double, StringBuilder,
* int, String)}.
*/
public void testWriteElevation() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeElevation(4.2, builder, R.string.description_min_elevation, "<br>");
assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writePace(Pair, StringBuilder, int,
* String)}.
*/
public void testWritePace() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writePace(
new Pair<Double, Double>(1.1, 2.2), builder, R.string.description_average_pace, "\n");
assertEquals("Average pace: 54.55 min/km (27.3 min/mi)\n", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
* int, String)}.
*/
public void testWriteGrade() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeGrade(.042, builder, R.string.description_max_grade, "<br>");
assertEquals("Max grade: 4 %<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
* int, String)} with a NaN.
*/
public void testWriteGrade_nan() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeGrade(Double.NaN, builder, R.string.description_max_grade, "<br>");
assertEquals("Max grade: 0 %<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
* int, String)} with an infinite number.
*/
public void testWriteGrade_infinite() {
StringBuilder builder = new StringBuilder();
descriptionGenerator.writeGrade(
Double.POSITIVE_INFINITY, builder, R.string.description_max_grade, "<br>");
assertEquals("Max grade: 0 %<br>", builder.toString());
}
/**
* Tests {@link DescriptionGeneratorImpl#getPace(double)}.
*/
public void testGetPace() {
assertEquals(12.0, descriptionGenerator.getPace(5));
}
/**
* Tests {@link DescriptionGeneratorImpl#getPace(double)} with zero speed.
*/
public void testGetPace_zero() {
assertEquals(0.0, descriptionGenerator.getPace(0));
}
}
@@ -1,6 +1,19 @@
/** /*
* * 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.content; package com.google.android.apps.mytracks.content;
import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult; import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;