forked from upstream-mirrors/OpenTracks
Cleanup: SegmentStatisticUpdater.
This commit is contained in:
+69
-70
@@ -16,20 +16,21 @@
|
|||||||
package de.dennisguse.opentracks.stats;
|
package de.dennisguse.opentracks.stats;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.data.models.AltitudeExtremities;
|
||||||
|
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||||
import de.dennisguse.opentracks.data.models.Speed;
|
import de.dennisguse.opentracks.data.models.Speed;
|
||||||
|
import de.dennisguse.opentracks.data.models.Statistics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link SegmentStatisticUpdater}.
|
* Tests for {@link SegmentStatisticUpdater}.
|
||||||
@@ -40,89 +41,87 @@ import de.dennisguse.opentracks.data.models.Speed;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class SegmentStatisticUpdaterTest {
|
public class SegmentStatisticUpdaterTest {
|
||||||
|
|
||||||
private SegmentStatisticUpdater statistics;
|
@Deprecated //TODO SegmentStatisticsUpdater should always have data, right?
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
statistics = new SegmentStatisticUpdater();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMerge_no_data() {
|
public void testMerge_no_data() {
|
||||||
// given
|
// given
|
||||||
SegmentStatisticUpdater statistics2 = new SegmentStatisticUpdater();
|
SegmentStatisticUpdater subject = new SegmentStatisticUpdater();
|
||||||
|
SegmentStatisticUpdater append = new SegmentStatisticUpdater();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
statistics.merge(statistics2);
|
subject.merge(append);
|
||||||
|
Statistics result = subject.getStatistics();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertNull(statistics.getStartTime());
|
assertEquals(
|
||||||
assertNull(statistics.getStopTime());
|
new Statistics(
|
||||||
assertEquals(Duration.ZERO, statistics.getMovingTime());
|
null,
|
||||||
assertEquals(Duration.ZERO, statistics.getTotalTime());
|
null,
|
||||||
|
Duration.ZERO,
|
||||||
assertNull(statistics.getTotalAltitudeGain());
|
Duration.ZERO,
|
||||||
assertNull(statistics.getTotalAltitudeLoss());
|
Distance.ZERO,
|
||||||
assertEquals(Double.NEGATIVE_INFINITY, statistics.getMaxAltitude(), 0.0);
|
Speed.ZERO,
|
||||||
assertEquals(Double.POSITIVE_INFINITY, statistics.getMinAltitude(), 0.0);
|
null,
|
||||||
assertEquals(0.0, statistics.getMaxSpeed().toMPS(), 0.0);
|
null,
|
||||||
assertEquals(0.0, statistics.getAverageSpeed().toMPS(), 0.0);
|
null,
|
||||||
assertEquals(0.0, statistics.getAverageMovingSpeed().toMPS(), 0.0);
|
null
|
||||||
assertNull(statistics.getAverageHeartRate());
|
),
|
||||||
|
result
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMerge() {
|
public void testMerge() {
|
||||||
// given
|
// given
|
||||||
SegmentStatisticUpdater statistics2 = new SegmentStatisticUpdater();
|
SegmentStatisticUpdater subject = new SegmentStatisticUpdater(
|
||||||
statistics.setStartTime(Instant.ofEpochMilli(1000)); // Resulting start time
|
new Statistics(
|
||||||
statistics.setStopTime(Instant.ofEpochMilli(2500));
|
Instant.ofEpochMilli(1000),
|
||||||
statistics2.setStartTime(Instant.ofEpochMilli(3000));
|
Instant.ofEpochMilli(2500),
|
||||||
statistics2.setStopTime(Instant.ofEpochMilli(4000)); // Resulting stop time
|
Duration.ofMillis(1500),
|
||||||
statistics.setTotalTime(Duration.ofMillis(1500));
|
Duration.ofMillis(700),
|
||||||
statistics2.setTotalTime(Duration.ofMillis(1000)); // Result: 1500+1000
|
Distance.of(750.0),
|
||||||
statistics.setMovingTime(Duration.ofMillis(700));
|
Speed.of(60.0),
|
||||||
statistics2.setMovingTime(Duration.ofMillis(600)); // Result: 700+600
|
new AltitudeExtremities(1200, 1250),
|
||||||
statistics.setTotalDistance(Distance.of(750.0));
|
new AltitudeGainLoss(50, 0),
|
||||||
statistics2.setTotalDistance(Distance.of(350.0)); // Result: 750+350
|
HeartRate.of(100),
|
||||||
statistics.setTotalAltitudeGain(50.0f);
|
null
|
||||||
statistics2.setTotalAltitudeGain(850.0f); // Result: 850+50
|
)
|
||||||
statistics.setMaxSpeed(Speed.of(60.0)); // Resulting max speed
|
);
|
||||||
statistics2.setMaxSpeed(Speed.of(30.0));
|
|
||||||
statistics.setMaxAltitude(1250.0);
|
SegmentStatisticUpdater append = new SegmentStatisticUpdater(
|
||||||
statistics.setMinAltitude(1200.0); // Resulting min altitude
|
new Statistics(
|
||||||
statistics2.setMaxAltitude(3575.0); // Resulting max altitude
|
Instant.ofEpochMilli(3000),
|
||||||
statistics2.setMinAltitude(2800.0);
|
Instant.ofEpochMilli(4000),
|
||||||
statistics.setAverageHeartRate(HeartRate.of(100f));
|
Duration.ofMillis(1000),
|
||||||
statistics2.setAverageHeartRate(HeartRate.of(200f));
|
Duration.ofMillis(600),
|
||||||
|
Distance.of(350.0),
|
||||||
|
Speed.of(30.0),
|
||||||
|
new AltitudeExtremities(2800.0, 3575.0),
|
||||||
|
new AltitudeGainLoss(850, 0),
|
||||||
|
HeartRate.of(200),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
statistics.merge(statistics2);
|
subject.merge(append);
|
||||||
|
Statistics result = subject.getStatistics();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(Instant.ofEpochMilli(1000), statistics.getStartTime());
|
assertEquals(
|
||||||
assertEquals(Instant.ofEpochMilli(4000), statistics.getStopTime());
|
new Statistics(
|
||||||
assertEquals(Duration.ofMillis(2500), statistics.getTotalTime());
|
Instant.ofEpochMilli(1000),
|
||||||
assertEquals(Duration.ofMillis(1300), statistics.getMovingTime());
|
Instant.ofEpochMilli(4000),
|
||||||
assertEquals(1100.0, statistics.getTotalDistance().toM(), 0.001);
|
Duration.ofMillis(2500),
|
||||||
assertEquals(900.0, statistics.getTotalAltitudeGain(), 0.001);
|
Duration.ofMillis(1300),
|
||||||
assertEquals(Speed.of(statistics.getTotalDistance(), statistics.getMovingTime()).toMPS(), statistics.getMaxSpeed().toMPS(), 0.001);
|
Distance.of(1100),
|
||||||
assertEquals(1200.0, statistics.getMinAltitude(), 0.001);
|
Speed.of(846.1538461538461), //TODO Check why this is not 60
|
||||||
assertEquals(3575.0, statistics.getMaxAltitude(), 0.001);
|
new AltitudeExtremities(1200, 3575),
|
||||||
assertEquals(150.0, statistics.getAverageHeartRate().getBPM(), 0.001);
|
new AltitudeGainLoss(900, 0),
|
||||||
}
|
HeartRate.of(150),
|
||||||
|
null
|
||||||
@Test
|
)
|
||||||
public void testGetAverageSpeed() {
|
, result
|
||||||
statistics.setTotalDistance(Distance.of(1000.0));
|
);
|
||||||
statistics.setTotalTime(Duration.ofMillis(50000));
|
|
||||||
assertEquals(20.0, statistics.getAverageSpeed().toMPS(), 0.001);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAverageMovingSpeed() {
|
|
||||||
statistics.setTotalDistance(Distance.of(1000.0));
|
|
||||||
statistics.setMovingTime(Duration.ofMillis(20000));
|
|
||||||
assertEquals(50.0, statistics.getAverageMovingSpeed().toMPS(), 0.001);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.annotation.Nullable;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
//TODO Add @NonNull to attributes
|
||||||
public record Statistics(
|
public record Statistics(
|
||||||
Instant startTime,
|
Instant startTime,
|
||||||
Instant stopTime,
|
Instant stopTime,
|
||||||
@@ -14,7 +15,7 @@ public record Statistics(
|
|||||||
Duration movingTime, // Based on when we believe the user is traveling
|
Duration movingTime, // Based on when we believe the user is traveling
|
||||||
|
|
||||||
Distance totalDistance,
|
Distance totalDistance,
|
||||||
//TODO Check if this is persisted; if not: remove
|
|
||||||
Speed maxSpeed,
|
Speed maxSpeed,
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -265,20 +265,18 @@ public class SegmentStatisticUpdater {
|
|||||||
return movingTime;
|
return movingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public void setMovingTime(Duration movingTime) {
|
public void setMovingTime(Duration movingTime) {
|
||||||
this.movingTime = movingTime;
|
this.movingTime = movingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMovingTime(TrackPoint trackPoint, TrackPoint lastTrackPoint) {
|
public void addMovingTime(TrackPoint trackPoint, TrackPoint lastTrackPoint) {
|
||||||
addMovingTime(Duration.between(lastTrackPoint.getTime(), trackPoint.getTime()));
|
Duration movingDuration = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
if (movingDuration.isNegative()) {
|
||||||
public void addMovingTime(Duration time) {
|
|
||||||
if (time.isNegative()) {
|
|
||||||
throw new RuntimeException("Moving time cannot be negative");
|
throw new RuntimeException("Moving time cannot be negative");
|
||||||
}
|
}
|
||||||
movingTime = movingTime.plus(time);
|
movingTime = movingTime.plus(movingDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isIdle() {
|
public boolean isIdle() {
|
||||||
@@ -289,16 +287,12 @@ public class SegmentStatisticUpdater {
|
|||||||
isIdle = idle;
|
isIdle = idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
public HeartRate getAverageHeartRate() {
|
public HeartRate getAverageHeartRate() {
|
||||||
return avgHeartRate;
|
return avgHeartRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Power getAveragePower() {
|
|
||||||
return avgPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the average speed.
|
* Gets the average speed.
|
||||||
* This calculation only takes into account the displacement until the last point that was accounted for in statistics.
|
* This calculation only takes into account the displacement until the last point that was accounted for in statistics.
|
||||||
@@ -322,26 +316,22 @@ public class SegmentStatisticUpdater {
|
|||||||
this.maxSpeed = maxSpeed;
|
this.maxSpeed = maxSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
@Deprecated
|
||||||
public double getMinAltitude() {
|
public double getMinAltitude() {
|
||||||
return altitudeExtremities.getMin();
|
return altitudeExtremities.getMin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMinAltitude(double altitude_m) {
|
|
||||||
altitudeExtremities.setMin(altitude_m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum altitude.
|
* Gets the maximum altitude.
|
||||||
* This is calculated from the smoothed altitude, so this can actually be less than the current altitude.
|
* This is calculated from the smoothed altitude, so this can actually be less than the current altitude.
|
||||||
*/
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
@Deprecated
|
||||||
public double getMaxAltitude() {
|
public double getMaxAltitude() {
|
||||||
return altitudeExtremities.getMax();
|
return altitudeExtremities.getMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxAltitude(double altitude_m) {
|
|
||||||
altitudeExtremities.setMax(altitude_m);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAltitudeExtremities(Altitude altitude) {
|
public void updateAltitudeExtremities(Altitude altitude) {
|
||||||
if (altitude != null) {
|
if (altitude != null) {
|
||||||
altitudeExtremities.update(altitude.toM());
|
altitudeExtremities.update(altitude.toM());
|
||||||
|
|||||||
@@ -214,11 +214,12 @@ public class TrackStatisticsUpdater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TrackStatisticsUpdater{" +
|
return "TrackStatisticsUpdater{" +
|
||||||
"trackStatistics=" + segmentStatisticUpdater +
|
"segmentStatisticUpdater=" + segmentStatisticUpdater +
|
||||||
|
", currentSegment=" + currentSegment +
|
||||||
|
", lastTrackPoint=" + lastTrackPoint +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user