Cleanup: TrackShareSummaryGenerator (was DescriptionGenerator) now only produces plaintext (HTML was not used anymore).

This commit is contained in:
Dennis Guse
2025-10-20 09:12:48 +02:00
parent ce2c608cc9
commit 1fa76301e2
3 changed files with 67 additions and 181 deletions
@@ -43,29 +43,26 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.StringUtils;
/** /**
* Tests for {@link DescriptionGenerator}. * Tests for {@link TrackShareSummaryGenerator}.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class DescriptionGeneratorTest { public class TrackShareSummaryGeneratorTest {
@Rule @Rule
public final LocaleRule mLocaleRule = new LocaleRule(Locale.ENGLISH); public final LocaleRule mLocaleRule = new LocaleRule(Locale.ENGLISH);
private static final Instant START_TIME = Instant.ofEpochMilli(1288721514000L); private static final Instant START_TIME = Instant.ofEpochMilli(1288721514000L);
private DescriptionGenerator descriptionGenerator; private TrackShareSummaryGenerator descriptionGenerator;
private final Context context = ApplicationProvider.getApplicationContext(); private final Context context = ApplicationProvider.getApplicationContext();
@Before @Before
public void setUp() { public void setUp() {
descriptionGenerator = new DescriptionGenerator(ApplicationProvider.getApplicationContext()); descriptionGenerator = new TrackShareSummaryGenerator(ApplicationProvider.getApplicationContext());
} }
/**
* Tests {@link DescriptionGenerator#generateTrackDescription(Track, boolean)}.
*/
@Test @Test
public void testGenerateTrackDescription() { public void testGenerateTrackDescription() {
Track track = new Track(); Track track = new Track();
@@ -82,112 +79,60 @@ public class DescriptionGeneratorTest {
track.setTrackStatistics(stats); track.setTrackStatistics(stats);
track.setActivityTypeLocalized("hiking"); track.setActivityTypeLocalized("hiking");
String expected = //"Created by" String expected = //"Created by"
"<a href='https://codeberg.org/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>" "OpenTracks (Debug)\n\n"
+ "Name: -<br>" + "Name: -\n"
+ "Activity type: hiking<br>" + "Activity type: hiking\n"
+ "Description: -<br>" + "Description: -\n"
+ "Total distance: 20.00 km (12.4 mi)<br>" + "Total distance: 20.00 km (12.4 mi)\n"
+ "Total time: 10:00<br>" + "Total time: 10:00\n"
+ "Moving time: 05:00<br>" + "Moving time: 05:00\n"
+ "Average speed: 120.00 km/h (74.6 mi/h)<br>" + "Average speed: 120.00 km/h (74.6 mi/h)\n"
+ "Average moving speed: 240.00 km/h (149.1 mi/h)<br>" + "Average moving speed: 240.00 km/h (149.1 mi/h)\n"
+ "Max speed: 360.00 km/h (223.7 mi/h)<br>" + "Max speed: 360.00 km/h (223.7 mi/h)\n"
+ "Average pace: 0:30 min/km (0:48 min/mi)<br>" + "Average pace: 0:30 min/km (0:48 min/mi)\n"
+ "Average moving pace: 0:15 min/km (0:24 min/mi)<br>" + "Average moving pace: 0:15 min/km (0:24 min/mi)\n"
+ "Fastest pace: 0:10 min/km (0:16 min/mi)<br>" + "Fastest pace: 0:10 min/km (0:16 min/mi)\n"
+ "Max elevation: 550 m (1804 ft)<br>" + "Max elevation: 550 m (1804 ft)\n"
+ "Min elevation: -500 m (-1640 ft)<br>" + "Min elevation: -500 m (-1640 ft)\n"
+ "Elevation gain: 6000 m (19685 ft)<br>" + "Elevation gain: 6000 m (19685 ft)\n"
+ "Elevation loss: 6000 m (19685 ft)<br>" + "Elevation loss: 6000 m (19685 ft)\n"
+ "Recorded: " + StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>"; + "Recorded: " + StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "\n";
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true)); assertEquals(expected, descriptionGenerator.generateTrackDescription(track));
} }
@Test
public void testGenerateTrackDescriptionWithoutMaxMinAltitude() {
Track track = new Track();
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(Distance.of(20000));
stats.setTotalTime(Duration.ofMillis(600000));
stats.setMovingTime(Duration.ofMillis(300000));
stats.setMaxSpeed(Speed.of(100));
stats.setMaxAltitude(Double.POSITIVE_INFINITY);
stats.setMinAltitude(Double.NEGATIVE_INFINITY);
stats.setTotalAltitudeGain(6000f);
stats.setTotalAltitudeLoss(6000f);
stats.setStartTime(START_TIME);
track.setTrackStatistics(stats);
track.setActivityTypeLocalized("hiking");
String expected = //"Created by"
"<a href='https://codeberg.org/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>"
+ "Name: -<br>"
+ "Activity type: hiking<br>"
+ "Description: -<br>"
+ "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:30 min/km (0:48 min/mi)<br>"
+ "Average moving pace: 0:15 min/km (0:24 min/mi)<br>"
+ "Fastest pace: 0:10 min/km (0:16 min/mi)<br>"
+ "Elevation gain: 6000 m (19685 ft)<br>"
+ "Elevation loss: 6000 m (19685 ft)<br>"
+ "Recorded: " + StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>";
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
}
/**
* Tests {@link DescriptionGenerator#writeDistance(Distance, StringBuilder, int, String)}.
*/
@Test @Test
public void testWriteDistance() { public void testWriteDistance() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeDistance(Distance.of(1100), builder, R.string.description_total_distance, "<br>"); descriptionGenerator.writeDistance(Distance.of(1100), builder, R.string.description_total_distance);
assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString()); assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString());
} }
/**
* Tests {@link DescriptionGenerator#writeTime(Duration, StringBuilder, int, String)}.
*/
@Test @Test
public void testWriteTime() { public void testWriteTime() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeTime(Duration.ofMillis(1000), builder, R.string.description_total_time, "<br>"); descriptionGenerator.writeTime(Duration.ofMillis(1000), builder, R.string.description_total_time);
assertEquals("Total time: 00:01<br>", builder.toString()); assertEquals("Total time: 00:01<br>", builder.toString());
} }
/**
* Tests {@link DescriptionGenerator#writeSpeed(Speed, StringBuilder, int, String)}.
*/
@Test @Test
public void testWriteSpeed() { public void testWriteSpeed() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeSpeed(Speed.of(1.1), builder, R.string.description_average_speed, "\n"); descriptionGenerator.writeSpeed(Speed.of(1.1), builder, R.string.description_average_speed);
assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString()); assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString());
} }
/**
* Tests {@link DescriptionGenerator#writeAltitude(double, StringBuilder, int, String)}.
*/
@Test @Test
public void testWriteAltitude() { public void testWriteAltitude() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeAltitude(4.2, builder, R.string.description_min_altitude, "<br>"); descriptionGenerator.writeAltitude(4.2, builder, R.string.description_min_altitude);
assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString()); assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString());
} }
/**
* Tests {@link DescriptionGenerator#writePace(Speed, StringBuilder, int, String)}.
*/
@Test @Test
public void testWritePace() { public void testWritePace() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writePace(Speed.of(1.1), builder, R.string.description_average_pace_in_minute, "\n"); descriptionGenerator.writePace(Speed.of(1.1), builder, R.string.description_average_pace_in_minute);
assertEquals("Average pace: 15:09 min/km (24:23 min/mi)\n", builder.toString()); assertEquals("Average pace: 15:09 min/km (24:23 min/mi)\n", builder.toString());
} }
} }
@@ -42,7 +42,7 @@ public class ShareUtils {
String trackDescription = ""; String trackDescription = "";
if (trackIds.length == 1) { if (trackIds.length == 1) {
Track track = contentProviderUtils.getTrack(trackIds[0]); Track track = contentProviderUtils.getTrack(trackIds[0]);
trackDescription = track == null ? "" : new DescriptionGenerator(context).generateTrackDescription(track, false); trackDescription = track == null ? "" : new TrackShareSummaryGenerator(context).generateTrackDescription(track);
} }
String mime = ""; String mime = "";
@@ -35,20 +35,17 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.StringUtils;
/** /**
* Generates descriptions for tracks and markers. * Generates descriptions for tracks.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public class DescriptionGenerator { public class TrackShareSummaryGenerator {
private static final String HTML_LINE_BREAK = "<br>";
private static final String HTML_PARAGRAPH_SEPARATOR = "<p>";
private static final String TEXT_LINE_BREAK = "\n"; private static final String TEXT_LINE_BREAK = "\n";
private static final String TEXT_PARAGRAPH_SEPARATOR = "\n\n";
private final Context context; private final Context context;
public DescriptionGenerator(Context context) { public TrackShareSummaryGenerator(Context context) {
this.context = context; this.context = context;
} }
@@ -56,156 +53,106 @@ public class DescriptionGenerator {
* Generates a track description. * Generates a track description.
* *
* @param track the track * @param track the track
* @param html true to output html, false to output plain text
*/ */
public String generateTrackDescription(Track track, boolean html) { public String generateTrackDescription(Track track) {
String paragraphSeparator = html ? HTML_PARAGRAPH_SEPARATOR : TEXT_PARAGRAPH_SEPARATOR;
String lineBreak = html ? HTML_LINE_BREAK : TEXT_LINE_BREAK;
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
// Created by // Created by
String creator = html builder.append(context.getString(R.string.app_name));
? "<a href='" + context.getString(R.string.app_web_url) + "'>" + context.getString(R.string.app_name) + "</a>" builder.append(TEXT_LINE_BREAK);
: context.getString(R.string.app_name); builder.append(TEXT_LINE_BREAK);
builder.append(creator);
builder.append(paragraphSeparator); writeString(track.getName(), builder, R.string.generic_name_line);
writeString(track.getActivityTypeLocalized(), builder, R.string.description_activity_type);
writeString(track.getName(), builder, R.string.generic_name_line, lineBreak); writeString(track.getDescription(), builder, R.string.generic_description_line);
writeString(track.getActivityTypeLocalized(), builder, R.string.description_activity_type, lineBreak); builder.append(generateTrackStatisticsDescription(track.getTrackStatistics()));
writeString(track.getDescription(), builder, R.string.generic_description_line, lineBreak);
builder.append(generateTrackStatisticsDescription(track.getTrackStatistics(), html));
return builder.toString(); return builder.toString();
} }
/** private void writeString(String text, StringBuilder builder, int resId) {
* Writes a string to a string builder.
*
* @param text the string
* @param builder the string builder
* @param resId the resource id containing one string placeholder
* @param lineBreak the line break
*/
private void writeString(String text, StringBuilder builder, int resId, String lineBreak) {
if (text == null || text.isEmpty()) { if (text == null || text.isEmpty()) {
text = context.getString(R.string.value_unknown); text = context.getString(R.string.value_unknown);
} }
builder.append(context.getString(resId, text)); builder.append(context.getString(resId, text));
builder.append(lineBreak); builder.append(TrackShareSummaryGenerator.TEXT_LINE_BREAK);
} }
/** private String generateTrackStatisticsDescription(TrackStatistics stats) {
* Generates a description for a {@link TrackStatistics}.
*
* @param stats the track statistics
* @param html true to use "<br>" for line break instead of "\n"
*/
private String generateTrackStatisticsDescription(TrackStatistics stats, boolean html) {
String lineBreak = html ? HTML_LINE_BREAK : TEXT_LINE_BREAK;
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
// Total distance // Total distance
writeDistance(stats.getTotalDistance(), builder, R.string.description_total_distance, lineBreak); writeDistance(stats.getTotalDistance(), builder, R.string.description_total_distance);
// Total time // Total time
writeTime(stats.getTotalTime(), builder, R.string.description_total_time, lineBreak); writeTime(stats.getTotalTime(), builder, R.string.description_total_time);
// Moving time // Moving time
writeTime(stats.getMovingTime(), builder, R.string.description_moving_time, lineBreak); writeTime(stats.getMovingTime(), builder, R.string.description_moving_time);
// Average speed // Average speed
writeSpeed(stats.getAverageSpeed(), builder, R.string.description_average_speed, lineBreak); writeSpeed(stats.getAverageSpeed(), builder, R.string.description_average_speed);
// Average moving speed // Average moving speed
writeSpeed(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_speed, lineBreak); writeSpeed(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_speed);
// Max speed // Max speed
writeSpeed(stats.getMaxSpeed(), builder, R.string.description_max_speed, lineBreak); writeSpeed(stats.getMaxSpeed(), builder, R.string.description_max_speed);
// Average pace // Average pace
writePace(stats.getAverageSpeed(), builder, R.string.description_average_pace_in_minute, lineBreak); writePace(stats.getAverageSpeed(), builder, R.string.description_average_pace_in_minute);
// Average moving pace // Average moving pace
writePace(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_pace_in_minute, lineBreak); writePace(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_pace_in_minute);
// Fastest pace // Fastest pace
writePace(stats.getMaxSpeed(), builder, R.string.description_fastest_pace_in_minute, lineBreak); writePace(stats.getMaxSpeed(), builder, R.string.description_fastest_pace_in_minute);
// Min and Max altitude // Min and Max altitude
if (stats.hasAltitudeExtremities()) { if (stats.hasAltitudeExtremities()) {
writeAltitude(stats.getMaxAltitude(), builder, R.string.description_max_altitude, lineBreak); writeAltitude(stats.getMaxAltitude(), builder, R.string.description_max_altitude);
writeAltitude(stats.getMinAltitude(), builder, R.string.description_min_altitude, lineBreak); writeAltitude(stats.getMinAltitude(), builder, R.string.description_min_altitude);
} }
// Altitude gain // Altitude gain
if (stats.hasTotalAltitudeGain()) { if (stats.hasTotalAltitudeGain()) {
writeAltitude(stats.getTotalAltitudeGain(), builder, R.string.description_altitude_gain, lineBreak); writeAltitude(stats.getTotalAltitudeGain(), builder, R.string.description_altitude_gain);
} }
// Altitude loss // Altitude loss
if (stats.hasTotalAltitudeLoss()) { if (stats.hasTotalAltitudeLoss()) {
writeAltitude(stats.getTotalAltitudeLoss(), builder, R.string.description_altitude_loss, lineBreak); writeAltitude(stats.getTotalAltitudeLoss(), builder, R.string.description_altitude_loss);
} }
// Recorded time // Recorded time
builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(stats.getStartTime(), ZoneId.systemDefault())))); builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(stats.getStartTime(), ZoneId.systemDefault()))));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
return builder.toString(); return builder.toString();
} }
/**
* Writes distance.
*
* @param distance distance in meters
* @param builder StringBuilder to append distance
* @param resId resource id of distance string
* @param lineBreak line break string
*/
@VisibleForTesting @VisibleForTesting
void writeDistance(Distance distance, StringBuilder builder, int resId, String lineBreak) { void writeDistance(Distance distance, StringBuilder builder, int resId) {
double distanceInKm = distance.toKM(); double distanceInKm = distance.toKM();
double distanceInMi = distance.toMI(); double distanceInMi = distance.toMI();
builder.append(context.getString(resId, distanceInKm, distanceInMi)); builder.append(context.getString(resId, distanceInKm, distanceInMi));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
} }
/**
* Writes time.
*
* @param time time in milliseconds.
* @param builder StringBuilder to append time
* @param resId resource id of time string
* @param lineBreak line break string
*/
@VisibleForTesting @VisibleForTesting
void writeTime(Duration time, StringBuilder builder, int resId, String lineBreak) { void writeTime(Duration time, StringBuilder builder, int resId) {
builder.append(context.getString(resId, StringUtils.formatElapsedTime(time))); builder.append(context.getString(resId, StringUtils.formatElapsedTime(time)));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
} }
/**
* Writes speed.
*
* @param speed speed in meters per second
* @param builder StringBuilder to append speed
* @param resId resource id of speed string
* @param lineBreak line break string
*/
@VisibleForTesting @VisibleForTesting
void writeSpeed(Speed speed, StringBuilder builder, int resId, String lineBreak) { void writeSpeed(Speed speed, StringBuilder builder, int resId) {
builder.append(context.getString(resId, speed.toKMH(), speed.toMPH())); builder.append(context.getString(resId, speed.toKMH(), speed.toMPH()));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
} }
/**
* @param builder StringBuilder to append pace
* @param resId resource id of pace string
* @param lineBreak line break string
*/
@VisibleForTesting @VisibleForTesting
void writePace(Speed speed, StringBuilder builder, int resId, String lineBreak) { void writePace(Speed speed, StringBuilder builder, int resId) {
Pair<String, String> paceInMetrics = SpeedFormatter.Builder().setUnit(UnitSystem.METRIC).setReportSpeedOrPace(false).build(context).getSpeedParts(speed); Pair<String, String> paceInMetrics = SpeedFormatter.Builder().setUnit(UnitSystem.METRIC).setReportSpeedOrPace(false).build(context).getSpeedParts(speed);
Pair<String, String> paceInImperial = SpeedFormatter.Builder().setUnit(UnitSystem.IMPERIAL_FEET).setReportSpeedOrPace(false).build(context).getSpeedParts(speed); Pair<String, String> paceInImperial = SpeedFormatter.Builder().setUnit(UnitSystem.IMPERIAL_FEET).setReportSpeedOrPace(false).build(context).getSpeedParts(speed);
@@ -213,20 +160,14 @@ public class DescriptionGenerator {
String formattedPaceImperial = paceInImperial.first != null ? paceInImperial.first : context.getString(R.string.value_unknown); String formattedPaceImperial = paceInImperial.first != null ? paceInImperial.first : context.getString(R.string.value_unknown);
builder.append(context.getString(resId, formattedPaceMetrics, formattedPaceImperial)); builder.append(context.getString(resId, formattedPaceMetrics, formattedPaceImperial));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
} }
/**
* @param altitude_m altitude_m in meters
* @param builder StringBuilder to append
* @param resId resource id of altitude string
* @param lineBreak line break string
*/
@VisibleForTesting @VisibleForTesting
void writeAltitude(double altitude_m, StringBuilder builder, int resId, String lineBreak) { void writeAltitude(double altitude_m, StringBuilder builder, int resId) {
long altitudeInM = Math.round(altitude_m); long altitudeInM = Math.round(altitude_m);
long altitudeInFt = Math.round(Distance.of(altitude_m).toFT()); long altitudeInFt = Math.round(Distance.of(altitude_m).toFT());
builder.append(context.getString(resId, altitudeInM, altitudeInFt)); builder.append(context.getString(resId, altitudeInM, altitudeInFt));
builder.append(lineBreak); builder.append(TEXT_LINE_BREAK);
} }
} }