forked from upstream-mirrors/OpenTracks
Compare commits
312 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ae4d2da262 | |||
| 708cbf0b2a | |||
| 60e2fe57f9 | |||
| 14cebf3fec | |||
| b651a8ca6a | |||
| d75472ef11 | |||
| 0b849c3d55 | |||
| 1c767c41a7 | |||
| dfa80d61d7 | |||
| fa558c9ab7 | |||
| a1a363698f | |||
| b79acfb942 | |||
| 24ea718ff2 | |||
| 6d187fa66d | |||
| ea27db13fa | |||
| 29d2e7c78c | |||
| 4b7badbecc | |||
| 0dcb8010e2 | |||
| 0a9d4b207c | |||
| c6cb388ce4 | |||
| e6e009ba14 | |||
| f8aa456549 | |||
| 167d90332e | |||
| 719a052f34 | |||
| 244ca26210 | |||
| 476f3a517b | |||
| 289e93eb5d | |||
| 18ff96733e | |||
| 0f2c5adf26 | |||
| 74954df600 | |||
| 1a14fed287 | |||
| 744853ee91 | |||
| 597e1b2c7f | |||
| 8156993921 | |||
| 9890dc28bd | |||
| b65d83010d | |||
| 1a5d06f9c6 | |||
| 723c21d7ec | |||
| 8fe0c3be7d | |||
| e64792bf3f | |||
| 21bafff761 | |||
| c33c2de51d | |||
| a6b11c1c37 | |||
| 315788308b | |||
| 547c1c5c65 | |||
| 69efd6fb82 | |||
| 3a0524f96d | |||
| 05456b44ef | |||
| b449dad619 | |||
| ccefe36489 | |||
| 90e9ab6d2a | |||
| d1061fa6cd | |||
| c0c813001f | |||
| 51498bbcf9 | |||
| 4ef1fcefbc | |||
| 9a572130a7 | |||
| e931f5ab7c | |||
| 9affe28fad | |||
| 4905a37951 | |||
| 439671d0a4 | |||
| 825e8dda6e | |||
| 661c839c78 | |||
| 8eb42a7ecb | |||
| 660a55ff5a | |||
| 958697bcb3 | |||
| 6029eb0317 | |||
| 8b56d53a6a | |||
| e9deebea6c | |||
| 54844b9a9a | |||
| 738201c1c2 | |||
| 48b6be0bd1 | |||
| 6b924cd936 | |||
| 5f083de530 | |||
| 278f6323f1 | |||
| 5baa8fa21e | |||
| 707f4add71 | |||
| b583f8f23d | |||
| c847f622e4 | |||
| 70dd58f484 | |||
| 015352c989 | |||
| 42ae582cd8 | |||
| 6e0ad50397 | |||
| d43efad52a | |||
| 693904529d | |||
| 08143a546a | |||
| eb49156ee7 | |||
| 51c03d8d75 | |||
| 666cbbad68 | |||
| 1cbc93c303 | |||
| afd1232940 | |||
| a3407ccbea | |||
| c259f9b8bd | |||
| b1a556bf91 | |||
| ab70874d59 | |||
| e6367b1dfa | |||
| 8db381c448 | |||
| ef111b7959 | |||
| 56c6cb1f19 | |||
| 874c5eb8ae | |||
| 1a087b1117 | |||
| 3120cd8da0 | |||
| 4263c000c0 | |||
| f4073ead63 | |||
| 2f90784442 | |||
| 2cab394d03 | |||
| 55f1bcb30b | |||
| 33a17784e6 | |||
| 7cb97b0e6b | |||
| 1cb3db496a | |||
| d49d6c9857 | |||
| 12f0c3313f | |||
| a78e059612 | |||
| 0774ee512f | |||
| 4c55468571 | |||
| 201f2d1b27 | |||
| 595ad7f7b5 | |||
| d518507193 | |||
| 888f59133d | |||
| 5bb5b3b344 | |||
| b584a95c9c | |||
| 9ba152c469 | |||
| 1191f2e1e2 | |||
| e5aed794ba | |||
| 7956063598 | |||
| 0f356de2ca | |||
| 5b4b54694c | |||
| 9c271972d2 | |||
| 744f11eaa0 | |||
| 3c16f67882 | |||
| 12d1a50995 | |||
| 21404fed50 | |||
| 990c91f978 | |||
| 6a262426a5 | |||
| 1b2998f423 | |||
| d24dd2b005 | |||
| 341fd02f9a | |||
| 6833ea7282 | |||
| a1da53864e | |||
| 28d49de047 | |||
| 4ae9d24960 | |||
| 0b0b1a0d8d | |||
| 090cdbf712 | |||
| 8258d607c3 | |||
| 686a2a9b8f | |||
| 7ddb6b32bb | |||
| 5cd639c852 | |||
| ae9906fb18 | |||
| 96bcac397b | |||
| d7b207afac | |||
| 1672ba99ad | |||
| a6d4a05839 | |||
| 860b90da37 | |||
| 46d7385d25 | |||
| 25fbd9490c | |||
| 6d33adffce | |||
| 92cecb6f3a | |||
| e6bdc9a41d | |||
| e234e9c493 | |||
| 73d6ca6ca6 | |||
| 1ef7a6ecc4 | |||
| 94a0b57362 | |||
| 4ebaf366d6 | |||
| 911f2c525f | |||
| a310f773a1 | |||
| 8a247e5b38 | |||
| 1045ade71a | |||
| 4307dceb70 | |||
| 59ea50b96f | |||
| 8d015fee6c | |||
| 653352255e | |||
| ebcdd87481 | |||
| 8d1af8f2cf | |||
| 766739c222 | |||
| 54fa6aa3e2 | |||
| 1dc737410b | |||
| 4093899a82 | |||
| 9236eb6944 | |||
| 9f00b0606b | |||
| 20a18b86dc | |||
| 34cfc235c3 | |||
| f733d18a60 | |||
| 221b61c7f1 | |||
| ca64f2c749 | |||
| 3d083928eb | |||
| f47ab142f2 | |||
| 6e4d46a14d | |||
| fffeb40200 | |||
| a5e5d0ca51 | |||
| 7791ff8659 | |||
| 3db0a53377 | |||
| 58dac8b706 | |||
| f29b6d4088 | |||
| 80fb4f9998 | |||
| 6340e55fff | |||
| 625549d381 | |||
| 7d9878b32e | |||
| a5553211af | |||
| 044e84154c | |||
| f61d718b2d | |||
| c7a54dcee8 | |||
| 3dc2ee3462 | |||
| 6817ff3234 | |||
| fb0400001a | |||
| 16591b3e80 | |||
| 28da32f573 | |||
| c687308d97 | |||
| 65c8e8542e | |||
| ca4cb648e7 | |||
| 53240c3d1a | |||
| 95b27f66fb | |||
| f31e146cda | |||
| 696939112a | |||
| 73ce97a63e | |||
| 5988ae3d3f | |||
| 58655814b2 | |||
| 11f1b6e72d | |||
| 8f537f33a7 | |||
| 4db72230ff | |||
| fd92793c2a | |||
| 05e45b6870 | |||
| 7521f906ed | |||
| 3222a0c497 | |||
| caf3d957cd | |||
| 005d00cfaa | |||
| c227d54f26 | |||
| bc62320b9f | |||
| 0ad32f676c | |||
| fff5f2d406 | |||
| be653b73ee | |||
| 4580f2a7bb | |||
| 5dd56892fb | |||
| e3460d94ed | |||
| 920ad5129a | |||
| fba08fe8dd | |||
| 5746a41905 | |||
| 361ae909e7 | |||
| 4b59660ea1 | |||
| cabf5d238e | |||
| 9c902b89ed | |||
| c31b8a5802 | |||
| 901c548d13 | |||
| b77de1e10d | |||
| b8c7fba7d8 | |||
| 466719fbc8 | |||
| 4f0ab71503 | |||
| daa4689f44 | |||
| 023a5aa221 | |||
| 291633c1d5 | |||
| 00990076fb | |||
| e672df7a60 | |||
| 82eb237117 | |||
| 832005565a | |||
| 894699f009 | |||
| f45dba258b | |||
| 17be49af70 | |||
| e91d36fc16 | |||
| 56f333180b | |||
| 9af8b0d353 | |||
| 57c0750980 | |||
| 8e36ee2e7d | |||
| ec2e527fd1 | |||
| d968e5d0c1 | |||
| 4257f21cae | |||
| 26e7059af2 | |||
| 94595f2a1f | |||
| 1fa76301e2 | |||
| ce2c608cc9 | |||
| 916f26dfda | |||
| a108edc125 | |||
| 1a1a8a851b | |||
| ddd1efeb58 | |||
| 6c30dd8509 | |||
| 21fe59f32c | |||
| f79b2b51c8 | |||
| b16e9ad964 | |||
| 65f8ba16b3 | |||
| 9b48993cd0 | |||
| 54cec3e821 | |||
| daeb972c8a | |||
| 73872e8926 | |||
| c15fa21a56 | |||
| e9d1080e5d | |||
| d0b3f45151 | |||
| 32b0b02d28 | |||
| d6617f61b7 | |||
| b5180f235f | |||
| e879eedbd6 | |||
| c7ca6800f7 | |||
| fed884a6ce | |||
| 02a77e5ce7 | |||
| 6f97399aeb | |||
| 1c4f0e67ab | |||
| ebed386d96 | |||
| e44f63feb7 | |||
| 34c5a3ab97 | |||
| eac47db058 | |||
| e72d2a750c | |||
| f54856c3f1 | |||
| 81f6bbe955 | |||
| c162c0a0ff | |||
| 385d05dcdb | |||
| 308ce4ac07 | |||
| f8a0241e1f | |||
| c74a5c8749 | |||
| defdd49a65 | |||
| 46cdae399d | |||
| a19f363b4a | |||
| b55b25e00d | |||
| d527770a0a | |||
| fb75b0fa58 | |||
| 1c986e48f2 | |||
| 7f666c571e |
+1
-1
@@ -4,7 +4,7 @@ end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 100
|
||||
max_line_length = 200
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Android Test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Android Lint
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'ubuntu:android-24.04'
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Lint
|
||||
shell: bash
|
||||
run: ./gradlew lint
|
||||
|
||||
android-check:
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'ubuntu:android-24.04'
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: ./gradlew testNightlyDebugUnitTest --stacktrace
|
||||
@@ -1,5 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
liberapay: OpenTracks
|
||||
github: [rgmf, pstorch, dennisguse]
|
||||
custom: https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore
|
||||
@@ -40,10 +40,9 @@ _OpenTracks_ is a sport tracking application that completely respects your priva
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Translations are hosted on <a href="https://hosted.weblate.org/engage/opentracks/">
|
||||
hosted.weblate.org</a>.
|
||||
<a href="https://hosted.weblate.org/engage/opentracks/">
|
||||
<img src="https://hosted.weblate.org/widgets/opentracks/-/horizontal-auto.svg" alt="Translation status" />
|
||||
Translations are hosted on <a href="https://translate.codeberg.org/engage/opentracks/">translate.codeberg.org/projects/opentracks/</a>.
|
||||
<a href="https://translate.codeberg.org/engage/opentracks/">
|
||||
<img src="https://translate.codeberg.org/widget/opentracks/opentracks-src-main-res-values-strings-xml-main/horizontal-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
|
||||
## Screenshots
|
||||
@@ -112,8 +111,7 @@ The API is disabled by default to protect the user's privacy, but it can easily
|
||||
`Classes`:
|
||||
* **Start a recording:** `de.dennisguse.opentracks.publicapi.StartRecording`
|
||||
* Set track data: `TRACK_NAME`, `TRACK_DESCRIPTION`, `TRACK_CATEGORY`, and `TRACK_ICON` (
|
||||
non-localized identifier
|
||||
see [/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38](/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38)).
|
||||
see `ActivityType.id` defined in [/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38](/src/main/java/de/dennisguse/opentracks/data/model/ActivityType.java)).
|
||||
NOTE: if `TRACK_ICON` is not present, `TRACK_CATEGORY` will be used to determine the icon (
|
||||
localized).
|
||||
* Send recorded data to another application via _Dashboard API_: `STATS_TARGET_PACKAGE` and
|
||||
@@ -134,6 +132,10 @@ adb shell am start -n "de.dennisguse.opentracks.playstore/de.dennisguse.opentrac
|
||||
```
|
||||
|
||||
## File formats compatibility with open-source software
|
||||
|
||||
KML/KMZ can be used to export indoor activities (no GPS present).
|
||||
GPX exports only those points that have a GPS coordinate present (sensor data is aggregated though).
|
||||
|
||||
| | [GPX 1.1](https://www.topografix.com/GPX/1/1/) | [KML 2.3](https://docs.opengeospatial.org/is/12-007r2/12-007r2.html) | [KMZ 2.3](https://docs.opengeospatial.org/is/12-007r2/12-007r2.html) |
|
||||
|-----------------------------------------------------------|--------------------------------------------------------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
| [OpenLayers 7.1.0](https://openlayers.org/) | ? | [no](https://github.com/openlayers/openlayers/issues/14104) | [no](https://github.com/openlayers/openlayers/issues/14104) |
|
||||
@@ -143,8 +145,8 @@ adb shell am start -n "de.dennisguse.opentracks.playstore/de.dennisguse.opentrac
|
||||
| [FitTrackee](https://github.com/SamR1/FitTrackee) | yes | n/a | n/a |
|
||||
| [SportsTracker](https://github.com/ssaring/sportstracker) | yes, [single tracks only](https://github.com/ssaring/sportstracker/issues/260) | no | no |
|
||||
| [ExifTool](https://exiftool.org) | [yes](https://exiftool.org/forum/index.php?topic=15972.0) | no | no |
|
||||
| [Wanderer](https://wanderer.to/) | yes | yes | yes |
|
||||
|
||||
| [Wanderer](https://wanderer.to/) | yes | yes | yes |
|
||||
| [GPX.Studio]https://gpx.studio/) | yes | no | no |
|
||||
|
||||
## Dashboard API (incl. map)
|
||||
|
||||
|
||||
+3
-3
@@ -3,10 +3,10 @@
|
||||
## Craft new releases
|
||||
|
||||
1. Execute use `RELEASE.sh`.
|
||||
2. Push to Github
|
||||
3. Create release on Github (incl. changelog)
|
||||
2. Push to Codeberg
|
||||
3. Create release on Codeberg (incl. changelog)
|
||||
This actually creates a tag that is later used by F-Droid
|
||||
4. Pull from Github
|
||||
4. Pull from Codeberg
|
||||
5. Build reproducible release and attach to release
|
||||
6. ... wait until reproducibility is verified by F-Droid
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ However, often only one value is provided.
|
||||
We only support _Instantaneous Power_.
|
||||
|
||||
For cycling (incl. cadence):
|
||||
* Assioma Duo Powermeter
|
||||
|
||||
* Assioma
|
||||
* Duo Powermeter
|
||||
* Pro MX-2
|
||||
* Elite drivo II
|
||||
* QUARQ Red DZero Powermeter
|
||||
* Tacx Satori Smart
|
||||
|
||||
+3
-6
@@ -11,9 +11,6 @@ CHANGELOG_FILE="$CHANGELOG_DIR/$VERSIONID.txt"
|
||||
|
||||
git diff --exit-code || echo -e "\nWARNING WARNING WARNING WARNING WARNING: this branch contains uncommit changes."
|
||||
|
||||
#TODO Execute all tests: we are destroying data, running on a real device.
|
||||
# ./gradlew connectedCheck
|
||||
|
||||
# Changelog
|
||||
echo -e "\nPrevious changelog\n------------"
|
||||
PREVIOUS_CHANGELOG=$(find "$CHANGELOG_DIR" -iname "[[:digit:]]**.txt" | sort -n | tail -1)
|
||||
@@ -34,8 +31,8 @@ gedit -w "$CHANGELOG_FILE"
|
||||
git add "$CHANGELOG_FILE"
|
||||
|
||||
echo "Updating build.gradle"
|
||||
sed -i s/versionCode\ .*/versionCode\ "$VERSIONID"/g build.gradle
|
||||
sed -i s/versionName\ .*/versionName\ "\"$VERSIONNAME\""/g build.gradle
|
||||
sed -i -e "s/versionCode\ [0-9]\{1,\}/versionCode\ $VERSIONID/g" build.gradle
|
||||
sed -i -e "s/versionName\ \"v[0-9\.]\{1,\}\"/versionName\ \"$VERSIONNAME\"/g" build.gradle
|
||||
|
||||
git diff
|
||||
|
||||
@@ -48,4 +45,4 @@ read
|
||||
git add -u
|
||||
git commit -m "$COMMIT_MESSAGE"
|
||||
|
||||
echo -e "Next steps:\n1. Push to Github\n2. Create release on Github: https://github.com/OpenTracksApp/OpenTracks/releases"
|
||||
echo -e "Next steps:\n1. Push to Codeberg\n2. Create release on Codeberg: https://codeberg.org/OpenTracksApp/OpenTracks/releases"
|
||||
+9
-4
@@ -2,12 +2,17 @@
|
||||
|
||||
set -e
|
||||
|
||||
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64/
|
||||
|
||||
JAVA_VERSION=`java --version`
|
||||
if [[ $JAVA_VERSION != "openjdk 17."* ]]; then
|
||||
echo "OpenJDK version should be 17.X"
|
||||
exit -1;
|
||||
if [[ $JAVA_VERSION != "openjdk 21."* ]]; then
|
||||
echo -e "OpenJDK version should be 21.X"
|
||||
fi
|
||||
|
||||
git diff --exit-code || echo -e "\nWARNING WARNING WARNING WARNING WARNING: this branch contains uncommit changes."
|
||||
|
||||
if [[ $(git log "$(git describe --tags --abbrev=0)..HEAD" --no-merges --oneline | wc -l) -gt 0 ]]; then
|
||||
echo -e "No version tag for this commit; please use RELEASE.sh";
|
||||
fi
|
||||
|
||||
RELEASE_STORE_PASSWORD=
|
||||
|
||||
+33
-26
@@ -6,7 +6,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.11.1'
|
||||
classpath 'com.android.tools.build:gradle:9.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ def getVersionName = { ->
|
||||
return 'git describe --tags'.execute().text.trim()
|
||||
}
|
||||
|
||||
def getVersionCode = { ->
|
||||
def getVersionCodeNightly = { ->
|
||||
return Integer.valueOf('git rev-list HEAD --count'.execute().text.trim())
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ android {
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
resValues = true
|
||||
}
|
||||
|
||||
androidResources {
|
||||
@@ -46,8 +47,8 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'de.dennisguse.opentracks'
|
||||
versionCode 6284
|
||||
versionName "v4.22.0"
|
||||
versionCode 6564
|
||||
versionName "v4.25.2"
|
||||
|
||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||
|
||||
@@ -57,6 +58,17 @@ android {
|
||||
testInstrumentationRunner 'de.dennisguse.opentracks.TestRunner'
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
}
|
||||
testOptions {
|
||||
managedDevices {
|
||||
localDevices {
|
||||
mediumPhone {
|
||||
device = "Medium Phone"
|
||||
apiLevel = 35
|
||||
systemImageSource = "aosp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
nightly {
|
||||
if (System.getProperty('nightly_store_file') != null) {
|
||||
@@ -95,41 +107,35 @@ android {
|
||||
nightly {
|
||||
dimension 'version'
|
||||
applicationId 'de.dennisguse.opentracks.nightly'
|
||||
resValue 'string', 'applicationId', 'de.dennisguse.opentracks.nightly'
|
||||
|
||||
versionCode getVersionCodeNightly()
|
||||
versionName getVersionName()
|
||||
base.archivesName = "de.dennisguse.opentracks.nightly_${getVersionCodeNightly()}"
|
||||
|
||||
signingConfig = signingConfigs.nightly
|
||||
}
|
||||
irreproducible {
|
||||
// Non-reproducible: https://f-droid.org/de/packages/de.dennisguse.opentracks/
|
||||
dimension 'version'
|
||||
applicationId 'de.dennisguse.opentracks'
|
||||
resValue 'string', 'applicationId', 'de.dennisguse.opentracks'
|
||||
versionNameSuffix 'irreproducible'
|
||||
}
|
||||
reproducible {
|
||||
// Developer Binaries: https://github.com/OpenTracksApp/OSMDashboard/releases/download/v%v/de.dennisguse.opentracks.playstore_%v.apk
|
||||
// Developer Binaries: https://codeberg.org/OpenTracksApp/OSMDashboard/releases/download/v%v/de.dennisguse.opentracks.playstore_%v.apk
|
||||
// FDroid: https://f-droid.org/de/packages/de.dennisguse.opentracks.playstore
|
||||
// PlayStore: https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore
|
||||
dimension 'version'
|
||||
applicationId 'de.dennisguse.opentracks.playstore'
|
||||
resValue 'string', 'applicationId', 'de.dennisguse.opentracks.playstore'
|
||||
|
||||
base.archivesName = "de.dennisguse.opentracks.playstore_${getVersionName()}_${android.defaultConfig.versionCode}"
|
||||
|
||||
signingConfig = signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
variant.resValue 'string', 'applicationId', variant.applicationId
|
||||
|
||||
variant.outputs.configureEach {
|
||||
if (variant.flavorName == 'nightly') {
|
||||
setVersionCodeOverride(getVersionCode())
|
||||
setVersionNameOverride(getVersionName())
|
||||
}
|
||||
|
||||
if (variant.flavorName == 'reproducible') {
|
||||
outputFileName = "${applicationId}_${variant.versionName}.apk"
|
||||
} else {
|
||||
outputFileName = "${applicationId}_${variant.versionCode}.apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
// Disables dependency metadata when building APKs.
|
||||
includeInApk = false
|
||||
@@ -146,19 +152,20 @@ dependencies {
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'androidx.documentfile:documentfile:1.1.0'
|
||||
implementation 'androidx.gridlayout:gridlayout:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'com.google.android.material:material:1.13.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
|
||||
implementation 'androidx.core:core:1.17.0'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.1'
|
||||
implementation 'androidx.core:core-splashscreen:1.2.0'
|
||||
implementation 'androidx.mediarouter:mediarouter:1.8.1'
|
||||
implementation 'androidx.core:core-location-altitude:1.0.0-alpha03'
|
||||
implementation 'androidx.core:core-location-altitude:1.0.0-beta01'
|
||||
implementation 'androidx.work:work-runtime:2.11.1'
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.7.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.7.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.7.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
|
||||
androidTestImplementation 'org.mockito:mockito-android:5.19.0'
|
||||
androidTestImplementation 'org.mockito:mockito-android:5.21.0'
|
||||
|
||||
androidTestUtil 'androidx.test:orchestrator:1.6.1'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.0: OpenTracks
|
||||
|
||||
Změny:
|
||||
- Přesun na https://codeberg.org/OpenTracksApp/OpenTracks
|
||||
@@ -0,0 +1,17 @@
|
||||
v3.0.1: OpenTracks
|
||||
|
||||
Änderungen:
|
||||
- Markierungen teilen
|
||||
- Umstrukturierte Einstellungen
|
||||
- Zurück-Schaltfläche in der Aktionsleiste entfernt
|
||||
- Export: Option zur Einstellung der Fotogröße entfernt
|
||||
- Export: KML als Format ist jetzt auswählbar
|
||||
|
||||
Fehlerbehebungen:
|
||||
- Exportverzeichnis ist jetzt /OpenTracks/
|
||||
- Querformatmodus stürzt nicht mehr ab
|
||||
- KML/KMZ-Export behoben
|
||||
|
||||
Entwickler:
|
||||
- Tests sind ausführbar (aber viele schlagen fehl)
|
||||
- Kontinuierliche Integration mit TravisCI aktiviert (keine Tests)
|
||||
@@ -0,0 +1,14 @@
|
||||
v3.1.0: OpenTracks
|
||||
|
||||
Änderungen:
|
||||
- Anzeige der Strecke in Karten-Apps hinzugefügt (getestet mit OsmAnd und Maps.ME)
|
||||
- Während der Verfolgung werden Streckenstatistiken angezeigt, ohne das Gerät entsperren zu müssen
|
||||
- Querformat für die Detailansicht der Strecke entfernt (war fehlerhaft)
|
||||
- Verlauf der Suchvorschläge entfernt
|
||||
|
||||
Fehlerbehebung:
|
||||
- Speicherberechtigung für „Alle importieren/Alle exportieren” anfordern
|
||||
|
||||
Entwickler:
|
||||
- Upgrade auf Gradle 5.6
|
||||
- Release-Builds nicht minimieren
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.0: OpenTracks
|
||||
|
||||
Änderungen:
|
||||
- Benutzeroberfläche: Durchschnittsgeschwindigkeit des aktuellen Segments hinzugefügt
|
||||
(derzeit nur in neuen Layouts verfügbar)
|
||||
- Durch Klicken auf die Benachrichtigung wird die eigentliche Aufzeichnungs-Benutzeroberfläche geöffnet
|
||||
|
||||
Entwickler:
|
||||
- Veralteter JobIntentService durch WorkManager ersetzt
|
||||
- Verwende .isEmpty() außer für CharSequence und Stream.toList()
|
||||
@@ -0,0 +1,8 @@
|
||||
v4.23.1: OpenTracks
|
||||
|
||||
Änderungen:
|
||||
|
||||
- Neue UI-Komponente zur Anzeige der verstrichenen Zeit im aktuellen Segment
|
||||
|
||||
Fehlerbehebung:
|
||||
- Sofortiger Export nach Workout abgestürzt (eingeführt in v4.23.0)
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.2: OpenTracks
|
||||
|
||||
Änderungen:
|
||||
- Vorausschauende Rückwärtsfunktion funktioniert vollständig
|
||||
|
||||
Fehlerbehebung:
|
||||
- Absturz im Zusammenhang mit dem Dateinamen der Strecke in den Einstellungen behoben
|
||||
|
||||
Entwickler:
|
||||
- Datenklasse für Statistiken eingeführt
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.1: OpenTracks
|
||||
|
||||
Changes:
|
||||
- First release via Codeberg
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.2: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Voice annoucements setting for time and unit were linked
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.0: OpenTracks
|
||||
|
||||
Changes:
|
||||
- UI: added average pace of current segment
|
||||
(currently only available in new layouts)
|
||||
- Clicking on notification opens actual recording UI
|
||||
|
||||
Developer:
|
||||
- Deprecated JobIntentService replaced with WorkManager
|
||||
- Use .isEmpty() except for CharSequence and Stream.toList()
|
||||
@@ -0,0 +1,7 @@
|
||||
v4.23.1: OpenTracks
|
||||
|
||||
Changes:
|
||||
- New UI component to show elapsed time in the current segment
|
||||
|
||||
Bugfix:
|
||||
- Instant post-workout export crashed (introduced in v4.23.0)
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.2: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Predictive back works completely
|
||||
|
||||
Bugfix:
|
||||
- Fixed in crash related to the track filename in the settings
|
||||
|
||||
Developer:
|
||||
- Introduced data class for Statistics
|
||||
@@ -0,0 +1,15 @@
|
||||
v4.24.0: OpenTracks
|
||||
|
||||
Changes:
|
||||
- PublicAPI: start track only sets field if data is present
|
||||
- Marker photos can be shared again
|
||||
- Removed KMZ without photos
|
||||
- Heart rate of 0.0 is treated as invalid (except for SensorStatistics)
|
||||
- Removed import workaround for special coordinates (100/200)
|
||||
(was used by MyTracks to export/import special trackpoints)
|
||||
|
||||
Developer:
|
||||
- Track and Marker are records
|
||||
- AggregatedStatistics are computed in database
|
||||
- Split into TrackStatisticsUpdater and SegmentStatisticUpdater
|
||||
- Introduced Iterator classes (instead of passing Cursor or List)
|
||||
@@ -0,0 +1,6 @@
|
||||
v4.24.1: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Restore compatibility with OSM Dashboard v6.4.1 and earlier (introduced in v4.24.0)
|
||||
- Crash when using default track name by number (introduced in v4.24.0)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.24.2: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Crash when select all (introduced in v4.24.0)
|
||||
@@ -0,0 +1,13 @@
|
||||
v4.25.0: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Record button is centered
|
||||
- Support for BLE thermometer (Environmental Sensing)
|
||||
|
||||
Bugfix:
|
||||
- On import: get type from filename (not URI)
|
||||
|
||||
Developer:
|
||||
- TrackPoint is a record
|
||||
- Update to Android Gradle Plugin 9.0
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
v4.25.1: OpenTracks
|
||||
|
||||
Bugfix:
|
||||
- Since v4.24.0, the API for transferring data to OSM Dashboard was broken.
|
||||
Sadly, the changes in OpenTracks could not be reverted.
|
||||
Thus, the protocol version was bumped to 3.
|
||||
This requires updating OSM Dashboard to a version AFTER v6.5.7.
|
||||
@@ -0,0 +1,8 @@
|
||||
v4.25.2: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Restored compatibility with OSMDashboard (Dashboard API protocol version 2)
|
||||
|
||||
Bugfix:
|
||||
- Update UI immediately after resuming a track
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.0: OpenTracks
|
||||
|
||||
Athruithe:
|
||||
- Aistriú go https://codeberg.org/OpenTracksApp/OpenTracks
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.2: OpenTracks
|
||||
|
||||
Cambios:
|
||||
- a volta predictiva funciona
|
||||
|
||||
Arranxo:
|
||||
- do fallo que daba relacionado co nome do ficheiro nos axustes
|
||||
|
||||
Desenvolvemento:
|
||||
- Engádese data class para as Estatísticas
|
||||
@@ -4,7 +4,7 @@ Modifiche:
|
||||
- Velocità degli annunci vocali configurabile
|
||||
- API <26: L'icona del lanciatore omette lo sfondo
|
||||
|
||||
Bugfix:
|
||||
Correzioni:
|
||||
- UI di registrazione: mostra i valori corretti
|
||||
- Registrazione UI: mostra (di nuovo) l'altitudine in EGM2008
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.0: OpenTracks
|
||||
|
||||
Modifiche:
|
||||
- Migrazione a https://codeberg.org/OpenTracksApp/OpenTracks
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.1: OpenTracks
|
||||
|
||||
Modifiche:
|
||||
- Primo rilascio da Codeberg
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.2: OpenTracks
|
||||
|
||||
Correzioni:
|
||||
- L'impostazione degli annunci vocali per l'ora e l'unità di misura è stata collegata
|
||||
@@ -0,0 +1,10 @@
|
||||
(versionName): OpenTracks
|
||||
|
||||
Modifiche:
|
||||
-
|
||||
|
||||
Correzioni:
|
||||
-
|
||||
|
||||
Sviluppatore:
|
||||
-
|
||||
@@ -1 +1 @@
|
||||
Un tracker sportivo che rispetta completamente la tua privacy.
|
||||
Un tracker sportivo che rispetta la tua privacy.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
v3.0.0: Opentracks
|
||||
v3.0.0: திறந்தபாதைகள்
|
||||
|
||||
ஓபன்ட்ராக்சின் முதல் வெளியீடு (அதாவது, மைட்ராக்சிலிருந்து ஆர்ட் ஃபோர்க்)
|
||||
திறந்தபாதைகளின் முதல் வெளியீடு (அதாவது, மைட்ராக்சிலிருந்து ஆர்ட் ஃபோர்க்)
|
||||
|
||||
மாற்றங்கள்:
|
||||
- மைட்ராக்சிலிருந்து ஓபன்ட்ராக்சுக்கு மறுபெயரிடப்பட்டது
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.8.0: Opentracks
|
||||
v3.8.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றத்தை உடைத்தல்:
|
||||
- சிபிஎக்ச் இறக்குமதி/ஏற்றுமதி விரைவு, கேடென்ச் மற்றும் ஆர்ட்ரேட் டிராக் பாயிண்ட் எக்ச்டென்சன்/வி 2 வழியாக
|
||||
@@ -6,7 +6,7 @@ v3.8.0: Opentracks
|
||||
மாற்றங்கள்:
|
||||
- டாச்போர்டு ஏபிஐ: குறிப்பான்களுக்கான அணுகலை வழங்குதல் (ஓபன்ட்ராக்சில் காண்பிக்க திரும்பப்பெறுதல்)
|
||||
- புதிய மார்க்கர் படவுரு (ஆரஞ்சு புச் முள், எச்.வி.சி)
|
||||
- இறக்குமதிக்கான கோப்புகளை கோப்பு மேலாளர் வழியாக தேர்ந்தெடுக்கலாம்
|
||||
- இறக்குமதிக்கான கோப்புகளைக் கோப்பு மேலாளர் வழியாகத் தேர்ந்தெடுக்கலாம்
|
||||
|
||||
பிழைத்திருத்தங்கள்:
|
||||
- ஒருங்கிணைந்த புள்ளிவிவரங்கள் இடைமுகம் விருப்பமான விகிதத்தை மதிக்கிறது
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.9.0: Opentracks
|
||||
v3.9.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- தடங்களை அவற்றின் UUID உடன் ஏற்றுமதி செய்யுங்கள்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.12.0: ஓபன்ட்ராக்ச்
|
||||
v3.12.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- ஊடலை சென்சார் முகவரிகள்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.15.0: ஓபன்ட்ராக்ச்
|
||||
v3.15.0: திறந்தபாதைகள்
|
||||
|
||||
எச்சரிக்கை:
|
||||
இந்த வெளியீடு மாற்ற முடியாத தரவுத்தள மாற்றங்களைப் பயன்படுத்துகிறது.
|
||||
@@ -14,7 +14,7 @@ v3.15.0: ஓபன்ட்ராக்ச்
|
||||
(தயவுசெய்து OSMDashboard 2.10.0 ஐ மேம்படுத்தவும்)
|
||||
|
||||
மாற்றங்கள்:
|
||||
- KML/KMZ சரியாக காப்புப் பிரதி எடுக்கவும் மீட்டமைக்கவும் பயன்படுத்தலாம் (புள்ளிவிவரங்கள் உட்பட)
|
||||
- KML/KMZ சரியாகக் காப்புப் பிரதி எடுக்கவும் மீட்டமைக்கவும் பயன்படுத்தலாம் (புள்ளிவிவரங்கள் உட்பட)
|
||||
|
||||
டெவலப்பர்:
|
||||
- மறுவேலை செய்யப்பட்ட தட பிரிவு மற்றும் அது சேமிப்பு (முன்னர் இடைநிறுத்தம்/மீண்டும் மார்க்கர்)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.16.0: ஓபன்ட்ராக்ச்
|
||||
v3.16.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- சைக்கிள் ஓட்டுதல்: பி.எல்.இ வேக சென்சாரிலிருந்து தூரத்தைப் பெறுங்கள்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.17.0: Opentracks
|
||||
v3.17.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- கயாக்கிங்கிற்கு ஐகானைச் சேர்க்கவும்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.18.0: ஓபன்ட்ராக்ச்
|
||||
v3.18.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- உயரம் EGM2008 இல் காட்டப்பட்டுள்ளது (WGS84 எனச் சேமிக்கப்படுகிறது/ஏற்றுமதி செய்யப்படுகிறது)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.18.3: ஓபன்ட்ராக்ச்
|
||||
v3.18.3: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- KML பாகுபடுத்தலுக்கு/GX: KOURS இன் ஆர்டர் தேவையில்லை
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.18.6: Opentracks
|
||||
v3.18.6: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- "வரைபடத்தில் காட்டு"- KMZ க்கு பதிலாக KML வழியாகச் செயல்பாடு
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.19.0: Opentracks
|
||||
v3.19.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- இயங்கும் விரைவு மற்றும் கேடென்ச் (ஆர்.சி.எச்) சென்சார்களுக்கான உதவி செயல்படுத்தப்பட்டது
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.20.2: ஓபன்ட்ராக்ச்
|
||||
v3.20.2: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- மிதவைகளுக்குப் பதிலாக உயரத்தை ஆதாயம் மற்றும் இழப்பு என்பது எண்கள்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.21.0: Opentracks
|
||||
v3.21.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- பதிவு செய்யும்போது: டிராக் பாயிண்டுகளின் செயலற்ற அல்லாத உருவாக்கத்தை அகற்று
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.24.0: Opentracks
|
||||
v3.24.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- சி.பி.எச் விருப்பமானது (உட்புற பயன்பாட்டிற்கும்): தூரத்தை வழங்கும் பி.எல்.இ சென்சார்களைப் பயன்படுத்தினால் பயன்படுத்தப்பட்டால்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v3.24.1: Opentracks
|
||||
v3.24.1: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- பிற பயன்பாடுகளிலிருந்து பதிவுகளைத் தொடங்க பநிஇ சேர்க்கப்பட்டது (இயல்பாக முடக்கப்பட்டுள்ளது)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
V3.27.0: Opentracks
|
||||
V3.27.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- குரல் அன்னியூசென்ச்: 100 மீ, 200 மீ மற்றும் 500 மீ
|
||||
- இடைவெளி: 100 மீ மற்றும் 500 மீ சேர்க்கவும்
|
||||
- இடைவெளி: 100 மீ மற்றும் 500 மீ சேர்
|
||||
- கடிகாரம் இப்போது விநாடிகளையும் காட்டுகிறது
|
||||
- சி.பி.எக்ச், கே.எம்.எல், கே.எம்.இசட்: கிடைமட்ட துல்லியத்தை ஏற்றுமதி செய்து இறக்குமதி செய்க
|
||||
- சி.பி.எக்ச்: கிளச்ட்ரச்ட் நீட்டிப்பு வழியாக ஒட்டுமொத்த தூரத்தை ஏற்றுமதி செய்யுங்கள்
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v4.0.0: Opentracks
|
||||
v4.0.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- கீழ் பயன்பாட்டு பட்டியுடன் இடைமுகம் மறுசீரமைப்பு.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
V4.0.1: Opentracks
|
||||
V4.0.1: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- குரல் அறிவிப்புகள் இப்போது கட்டமைக்கப்படுகின்றன
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
V4.9.0: Opentracks
|
||||
V4.9.0: திறந்தபாதைகள்
|
||||
|
||||
குறிப்பு: மாற்றத்தை உடைத்தல்
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
V4.10.0: Opentracks
|
||||
V4.10.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- BLE சுற்றுச்சூழல் உணர்திறன் (காற்றழுத்தமானி) வழியாக உதவி ஆதாயம்/இழப்பு
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
v4.13.0: ஓபன்ட்ராக்ச்
|
||||
v4.13.0: திறந்தபாதைகள்
|
||||
|
||||
மாற்றங்கள்:
|
||||
- பொது பநிஇ வழியாகக் குறிப்பான்களை உருவாக்க முடியும்
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.0: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- https://codeberg.org/OpenTracksApp/OpenTracks க்கு இடம்பெயர்தல்
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.22.1: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- கோட்பெர்க் வழியாக முதல் வெளியீடு
|
||||
@@ -0,0 +1,3 @@
|
||||
v4.22.2: திறந்தபாதைகள்
|
||||
பிழைத்திருத்தம்:
|
||||
- நேரம் மற்றும் அலகுக்கான குரல் அறிவிப்பு அமைப்பு இணைக்கப்பட்டது
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.0: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- UI: தற்போதைய பிரிவின் சராசரி வேகத்தைச் சேர்த்தது
|
||||
(தற்போது புதிய தளவமைப்புகளில் மட்டுமே கிடைக்கிறது)
|
||||
- அறிவிப்பைக் சொடுக்கு செய்வதன் மூலம் உண்மையான பதிவு இடைமுகம் திறக்கும்
|
||||
|
||||
டெவலப்பர்:
|
||||
- நிராகரிக்கப்பட்ட JobIntentService, WorkManager உடன் மாற்றப்பட்டது
|
||||
- CharSequence மற்றும் Stream.toList() தவிர .isEmpty() ஐப் பயன்படுத்தவும்
|
||||
@@ -0,0 +1,7 @@
|
||||
v4.23.1: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- தற்போதைய பிரிவில் கழிந்த நேரத்தைக் காட்ட புதிய இடைமுகம் கூறு
|
||||
|
||||
பிழைத்திருத்தம்:
|
||||
- உடற்பயிற்சிக்குப் பிந்தைய உடனடி ஏற்றுமதி செயலிழந்தது (v4.23.0 இல் அறிமுகப்படுத்தப்பட்டது)
|
||||
@@ -0,0 +1,10 @@
|
||||
v4.23.2: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- முன்கணிப்பு முற்றிலும் வேலை செய்கிறது
|
||||
|
||||
பிழைத்திருத்தம்:
|
||||
- அமைப்புகளில் டிராக் கோப்புப் பெயருடன் தொடர்புடைய செயலிழப்பில் சரி செய்யப்பட்டது
|
||||
|
||||
டெவலப்பர்:
|
||||
- புள்ளிவிவரங்களுக்கான தரவு வகுப்பு அறிமுகப்படுத்தப்பட்டது
|
||||
@@ -0,0 +1,15 @@
|
||||
v4.24.0: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- PublicAPI: தரவு இருந்தால் ஸ்டார்ட் டிராக் மட்டுமே புலத்தை அமைக்கும்
|
||||
- மார்க்கர் புகைப்படங்களை மீண்டும் பகிரலாம்
|
||||
- புகைப்படங்கள் இல்லாமல் KMZ அகற்றப்பட்டது
|
||||
- இதயத் துடிப்பு 0.0 தவறானதாகக் கருதப்படுகிறது (சென்சார் ஸ்டாடிஸ்டிக்ஸ் தவிர)
|
||||
- சிறப்பு ஒருங்கிணைப்புகளுக்கான இறக்குமதி தீர்வு நீக்கப்பட்டது (100/200)
|
||||
(சிறப்பு டிராக் பாயிண்ட்களை ஏற்றுமதி/இறக்குமதி செய்ய MyTracks பயன்படுத்தியது)
|
||||
|
||||
டெவலப்பர்:
|
||||
- ட்ராக் மற்றும் மார்க்கர் பதிவுகள்
|
||||
- திரட்டப்பட்ட புள்ளிவிவரங்கள் தரவுத்தளத்தில் கணக்கிடப்படுகின்றன
|
||||
- TrackStatisticsUpdater மற்றும் SegmentStatisticUpdater எனப் பிரிக்கவும்
|
||||
- அறிமுகப்படுத்தப்பட்ட இட்டரேட்டர் வகுப்புகள் (கர்சர் அல்லது பட்டியலைக் கடந்து செல்வதற்குப் பதிலாக)
|
||||
@@ -0,0 +1,5 @@
|
||||
v4.24.1: OpenTracks
|
||||
|
||||
பிழைத்திருத்தம்:
|
||||
- OSM டாஷ்போர்டு v6.4.1 மற்றும் அதற்கு முந்தையவற்றுடன் இணக்கத்தன்மையை மீட்டெடுக்கவும் (v4.24.0 இல் அறிமுகப்படுத்தப்பட்டது)
|
||||
- எண்ணின்படி இயல்புநிலை ட்ராக் பெயரைப் பயன்படுத்தும்போது செயலிழக்கிறது (v4.24.0 இல் அறிமுகப்படுத்தப்பட்டது)
|
||||
@@ -0,0 +1,4 @@
|
||||
v4.24.2: OpenTracks
|
||||
|
||||
பிழைத்திருத்தம்:
|
||||
- அனைத்தையும் தேர்ந்தெடுக்கும்போது செயலிழக்க (v4.24.0 இல் அறிமுகப்படுத்தப்பட்டது)
|
||||
@@ -0,0 +1,12 @@
|
||||
v4.25.0: OpenTracks
|
||||
|
||||
மாற்றங்கள்:
|
||||
- பதிவுப் பொத்தான் மையமாக உள்ளது
|
||||
- BLE தெர்மோமீட்டருக்கான ஆதரவு (சுற்றுச்சூழல் உணர்தல்)
|
||||
|
||||
பிழைத்திருத்தம்:
|
||||
- இறக்குமதியில்: கோப்பு பெயரிலிருந்து வகையைப் பெறுங்கள் (URI அல்ல)
|
||||
|
||||
டெவலப்பர்:
|
||||
- TrackPoint ஒரு பதிவு
|
||||
- Android Gradle செருகுநிரல் 9.0 க்கு புதுப்பிக்கவும்
|
||||
@@ -1,22 +1,22 @@
|
||||
一款尊重您的隐私的运动追踪应用。
|
||||
尊重您隐私的运动追踪伙伴。
|
||||
|
||||
健康幸福的生活总少不了各种运动和户外活动。
|
||||
运动与户外活动能带来快乐、提升技能、增强自信。
|
||||
|
||||
使用本应用,您可以保持对您的训练数据的有效追踪,为您的健康助力。
|
||||
本应用可以在您跑步或散步时记录数据,也可以在您骑车时作为一个大屏幕自行车电脑。
|
||||
您可以为路上的有趣位置创建标记,还可以用图片作为标记。
|
||||
您的数据会被详尽地记录下来,供您查阅分析。
|
||||
您的数据只会分享给您想要分享给的人。
|
||||
通过跟踪训练数据,珍视您的健康。
|
||||
记录您的跑步或步行数据,并提供大屏的专用骑行码表。
|
||||
用照片标记沿途有趣的地点。
|
||||
保留详细记录的统计数据以供分析。
|
||||
仅分享您愿意公开的数据。
|
||||
|
||||
* 语音播报
|
||||
* 支持蓝牙LE传感器:心率、速度和距离(骑车)、踏频(骑车)和功率计(骑车)。
|
||||
* 海拔增减:通过气压传感器。
|
||||
* EGM2008 海拔显示(平均海平面以上);导出为 WGS84。
|
||||
* 导出路线数据,支持 KMZ(包括照片)、KML 和 GPX 格式。
|
||||
* 不需要联网,不需要额外权限。
|
||||
* 语音播报。
|
||||
* 支持蓝牙低功耗传感器:心率、速度和距离(骑行)、踏频(骑行)、功率计(骑行)。
|
||||
* 海拔上升和下降:通过气压传感器。
|
||||
* 采用 EGM2008 显示海拔(平均海平面以上);导出为 WGS84。
|
||||
* 以 KMZ(含照片)、KML 或 GPX 格式导出轨迹数据。
|
||||
* 无需互联网访问或额外权限。
|
||||
* 深色和浅色主题,跟随系统设置。
|
||||
* 没有广告。
|
||||
* 无广告。
|
||||
|
||||
本应用是开源软件
|
||||
意味着您可以使用、学习、修改和分发本应用的源代码。
|
||||
本应用使用 Apache 2.0 协议发布。
|
||||
自由软件/开放源代码
|
||||
意味着您可以使用、研究、修改和分享源代码。
|
||||
采用 Apache 2.0 许可
|
||||
|
||||
@@ -1 +1 @@
|
||||
一款尊重您的隐私的运动追踪应用。
|
||||
尊重您隐私的运动追踪伙伴。
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
Vendored
+93
-94
@@ -1,94 +1,93 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||
}
|
||||
@@ -36,7 +36,8 @@ public class EspressoDeleteTrackTest {
|
||||
@Test
|
||||
public void espressoDeleteTrackTest() {
|
||||
// TrackListActivity: start recording
|
||||
onView(withId(R.id.track_list_fab_action)).perform(click());
|
||||
onView(withId(R.id.track_list_fab_action))
|
||||
.perform(click());
|
||||
|
||||
// TrackRecordingActivity
|
||||
onView(withId(R.id.track_recording_fab_action))
|
||||
@@ -46,13 +47,14 @@ public class EspressoDeleteTrackTest {
|
||||
.perform(longClick());
|
||||
|
||||
// TrackStoppedActivity
|
||||
onView(withId(R.id.finish_button)).perform(click());
|
||||
onView(withId(R.id.finish_button))
|
||||
.perform(click());
|
||||
|
||||
// select track
|
||||
onView(allOf(withParent(withId(R.id.track_list)), withParentIndex(0))).perform(longClick());
|
||||
onView(allOf(withParent(withId(R.id.track_list)), withParentIndex(0)))
|
||||
.perform(longClick());
|
||||
|
||||
// open menu and delete selected track
|
||||
//TODO openActionBarOverflowOrOptionsMenu(); doesn't work
|
||||
onView(
|
||||
allOf(withContentDescription("More options"),
|
||||
childAtPosition(
|
||||
@@ -63,9 +65,11 @@ public class EspressoDeleteTrackTest {
|
||||
isDisplayed()))
|
||||
.perform(click());
|
||||
|
||||
onView(withText("Delete")).perform(click());
|
||||
onView(withText("Delete"))
|
||||
.perform(click());
|
||||
|
||||
onView(withText("OK")).perform(click());
|
||||
onView(withText("OK"))
|
||||
.perform(click());
|
||||
|
||||
// tracklist is empty now
|
||||
onView(allOf(withText("Start recording your next adventure here"), isDisplayed()));
|
||||
|
||||
@@ -15,7 +15,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static de.dennisguse.opentracks.util.EspressoUtils.waitFor;
|
||||
|
||||
import androidx.test.espresso.ViewInteraction;
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.LargeTest;
|
||||
@@ -45,41 +44,43 @@ public class EspressoEditTrackRecordingTest {
|
||||
public void espressoEditTrackRecordingTest() {
|
||||
{
|
||||
// TrackListActivity: start recording
|
||||
ViewInteraction fabRecordButton = onView(withId(R.id.track_list_fab_action));
|
||||
fabRecordButton.perform(click());
|
||||
onView(withId(R.id.track_list_fab_action))
|
||||
.perform(click());
|
||||
}
|
||||
{
|
||||
// TrackRecordingActivity
|
||||
ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
|
||||
|
||||
// wait; stay recording
|
||||
trackControllerStopButton.perform(waitFor(4000));
|
||||
onView(withId(R.id.track_recording_fab_action))
|
||||
.perform(waitFor(4000));
|
||||
|
||||
// open menu
|
||||
openContextualActionModeOverflowMenu();
|
||||
|
||||
// Click the item.
|
||||
onView(withText(R.string.menu_edit)).perform(click());
|
||||
onView(withText(R.string.menu_edit))
|
||||
.perform(click());
|
||||
|
||||
// change name for "New Name"
|
||||
ViewInteraction textInputEditText = onView(withId(R.id.track_edit_name));
|
||||
textInputEditText.perform(scrollTo(), replaceText("New Name"));
|
||||
onView(withId(R.id.track_edit_name))
|
||||
.perform(scrollTo(), replaceText("New Name"));
|
||||
|
||||
ViewInteraction textInputEditText2 = onView(allOf(withId(R.id.track_edit_name), withText("New Name"), isDisplayed()));
|
||||
textInputEditText2.perform(closeSoftKeyboard());
|
||||
onView(allOf(withId(R.id.track_edit_name), withText("New Name"), isDisplayed()))
|
||||
.perform(closeSoftKeyboard());
|
||||
|
||||
// save edition
|
||||
ViewInteraction appCompatButton = onView(withId(R.id.track_edit_save));
|
||||
appCompatButton.perform(click());
|
||||
onView(withId(R.id.track_edit_save))
|
||||
.perform(click());
|
||||
|
||||
// stop;
|
||||
trackControllerStopButton.perform(longClick());
|
||||
onView(withId(R.id.track_recording_fab_action))
|
||||
.perform(longClick());
|
||||
|
||||
// it's on track stopped activity and there are two buttons
|
||||
ViewInteraction resumeButton = onView(withId(R.id.resume_button));
|
||||
resumeButton.check(matches(isDisplayed()));
|
||||
ViewInteraction finishButton = onView(withId(R.id.finish_button));
|
||||
finishButton.check(matches(isDisplayed()));
|
||||
onView(withId(R.id.resume_button))
|
||||
.check(matches(isDisplayed()));
|
||||
onView(withId(R.id.finish_button))
|
||||
.check(matches(isDisplayed()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ public class EspressoUITest {
|
||||
public void record_stop_resume_stop_finish() {
|
||||
{
|
||||
// TrackListActivity: start recording
|
||||
ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_list_fab_action));
|
||||
trackControllerRecordButton.perform(click());
|
||||
onView(withId(R.id.track_list_fab_action))
|
||||
.perform(click());
|
||||
}
|
||||
{
|
||||
// TrackRecordingActivity: wait to record some time and then stop
|
||||
@@ -66,13 +66,12 @@ public class EspressoUITest {
|
||||
public void record_move_through_tabs() {
|
||||
{
|
||||
// TrackListActivity: start recording
|
||||
ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_list_fab_action));
|
||||
trackControllerRecordButton.perform(click());
|
||||
onView(withId(R.id.track_list_fab_action))
|
||||
.perform(click());
|
||||
}
|
||||
{
|
||||
// TrackRecordingActivity
|
||||
ViewInteraction tabLayout = onView(withId(R.id.track_detail_activity_tablayout));
|
||||
ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
|
||||
|
||||
tabLayout.perform(selectTabAtIndex(1));
|
||||
tabLayout.perform(waitFor(1000));
|
||||
@@ -87,7 +86,8 @@ public class EspressoUITest {
|
||||
tabLayout.perform(waitFor(1000));
|
||||
|
||||
// stop
|
||||
trackControllerStopButton.perform(longClick());
|
||||
onView(withId(R.id.track_recording_fab_action)).
|
||||
perform(longClick());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package de.dennisguse.opentracks.chart;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ChartPointTest {
|
||||
|
||||
@Test
|
||||
public void create_by_time() {
|
||||
// given
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
statistics.setTotalTime(Duration.ofSeconds(1000));
|
||||
|
||||
// when
|
||||
ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), false, UnitSystem.IMPERIAL_FEET);
|
||||
|
||||
// then
|
||||
assertEquals(1000000, (long) point.timeOrDistance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_by_distance() {
|
||||
// given
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
statistics.setTotalDistance(Distance.of(1000));
|
||||
|
||||
// when
|
||||
ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), true, UnitSystem.METRIC);
|
||||
|
||||
// then
|
||||
assertEquals(1, (long) point.timeOrDistance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_get_altitude_speed_and_pace() {
|
||||
// given
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint()
|
||||
.setAltitude(Altitude.EGM2008.of(50));
|
||||
|
||||
// when
|
||||
ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC);
|
||||
|
||||
// then
|
||||
assertEquals(50, point.altitude(), 0.01);
|
||||
assertEquals(36, point.speed(), 0.01);
|
||||
assertEquals(1.66, point.pace(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_sensorNotAvailable() {
|
||||
// given
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint()
|
||||
.setAltitude(Altitude.EGM2008.of(50));
|
||||
// when
|
||||
ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC);
|
||||
|
||||
// then
|
||||
assertNull(point.heartRate());
|
||||
assertNull(point.cadence());
|
||||
assertNull(point.power());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_sensorAvailable() {
|
||||
// given
|
||||
TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint()
|
||||
.setAltitude(Altitude.EGM2008.of(50))
|
||||
.setHeartRate(100f)
|
||||
.setCadence(101f)
|
||||
.setPower(102f);
|
||||
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
|
||||
// when
|
||||
ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC);
|
||||
|
||||
// then
|
||||
assertEquals(100.0, point.heartRate(), 0.01);
|
||||
assertEquals(101.0, point.cadence(), 0.01);
|
||||
assertEquals(102.0, point.power(), 0.01);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package de.dennisguse.opentracks.chart;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
|
||||
/**
|
||||
* Commons utilities for creating stubs of track, location.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
//TODO Move to ChartPointTest
|
||||
class TrackStubUtils {
|
||||
|
||||
public static final double INITIAL_ALTITUDE = 22;
|
||||
public static final long INITIAL_TIME = 1000L;
|
||||
private static final double INITIAL_LATITUDE = 22;
|
||||
private static final double INITIAL_LONGITUDE = 22;
|
||||
private static final Distance INITIAL_ACCURACY = Distance.of(5);
|
||||
private static final Speed INITIAL_SPEED = Speed.of(10);
|
||||
private static final float INITIAL_BEARING = 3.0f;
|
||||
|
||||
/**
|
||||
* Create a MyTracks location with default values.
|
||||
*
|
||||
* @return a track stub.
|
||||
*/
|
||||
public static TrackPoint createDefaultTrackPoint() {
|
||||
return createDefaultTrackPoint(INITIAL_LATITUDE, INITIAL_LONGITUDE, INITIAL_ALTITUDE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TrackPoint} stub with specified values.
|
||||
*
|
||||
* @return a SensorDataSetLocation stub.
|
||||
*/
|
||||
private static TrackPoint createDefaultTrackPoint(double latitude, double longitude, double altitude) {
|
||||
return new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(INITIAL_TIME),
|
||||
latitude,
|
||||
longitude,
|
||||
INITIAL_ACCURACY,
|
||||
Altitude.WGS84.of(altitude),
|
||||
INITIAL_ACCURACY,
|
||||
INITIAL_BEARING,
|
||||
INITIAL_SPEED
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,28 @@ import android.util.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Power;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
@@ -37,11 +43,15 @@ public class TestDataUtil {
|
||||
* Create a track without any trackPoints.
|
||||
*/
|
||||
public static Track createTrack(Track.Id trackId) {
|
||||
Track track = new Track();
|
||||
track.setId(trackId);
|
||||
track.setName("Test: " + trackId.id());
|
||||
|
||||
return track;
|
||||
return new Track(
|
||||
trackId,
|
||||
UUID.randomUUID(),
|
||||
"Test: " + trackId.id(),
|
||||
"",
|
||||
"",
|
||||
ActivityType.UNKNOWN,
|
||||
ZoneOffset.UTC,
|
||||
Statistics.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,14 +95,10 @@ public class TestDataUtil {
|
||||
createTrackPoint(i, TrackPoint.Type.SEGMENT_END_MANUAL)
|
||||
);
|
||||
|
||||
//TODO Use TrackStatisticsUpdater
|
||||
TrackStatistics stats = new TrackStatistics();
|
||||
stats.setTotalDistance(Distance.of(0));
|
||||
stats.setTotalTime(Duration.ofMillis(0));
|
||||
List<Marker> markers = List.of(
|
||||
new Marker(trackId, trackPoints.get(1), "Marker 1", "Marker description 1", "Marker category 3", "", null),
|
||||
new Marker(trackId, trackPoints.get(4), "Marker 2", "Marker description 2", "Marker category 3", "", null),
|
||||
new Marker(trackId, trackPoints.get(5), "Marker 3", "Marker description 3", "Marker category 3", "", null)
|
||||
new Marker(null, trackId, "Marker 1", "Marker description 1", "Marker typeLocalized 3", trackPoints.get(1).position(), null),
|
||||
new Marker(null, trackId, "Marker 2", "Marker description 2", "Marker typeLocalized 3", trackPoints.get(4).position(), null),
|
||||
new Marker(null, trackId, "Marker 3", "Marker description 3", "Marker typeLocalized 3", trackPoints.get(5).position(), null)
|
||||
);
|
||||
|
||||
return new TrackData(track, trackPoints, markers);
|
||||
@@ -110,8 +116,10 @@ public class TestDataUtil {
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
public static TrackPoint createTrackPoint(int i) {
|
||||
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
public static TrackPoint createTrackPoint(int i, TrackPoint.Type type, AltitudeGainLoss altitudeGainLoss) {
|
||||
return new TrackPoint(
|
||||
null,
|
||||
type,
|
||||
new Position(
|
||||
Instant.ofEpochSecond(i),
|
||||
INITIAL_LATITUDE + (double) i / 10000.0,
|
||||
@@ -121,22 +129,25 @@ public class TestDataUtil {
|
||||
null,
|
||||
null,
|
||||
Speed.of(5f + (i / 10f))
|
||||
));
|
||||
|
||||
trackPoint.setHeartRate(100f + i % 80);
|
||||
trackPoint.setCadence(300f + i);
|
||||
trackPoint.setPower(400f + i);
|
||||
trackPoint.setAltitudeGain(ALTITUDE_GAIN);
|
||||
trackPoint.setAltitudeLoss(ALTITUDE_LOSS);
|
||||
return trackPoint;
|
||||
),
|
||||
null,
|
||||
HeartRate.of(100f + i % 80),
|
||||
null,
|
||||
Cadence.of(300f + i),
|
||||
Power.of(400f + i),
|
||||
altitudeGainLoss
|
||||
);
|
||||
}
|
||||
|
||||
public static TrackPoint createTrackPoint(int i, TrackPoint.Type type) {
|
||||
TrackPoint trackPoint = createTrackPoint(i);
|
||||
trackPoint.setType(type);
|
||||
return trackPoint;
|
||||
return createTrackPoint(i, TrackPoint.Type.TRACKPOINT, new AltitudeGainLoss(ALTITUDE_GAIN, ALTITUDE_LOSS));
|
||||
}
|
||||
|
||||
public static TrackPoint createTrackPoint(int i) {
|
||||
return createTrackPoint(i, TrackPoint.Type.TRACKPOINT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inserts a track with locations into the database.
|
||||
*
|
||||
@@ -145,45 +156,41 @@ public class TestDataUtil {
|
||||
*/
|
||||
public static void insertTrackWithLocations(ContentProviderUtils contentProviderUtils, Track track, List<TrackPoint> trackPoints) {
|
||||
contentProviderUtils.insertTrack(track);
|
||||
contentProviderUtils.bulkInsertTrackPoint(trackPoints, track.getId());
|
||||
contentProviderUtils.bulkInsertTrackPoint(trackPoints, track.id());
|
||||
}
|
||||
|
||||
public static Marker createMarkerWithPhoto(Context context, Track.Id trackId, TrackPoint trackPoint) throws IOException {
|
||||
return createMarkerWithPhoto(context, trackId, trackPoint, "Marker description");
|
||||
}
|
||||
|
||||
public static Marker createMarkerWithPhoto(Context context, Track.Id trackId, TrackPoint trackPoint, String description) throws IOException {
|
||||
File dstFile = new File(MarkerUtils.getImageUrl(context, trackId));
|
||||
dstFile.createNewFile();
|
||||
Uri photoUri = FileUtils.getUriForFile(context, dstFile);
|
||||
|
||||
//TODO Use TrackStatisticsUpdater
|
||||
TrackStatistics stats = new TrackStatistics();
|
||||
stats.setTotalDistance(Distance.of(0));
|
||||
stats.setTotalTime(Duration.ofMillis(0));
|
||||
|
||||
return new Marker(trackId, trackPoint, "Marker name", "Marker description", "Marker category", "", photoUri);
|
||||
return new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"Marker name",
|
||||
description,
|
||||
"Marker typeLocalized",
|
||||
trackPoint.position(),
|
||||
photoUri);
|
||||
}
|
||||
|
||||
public static List<TrackPoint> getTrackPoints(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
||||
while (trackPointIterator.hasNext()) {
|
||||
trackPoints.add(trackPointIterator.next());
|
||||
}
|
||||
trackPointIterator.forEachRemaining(trackPoints::add);
|
||||
return trackPoints;
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<Track.Id, TrackStatistics> buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) {
|
||||
Track dummyTrack = new Track();
|
||||
dummyTrack.setId(new Track.Id(System.currentTimeMillis()));
|
||||
dummyTrack.setName("Dummy Track");
|
||||
contentProviderUtils.insertTrack(dummyTrack);
|
||||
TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater();
|
||||
for (int i = 0; i < numberOfPoints; i++) {
|
||||
TrackPoint tp = TestDataUtil.createTrackPoint(i);
|
||||
contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId());
|
||||
trackStatisticsUpdater.addTrackPoint(tp);
|
||||
public static List<Marker> getMarkers(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
|
||||
try (MarkerIterator trackPointIterator = contentProviderUtils.getMarkerIterator(trackId)) {
|
||||
ArrayList<Marker> markers = new ArrayList<>();
|
||||
trackPointIterator.forEachRemaining(markers::add);
|
||||
return markers;
|
||||
}
|
||||
dummyTrack.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
|
||||
contentProviderUtils.updateTrack(dummyTrack);
|
||||
return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics());
|
||||
}
|
||||
}
|
||||
|
||||
+15
-13
@@ -6,8 +6,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Power;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
|
||||
@@ -20,7 +24,9 @@ public class TestSensorDataUtil {
|
||||
sensorDataList.add(new TestSensorDataUtil.SensorData(time, hr, cadence, power, type));
|
||||
int i = trackPointList.size() + 1;
|
||||
|
||||
TrackPoint tp = new TrackPoint(type,
|
||||
TrackPoint tp = new TrackPoint(
|
||||
null,
|
||||
type,
|
||||
new Position(
|
||||
time,
|
||||
TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0,
|
||||
@@ -30,19 +36,15 @@ public class TestSensorDataUtil {
|
||||
null,
|
||||
null,
|
||||
Speed.of(5f + (i / 10f))
|
||||
)
|
||||
),
|
||||
null,
|
||||
HeartRate.ofOrNull(hr),
|
||||
null,
|
||||
cadence != null ? Cadence.of(cadence) : null,
|
||||
power != null ? Power.of(power) : null,
|
||||
new AltitudeGainLoss(3, 3)
|
||||
);
|
||||
if (hr != null) {
|
||||
tp.setHeartRate(hr);
|
||||
}
|
||||
if (cadence != null) {
|
||||
tp.setCadence(cadence);
|
||||
}
|
||||
if (power != null) {
|
||||
tp.setPower(power);
|
||||
}
|
||||
tp.setAltitudeGain(3f);
|
||||
tp.setAltitudeLoss(3f);
|
||||
|
||||
trackPointList.add(tp);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package de.dennisguse.opentracks.data;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dennisguse.opentracks.data.tables.MarkerColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TracksColumns;
|
||||
|
||||
/**
|
||||
* Tests {@link CustomContentProvider}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class CustomContentProviderTest {
|
||||
|
||||
private CustomContentProvider customContentProvider;
|
||||
private final Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
customContentProvider = new CustomContentProvider() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link CustomContentProvider#onCreate(android.content.Context)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnCreate() {
|
||||
assertTrue(customContentProvider.onCreate(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link CustomContentProvider#getType(Uri)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetType() {
|
||||
assertEquals(TracksColumns.CONTENT_TYPE, customContentProvider.getType(TracksColumns.CONTENT_URI));
|
||||
assertEquals(TracksColumns.CONTENT_ITEMTYPE, customContentProvider.getType(ContentUris.appendId(TracksColumns.CONTENT_URI.buildUpon(), 1).build()));
|
||||
|
||||
assertEquals(TrackPointsColumns.CONTENT_TYPE, customContentProvider.getType(TrackPointsColumns.CONTENT_URI_BY_ID));
|
||||
assertEquals(TrackPointsColumns.CONTENT_ITEMTYPE, customContentProvider.getType(ContentUris.appendId(TrackPointsColumns.CONTENT_URI_BY_TRACKID.buildUpon(), 1).build()));
|
||||
|
||||
assertEquals(MarkerColumns.CONTENT_TYPE, customContentProvider.getType(MarkerColumns.CONTENT_URI));
|
||||
assertEquals(MarkerColumns.CONTENT_ITEMTYPE, customContentProvider.getType(ContentUris.appendId(MarkerColumns.CONTENT_URI.buildUpon(), 1).build()));
|
||||
}
|
||||
}
|
||||
+233
-214
@@ -27,7 +27,6 @@ import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@@ -42,28 +41,35 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TestDataUtil;
|
||||
import de.dennisguse.opentracks.content.data.TestSensorDataUtil;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeExtremities;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.MarkerBuilder;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Power;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackBuilder;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.data.statistics.SensorStatistics;
|
||||
import de.dennisguse.opentracks.data.tables.MarkerColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TracksColumns;
|
||||
import de.dennisguse.opentracks.stats.SensorStatistics;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
@@ -115,24 +121,32 @@ public class CustomContentProviderUtilsTest {
|
||||
private void testIterator(Track.Id trackId, int numPoints) {
|
||||
TrackPoint.Id lastPointId = initializeTrack(trackId, numPoints);
|
||||
List<TrackPoint> locations = new ArrayList<>(numPoints);
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
while (it.hasNext()) {
|
||||
TrackPoint trackPoint = it.next();
|
||||
assertNotNull(trackPoint);
|
||||
locations.add(trackPoint);
|
||||
// Make sure the IDs are returned in the right order.
|
||||
assertEquals(lastPointId.id() - numPoints + locations.size(), trackPoint.getId().id());
|
||||
assertEquals(lastPointId.id() - numPoints + locations.size(), trackPoint.id().id());
|
||||
}
|
||||
assertEquals(numPoints, locations.size());
|
||||
}
|
||||
}
|
||||
|
||||
private TrackPoint.Id initializeTrack(Track.Id id, int numPoints) {
|
||||
Track track = new Track();
|
||||
track.setId(id);
|
||||
track.setName("Test: " + id.id());
|
||||
contentProviderUtils.insertTrack(track);
|
||||
track = contentProviderUtils.getTrack(id);
|
||||
Track createdTrack = new Track(
|
||||
id,
|
||||
UUID.randomUUID(),
|
||||
"Test: " + id,
|
||||
"",
|
||||
"",
|
||||
ActivityType.UNKNOWN,
|
||||
ZoneOffset.UTC,
|
||||
Statistics.DEFAULT);
|
||||
|
||||
contentProviderUtils.insertTrack(createdTrack);
|
||||
|
||||
Track track = contentProviderUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
|
||||
List<TrackPoint> trackPoints = new ArrayList<>(numPoints);
|
||||
@@ -153,10 +167,10 @@ public class CustomContentProviderUtilsTest {
|
||||
// Load all inserted trackPoints.
|
||||
TrackPoint.Id lastPointId = null;
|
||||
int counter = 0;
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, null)) {
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointIterator(id, null)) {
|
||||
while (it.hasNext()) {
|
||||
TrackPoint trackPoint = it.next();
|
||||
lastPointId = trackPoint.getId();
|
||||
lastPointId = trackPoint.id();
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
@@ -194,8 +208,8 @@ public class CustomContentProviderUtilsTest {
|
||||
when(cursorMock.getString(columnIndex)).thenReturn(name);
|
||||
|
||||
Track track = ContentProviderUtils.createTrack(cursorMock);
|
||||
assertEquals(trackId, track.getId());
|
||||
assertEquals(name, track.getName());
|
||||
assertEquals(trackId, track.id());
|
||||
assertEquals(name, track.name());
|
||||
}
|
||||
|
||||
private void assertCount(int trackCount, int trackPointCount, int markerCount) {
|
||||
@@ -220,8 +234,15 @@ public class CustomContentProviderUtilsTest {
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
Marker marker = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
contentProviderUtils.insertMarker(marker);
|
||||
contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
assertCount(1, 10, 1);
|
||||
|
||||
@@ -239,14 +260,14 @@ public class CustomContentProviderUtilsTest {
|
||||
public void testDeleteAllTracks_withMarkerAndPhoto() throws IOException {
|
||||
// Insert track, points and marker with photo at first.
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
TrackPoint trackPoint = getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
contentProviderUtils.insertMarker(marker);
|
||||
|
||||
assertCount(1, 10, 1);
|
||||
assertTrue(marker.hasPhoto());
|
||||
assertNotNull(marker.photoUrl());
|
||||
File dir = FileUtils.getPhotoDir(context, trackId);
|
||||
assertTrue(dir.isDirectory());
|
||||
assertEquals(1, dir.list().length);
|
||||
@@ -276,8 +297,15 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId2, 10);
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId3, 10);
|
||||
|
||||
Marker marker = new Marker(trackId1, contentProviderUtils.getLastValidTrackPoint(trackId2));
|
||||
contentProviderUtils.insertMarker(marker);
|
||||
contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId1,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
getLastValidTrackPoint(trackId1).position(),
|
||||
null
|
||||
));
|
||||
|
||||
assertCount(3, 30, 1);
|
||||
|
||||
@@ -304,19 +332,19 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId3, 10);
|
||||
|
||||
// Insert a marker in tracks trackId and trackId + 1.
|
||||
TrackPoint trackPoint1 = contentProviderUtils.getLastValidTrackPoint(trackId1);
|
||||
TrackPoint trackPoint1 = getLastValidTrackPoint(trackId1);
|
||||
Marker marker1 = TestDataUtil.createMarkerWithPhoto(context, trackId1, trackPoint1);
|
||||
contentProviderUtils.insertMarker(marker1);
|
||||
File dir1 = FileUtils.getPhotoDir(context, trackId1);
|
||||
|
||||
TrackPoint trackPoint2 = contentProviderUtils.getLastValidTrackPoint(trackId2);
|
||||
TrackPoint trackPoint2 = getLastValidTrackPoint(trackId2);
|
||||
Marker marker2 = TestDataUtil.createMarkerWithPhoto(context, trackId2, trackPoint2);
|
||||
contentProviderUtils.insertMarker(marker2);
|
||||
File dir2 = FileUtils.getPhotoDir(context, trackId2);
|
||||
|
||||
// Check.
|
||||
assertCount(3, 30, 2);
|
||||
assertTrue(marker1.hasPhoto());
|
||||
assertNotNull(marker1.photoUrl());
|
||||
assertTrue(dir1.isDirectory());
|
||||
assertEquals(1, dir1.list().length);
|
||||
assertTrue(dir1.exists());
|
||||
@@ -348,7 +376,7 @@ public class CustomContentProviderUtilsTest {
|
||||
|
||||
// then
|
||||
assertEquals(initialTrackNumber + 1, allTracks.size());
|
||||
assertEquals(trackId, allTracks.get(allTracks.size() - 1).getId());
|
||||
assertEquals(trackId, allTracks.get(allTracks.size() - 1).id());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,61 +403,57 @@ public class CustomContentProviderUtilsTest {
|
||||
contentProviderUtils.insertTrack(track);
|
||||
|
||||
// when / then
|
||||
assertNotNull(contentProviderUtils.getTrack(track.getUuid()));
|
||||
assertNotNull(contentProviderUtils.getTrack(track.uuid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ContentProviderUtils#updateTrack(Track)}
|
||||
*/
|
||||
@Test
|
||||
public void testUpdateTrack() {
|
||||
// given
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrack(trackId);
|
||||
TrackBuilder track = new TrackBuilder(TestDataUtil.createTrack(trackId));
|
||||
String nameOld = "name1";
|
||||
String nameNew = "name2";
|
||||
track.setName(nameOld);
|
||||
|
||||
// when / then
|
||||
contentProviderUtils.insertTrack(track);
|
||||
assertEquals(nameOld, contentProviderUtils.getTrack(trackId).getName());
|
||||
contentProviderUtils.insertTrack(track.getTrack());
|
||||
assertEquals(nameOld, contentProviderUtils.getTrack(trackId).name());
|
||||
track.setName(nameNew);
|
||||
contentProviderUtils.updateTrack(track);
|
||||
assertEquals(nameNew, contentProviderUtils.getTrack(trackId).getName());
|
||||
contentProviderUtils.updateTrack(track.getTrack());
|
||||
assertEquals(nameNew, contentProviderUtils.getTrack(trackId).name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ContentProviderUtils#createContentValues(Marker)}.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateContentValues_marker() {
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Pair<Track, List<TrackPoint>> track = TestDataUtil.createTrack(trackId, 10);
|
||||
|
||||
TrackBuilder trackBuilder = new TrackBuilder(track.first);
|
||||
|
||||
// AverageSpeed
|
||||
TrackStatistics statistics = new TrackStatistics();
|
||||
statistics.setStartTime(Instant.ofEpochMilli(1000));
|
||||
statistics.setStopTime(Instant.ofEpochMilli(2500));
|
||||
statistics.setTotalTime(Duration.ofMillis(1500));
|
||||
statistics.setMovingTime(Duration.ofMillis(700));
|
||||
statistics.setTotalDistance(Distance.of(750.0));
|
||||
statistics.setTotalAltitudeGain(50.0f);
|
||||
statistics.setMaxSpeed(Speed.of(60.0));
|
||||
statistics.setMaxAltitude(1250.0);
|
||||
statistics.setMinAltitude(1200.0);
|
||||
trackBuilder.setStatistics(new Statistics(
|
||||
Instant.ofEpochMilli(1000),
|
||||
Instant.ofEpochMilli(2500),
|
||||
Duration.ofMillis(1500),
|
||||
Duration.ofMillis(700),
|
||||
Distance.of(750),
|
||||
Speed.of(60),
|
||||
new AltitudeExtremities(1250, 1200),
|
||||
new AltitudeGainLoss(50, 50),
|
||||
null,
|
||||
null
|
||||
));
|
||||
contentProviderUtils.insertTrack(trackBuilder.getTrack());
|
||||
|
||||
track.first.setTrackStatistics(statistics);
|
||||
contentProviderUtils.insertTrack(track.first);
|
||||
|
||||
Marker marker = new Marker(trackId, track.second.get(0));
|
||||
MarkerBuilder marker = new MarkerBuilder(trackId, track.second.get(0));
|
||||
marker.setDescription(TEST_DESC);
|
||||
contentProviderUtils.insertMarker(marker);
|
||||
contentProviderUtils.insertMarker(marker.getMarker());
|
||||
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(contentResolverMock);
|
||||
|
||||
Marker.Id markerId = new Marker.Id(System.currentTimeMillis());
|
||||
marker.setId(markerId);
|
||||
ContentValues contentValues = contentProviderUtils.createContentValues(marker);
|
||||
ContentValues contentValues = contentProviderUtils.createContentValues(marker.getMarker(), trackId);
|
||||
assertEquals(markerId.id(), contentValues.get(MarkerColumns._ID));
|
||||
assertEquals((int) (TestDataUtil.INITIAL_LONGITUDE * 1000000), contentValues.get(MarkerColumns.LONGITUDE));
|
||||
assertEquals(TEST_DESC, contentValues.get(MarkerColumns.DESCRIPTION));
|
||||
@@ -446,15 +470,18 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert at first.
|
||||
Marker marker1 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
marker1.setDescription(TEST_DESC);
|
||||
contentProviderUtils.insertMarker(marker1);
|
||||
Marker.Id marker1Id = contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
TEST_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
// Check insert was done.
|
||||
assertEquals(contentProviderUtils.getMarkers(trackId).size(), 1);
|
||||
|
||||
// Get marker id that needs to delete.
|
||||
Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1);
|
||||
assertEquals(1, TestDataUtil.getMarkers(contentProviderUtils, trackId).size());
|
||||
|
||||
// Delete
|
||||
contentProviderUtils.deleteMarker(context, marker1Id);
|
||||
@@ -473,18 +500,18 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert at first.
|
||||
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
TrackPoint trackPoint = getLastValidTrackPoint(trackId);
|
||||
Marker marker1 = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
contentProviderUtils.insertMarker(marker1);
|
||||
|
||||
// Check insert was done.
|
||||
assertEquals(contentProviderUtils.getMarkers(trackId).size(), 1);
|
||||
assertEquals(1, TestDataUtil.getMarkers(contentProviderUtils, trackId).size());
|
||||
|
||||
// Get marker id that needs to delete.
|
||||
Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1);
|
||||
|
||||
// Check marker has photo and it's in the external storage.
|
||||
assertTrue(marker1.hasPhoto());
|
||||
assertNotNull(marker1.photoUrl());
|
||||
File dir = FileUtils.getPhotoDir(context, trackId);
|
||||
assertTrue(dir.isDirectory());
|
||||
assertEquals(1, dir.list().length);
|
||||
@@ -523,20 +550,31 @@ public class CustomContentProviderUtilsTest {
|
||||
// TestDataUtil.insertTrackWithLocations(contentProviderUtils, track);
|
||||
|
||||
// Insert at first.
|
||||
Marker marker1 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
marker1.setDescription(MOCK_DESC);
|
||||
Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1);
|
||||
|
||||
Marker marker2 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
marker2.setDescription(MOCK_DESC);
|
||||
Marker.Id marker2Id = contentProviderUtils.insertMarker(marker2);
|
||||
Marker.Id marker1Id = contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
MOCK_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
Marker.Id marker2Id = contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
MOCK_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
// Delete
|
||||
assertNotNull(contentProviderUtils.getMarker(marker1Id));
|
||||
contentProviderUtils.deleteMarker(context, marker1Id);
|
||||
assertNull(contentProviderUtils.getMarker(marker1Id));
|
||||
|
||||
assertEquals(MOCK_DESC, contentProviderUtils.getMarker(marker2Id).getDescription());
|
||||
assertEquals(MOCK_DESC, contentProviderUtils.getMarker(marker2Id).description());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -547,14 +585,17 @@ public class CustomContentProviderUtilsTest {
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
Marker marker1 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
Marker marker2 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
Marker marker3 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
Marker marker4 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
contentProviderUtils.insertMarker(marker1);
|
||||
contentProviderUtils.insertMarker(marker2);
|
||||
contentProviderUtils.insertMarker(marker3);
|
||||
contentProviderUtils.insertMarker(marker4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
contentProviderUtils.insertMarker(new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
MOCK_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
assertEquals(Integer.valueOf(4), contentProviderUtils.getNextMarkerNumber(trackId));
|
||||
}
|
||||
@@ -568,11 +609,18 @@ public class CustomContentProviderUtilsTest {
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
Marker marker = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
marker.setDescription(TEST_DESC);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(marker);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
TEST_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
assertEquals(TEST_DESC, contentProviderUtils.getMarker(markerId).getDescription());
|
||||
assertEquals(TEST_DESC, contentProviderUtils.getMarker(markerId).description());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,16 +632,29 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert at first.
|
||||
Marker marker = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId));
|
||||
marker.setDescription(TEST_DESC);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(marker);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"",
|
||||
TEST_DESC,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
// Update
|
||||
marker = contentProviderUtils.getMarker(markerId);
|
||||
marker.setDescription(TEST_DESC_NEW);
|
||||
contentProviderUtils.updateMarker(context, marker);
|
||||
contentProviderUtils.updateMarker(context, new Marker(
|
||||
markerId,
|
||||
trackId,
|
||||
"",
|
||||
TEST_DESC_NEW,
|
||||
"",
|
||||
getLastValidTrackPoint(trackId).position(),
|
||||
null
|
||||
));
|
||||
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).getDescription());
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).description());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,10 +668,8 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert at first.
|
||||
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
marker.setDescription(TEST_DESC);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(marker);
|
||||
TrackPoint trackPoint = getLastValidTrackPoint(trackId);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint, TEST_DESC));
|
||||
|
||||
File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.id());
|
||||
assertTrue(dir.exists());
|
||||
@@ -618,14 +677,13 @@ public class CustomContentProviderUtilsTest {
|
||||
assertEquals(1, dir.list().length);
|
||||
|
||||
// Update
|
||||
marker = contentProviderUtils.getMarker(markerId);
|
||||
MarkerBuilder marker = new MarkerBuilder(contentProviderUtils.getMarker(markerId));
|
||||
marker.setName(TEST_NAME_NEW);
|
||||
marker.setDescription(TEST_DESC_NEW);
|
||||
contentProviderUtils.updateMarker(context, marker);
|
||||
contentProviderUtils.updateMarker(context, marker.getMarker());
|
||||
|
||||
assertEquals(TEST_NAME_NEW, contentProviderUtils.getMarker(markerId).getName());
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).getDescription());
|
||||
assertTrue(marker.hasPhoto());
|
||||
assertEquals(TEST_NAME_NEW, contentProviderUtils.getMarker(markerId).name());
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).description());
|
||||
assertTrue(dir.exists());
|
||||
assertTrue(dir.isDirectory());
|
||||
assertEquals(1, dir.list().length);
|
||||
@@ -642,9 +700,8 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert at first.
|
||||
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
marker.setDescription(TEST_DESC);
|
||||
TrackPoint trackPoint = getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint, TEST_DESC);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(marker);
|
||||
|
||||
File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.id());
|
||||
@@ -653,15 +710,14 @@ public class CustomContentProviderUtilsTest {
|
||||
assertEquals(1, dir.list().length);
|
||||
|
||||
// Update
|
||||
marker = contentProviderUtils.getMarker(markerId);
|
||||
marker.setName(TEST_NAME_NEW);
|
||||
marker.setDescription(TEST_DESC_NEW);
|
||||
marker.setPhotoUrl(null);
|
||||
contentProviderUtils.updateMarker(context, marker);
|
||||
MarkerBuilder markerBuilder = new MarkerBuilder(contentProviderUtils.getMarker(markerId));
|
||||
markerBuilder.setName(TEST_NAME_NEW);
|
||||
markerBuilder.setDescription(TEST_DESC_NEW);
|
||||
markerBuilder.setPhotoUrl(null);
|
||||
contentProviderUtils.updateMarker(context, markerBuilder.getMarker());
|
||||
|
||||
assertEquals(TEST_NAME_NEW, contentProviderUtils.getMarker(markerId).getName());
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).getDescription());
|
||||
assertFalse(marker.hasPhoto());
|
||||
assertEquals(TEST_NAME_NEW, contentProviderUtils.getMarker(markerId).name());
|
||||
assertEquals(TEST_DESC_NEW, contentProviderUtils.getMarker(markerId).description());
|
||||
assertFalse(dir.exists());
|
||||
}
|
||||
|
||||
@@ -676,11 +732,9 @@ public class CustomContentProviderUtilsTest {
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
// Insert two markers with photos.
|
||||
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
marker.setDescription(TEST_DESC);
|
||||
Marker otherMarker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint);
|
||||
otherMarker.setDescription(TEST_DESC);
|
||||
TrackPoint trackPoint = getLastValidTrackPoint(trackId);
|
||||
Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint, TEST_DESC);
|
||||
Marker otherMarker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint, TEST_DESC);
|
||||
Marker.Id markerId = contentProviderUtils.insertMarker(marker);
|
||||
contentProviderUtils.insertMarker(otherMarker);
|
||||
|
||||
@@ -690,12 +744,14 @@ public class CustomContentProviderUtilsTest {
|
||||
assertEquals(2, dir.list().length);
|
||||
|
||||
// Update one marker deleting photo.
|
||||
marker = contentProviderUtils.getMarker(markerId);
|
||||
marker.setPhotoUrl(null);
|
||||
contentProviderUtils.updateMarker(context, marker);
|
||||
MarkerBuilder markerBuilder = new MarkerBuilder(contentProviderUtils.getMarker(markerId));
|
||||
markerBuilder.setPhotoUrl(null);
|
||||
contentProviderUtils.updateMarker(context, markerBuilder.getMarker());
|
||||
|
||||
assertEquals(TEST_DESC, contentProviderUtils.getMarker(markerId).getDescription());
|
||||
assertFalse(marker.hasPhoto());
|
||||
// then
|
||||
marker = contentProviderUtils.getMarker(markerId);
|
||||
assertEquals(TEST_DESC, contentProviderUtils.getMarker(markerId).description());
|
||||
assertNull(marker.photoUrl());
|
||||
assertTrue(dir.exists());
|
||||
assertTrue(dir.isDirectory());
|
||||
assertEquals(1, dir.list().length);
|
||||
@@ -726,50 +782,6 @@ public class CustomContentProviderUtilsTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ContentProviderUtils#createTrackPoint(Cursor)}.
|
||||
*/
|
||||
//TODO incomplete
|
||||
@Test
|
||||
public void testCreateTrackPoint() {
|
||||
// given
|
||||
when(cursorMock.getColumnIndex(TrackPointsColumns._ID)).thenReturn(1);
|
||||
|
||||
when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE)).thenReturn(2);
|
||||
when(cursorMock.isNull(2)).thenReturn(false);
|
||||
int longitude = 11;
|
||||
when(cursorMock.getInt(2)).thenReturn(longitude * 1000000);
|
||||
|
||||
when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE)).thenReturn(3);
|
||||
when(cursorMock.isNull(3)).thenReturn(false);
|
||||
int latitude = 22;
|
||||
when(cursorMock.getInt(3)).thenReturn(latitude * 1000000);
|
||||
|
||||
when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.TIME)).thenReturn(4);
|
||||
when(cursorMock.isNull(4)).thenReturn(false);
|
||||
long time = System.currentTimeMillis();
|
||||
when(cursorMock.getLong(4)).thenReturn(time);
|
||||
|
||||
when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.SPEED)).thenReturn(5);
|
||||
when(cursorMock.isNull(5)).thenReturn(false);
|
||||
float speed = 2.2f;
|
||||
when(cursorMock.getFloat(5)).thenReturn(speed);
|
||||
|
||||
when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_HEARTRATE)).thenReturn(6);
|
||||
when(cursorMock.isNull(6)).thenReturn(false);
|
||||
when(cursorMock.getFloat(6)).thenReturn(75f);
|
||||
|
||||
// when
|
||||
TrackPoint trackPoint = contentProviderUtils.createTrackPoint(cursorMock);
|
||||
|
||||
// then
|
||||
assertEquals(latitude, trackPoint.getPosition().latitude(), 0.01);
|
||||
assertEquals(longitude, trackPoint.getPosition().longitude(), 0.01);
|
||||
assertEquals(time, trackPoint.getTime().toEpochMilli());
|
||||
assertEquals(speed, trackPoint.getSpeed().toMPS(), 0.01);
|
||||
assertEquals(HeartRate.of(75f), trackPoint.getHeartRate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link ContentProviderUtils#insertTrackPoint(TrackPoint, Track.Id)}.
|
||||
@@ -778,7 +790,7 @@ public class CustomContentProviderUtilsTest {
|
||||
public void testInsertTrackPoint() {
|
||||
// Insert track, point at first.
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
contentProviderUtils.insertTrackPoint(TestDataUtil.createTrackPoint(22), trackId);
|
||||
// when
|
||||
@@ -792,35 +804,29 @@ public class CustomContentProviderUtilsTest {
|
||||
public void testInsertAndLoadTrackPoint() {
|
||||
// given
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
TrackPoint trackPoint = TestDataUtil.createTrackPoint(5);
|
||||
trackPoint.setHeartRate(1F);
|
||||
trackPoint.setCadence(2F);
|
||||
trackPoint.setPower(3F);
|
||||
TrackPoint trackPoint = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
TestDataUtil.createTrackPoint(5).position(),
|
||||
null,
|
||||
HeartRate.of(1),
|
||||
null,
|
||||
Cadence.of(2),
|
||||
Power.of(3),
|
||||
null
|
||||
);
|
||||
|
||||
// when
|
||||
contentProviderUtils.insertTrackPoint(trackPoint, trackId);
|
||||
|
||||
// then
|
||||
List<TrackPoint> trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId);
|
||||
assertTrue(trackPoints.get(10).hasHeartRate());
|
||||
assertEquals(trackPoint.getHeartRate(), trackPoints.get(10).getHeartRate());
|
||||
assertEquals(trackPoint.getCadence(), trackPoints.get(10).getCadence());
|
||||
assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ContentProviderUtils#getLastValidTrackPoint(Track.Id)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetLastValidTrackPoint() {
|
||||
// Insert track, points at first.
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||
|
||||
TrackPoint lastTrackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||
checkLocation(9, lastTrackPoint.getLocation());
|
||||
assertNotNull(trackPoints.get(10).heartRate());
|
||||
assertEquals(trackPoint.heartRate(), trackPoints.get(10).heartRate());
|
||||
assertEquals(trackPoint.cadence(), trackPoints.get(10).cadence());
|
||||
assertEquals(trackPoint.power(), trackPoints.get(10).power());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -831,8 +837,8 @@ public class CustomContentProviderUtilsTest {
|
||||
contentProviderUtils.insertTrack(track.first);
|
||||
|
||||
List<TrackPoint.Id> trackpointIds = track.second.stream()
|
||||
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.getId())))
|
||||
.map(TrackPoint.Id::new).collect(Collectors.toList());
|
||||
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.id())))
|
||||
.map(TrackPoint.Id::new).toList();
|
||||
|
||||
// when
|
||||
try (Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds.get(8))) {
|
||||
@@ -842,45 +848,36 @@ public class CustomContentProviderUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTrackPointLocationIterator_asc() {
|
||||
public void testGetTrackPointIterator_asc() {
|
||||
// given
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Pair<Track, List<TrackPoint>> track = TestDataUtil.createTrack(trackId, 10);
|
||||
contentProviderUtils.insertTrack(track.first);
|
||||
|
||||
List<TrackPoint.Id> trackpointIds = track.second.stream()
|
||||
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.getId())))
|
||||
.map(TrackPoint.Id::new).collect(Collectors.toList());
|
||||
.map(it -> ContentUris.parseId(contentProviderUtils.insertTrackPoint(it, track.first.id())))
|
||||
.map(TrackPoint.Id::new).toList();
|
||||
|
||||
TrackPoint.Id startTrackPointId = trackpointIds.get(0);
|
||||
|
||||
// when
|
||||
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, trackpointIds.get(0));
|
||||
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, trackpointIds.get(0));
|
||||
|
||||
// then
|
||||
for (int i = 0; i < trackpointIds.size(); i++) {
|
||||
assertTrue(trackPointIterator.hasNext());
|
||||
TrackPoint trackPoint = trackPointIterator.next();
|
||||
assertEquals(startTrackPointId.id() + i, trackPoint.getId().id());
|
||||
assertEquals(startTrackPointId.id() + i, trackPoint.id().id());
|
||||
|
||||
checkLocation(i, trackPoint.getLocation());
|
||||
Position position = trackPoint.position();
|
||||
assertEquals(TestDataUtil.INITIAL_LATITUDE + i / 10000.0, position.latitude(), 0.01);
|
||||
assertEquals(TestDataUtil.INITIAL_LONGITUDE - i / 10000.0, position.longitude(), 0.01);
|
||||
assertEquals(i / 100.0, position.horizontalAccuracy().distance_m(), 0.01);
|
||||
assertEquals(i * TestDataUtil.ALTITUDE_INTERVAL, position.altitude().toM(), 0.01);
|
||||
}
|
||||
assertFalse(trackPointIterator.hasNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the value of a location.
|
||||
*
|
||||
* @param i the index of this location which created in the method {@link TestDataUtil#createTrack(Track.Id, int)}
|
||||
* @param location the location to be checked
|
||||
*/
|
||||
private void checkLocation(int i, Location location) {
|
||||
assertEquals(TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0, location.getLatitude(), 0.01);
|
||||
assertEquals(TestDataUtil.INITIAL_LONGITUDE - (double) i / 10000.0, location.getLongitude(), 0.01);
|
||||
assertEquals((float) i / 100.0f, location.getAccuracy(), 0.01);
|
||||
assertEquals(i * TestDataUtil.ALTITUDE_INTERVAL, location.getAltitude(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatIdListForUri() {
|
||||
assertEquals("", ContentProviderUtils.formatIdListForUri());
|
||||
@@ -892,11 +889,18 @@ public class CustomContentProviderUtilsTest {
|
||||
public void testGetSensorStats_noSensorData() {
|
||||
// given
|
||||
List<TrackPoint> trackPointList = new ArrayList<>();
|
||||
TrackPoint trackPoint = TestDataUtil.createTrackPoint(1);
|
||||
trackPoint.setType(TrackPoint.Type.TRACKPOINT);
|
||||
trackPoint.setPower(null);
|
||||
trackPoint.setCadence(null);
|
||||
trackPoint.setHeartRate(null);
|
||||
TrackPoint trackPoint = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
TestDataUtil.createTrackPoint(1).position(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
trackPointList.add(trackPoint);
|
||||
Track.Id trackId = new Track.Id(System.currentTimeMillis());
|
||||
Track track = TestDataUtil.createTrack(trackId);
|
||||
@@ -1220,4 +1224,19 @@ public class CustomContentProviderUtilsTest {
|
||||
public void testGetSensorStats_withSeveralRandomStartSegments() {
|
||||
testGetSensorStats_randomData(5000, true);
|
||||
}
|
||||
|
||||
private TrackPoint getLastValidTrackPoint(Track.Id trackId) {
|
||||
try (TrackPointIterator trackPointsCursor = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
List<TrackPoint> trackpoints = new ArrayList<>();
|
||||
while (trackPointsCursor.hasNext())
|
||||
trackpoints.add(trackPointsCursor.next());
|
||||
trackpoints = trackpoints.reversed();
|
||||
|
||||
return trackpoints.reversed()
|
||||
.stream()
|
||||
.filter(it -> List.of(TrackPoint.Type.TRACKPOINT, TrackPoint.Type.SEGMENT_START_AUTOMATIC).contains(it.type()))
|
||||
.findFirst().orElseThrow();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-33
@@ -48,10 +48,8 @@ public class CustomSQLiteOpenHelperTest {
|
||||
public static Map<String, String> getSQL(SQLiteDatabase db, String type) {
|
||||
HashMap<String, String> sqlMap = new HashMap<>();
|
||||
try (Cursor cursor = db.query("sqlite_master", new String[]{"name", "SQL"}, "type=?", new String[]{type}, null, null, "name")) {
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
sqlMap.put(cursor.getString(0), cursor.getString(1));
|
||||
}
|
||||
while (cursor.moveToNext()) {
|
||||
sqlMap.put(cursor.getString(0), cursor.getString(1));
|
||||
}
|
||||
}
|
||||
return sqlMap;
|
||||
@@ -64,12 +62,10 @@ public class CustomSQLiteOpenHelperTest {
|
||||
*/
|
||||
private static boolean hasSqlCreate(SQLiteDatabase db, String sqlCreate) {
|
||||
try (Cursor cursor = db.rawQuery("SELECT SQL FROM sqlite_master", null)) {
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
String sql = cursor.getString(0);
|
||||
if (sqlCreate.equals(sql)) {
|
||||
return true;
|
||||
}
|
||||
while (cursor.moveToNext()) {
|
||||
String sql = cursor.getString(0);
|
||||
if (sqlCreate.equals(sql)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,18 +100,18 @@ public class CustomSQLiteOpenHelperTest {
|
||||
// Open database with SQL upgrade
|
||||
Map<String, String> tableByUpgrade;
|
||||
Map<String, String> indicesByUpgrade;
|
||||
try (SQLiteDatabase dbUpgraded = new CustomSQLiteOpenHelper(context, DATABASE_NAME).getReadableDatabase()) {
|
||||
tableByUpgrade = getSQL(dbUpgraded, "table");
|
||||
indicesByUpgrade = getSQL(dbUpgraded, "index");
|
||||
try (CustomSQLiteOpenHelper dbUpgraded = new CustomSQLiteOpenHelper(context, DATABASE_NAME)) {
|
||||
tableByUpgrade = getSQL(dbUpgraded.getReadableDatabase(), "table");
|
||||
indicesByUpgrade = getSQL(dbUpgraded.getReadableDatabase(), "index");
|
||||
}
|
||||
context.deleteDatabase(DATABASE_NAME);
|
||||
|
||||
// Open database via creation script
|
||||
Map<String, String> tablesByCreate;
|
||||
Map<String, String> indicesByCreate;
|
||||
try (SQLiteDatabase dbCreated = new CustomSQLiteOpenHelper(context, DATABASE_NAME).getReadableDatabase()) {
|
||||
tablesByCreate = getSQL(dbCreated, "table");
|
||||
indicesByCreate = getSQL(dbCreated, "index");
|
||||
try (CustomSQLiteOpenHelper dbCreated = new CustomSQLiteOpenHelper(context, DATABASE_NAME)) {
|
||||
tablesByCreate = getSQL(dbCreated.getReadableDatabase(), "table");
|
||||
indicesByCreate = getSQL(dbCreated.getReadableDatabase(), "index");
|
||||
}
|
||||
|
||||
|
||||
@@ -138,14 +134,16 @@ public class CustomSQLiteOpenHelperTest {
|
||||
@Test
|
||||
public void onDowngrade_ToVersion23() {
|
||||
// Create most recent database schema
|
||||
new CustomSQLiteOpenHelper(context, DATABASE_NAME).getReadableDatabase().close();
|
||||
try(CustomSQLiteOpenHelper db = new CustomSQLiteOpenHelper(context, DATABASE_NAME)) {
|
||||
db.getReadableDatabase();
|
||||
}
|
||||
|
||||
// Downgrade schema to version 23 (base version)
|
||||
Map<String, String> tablesByDowngrade;
|
||||
Map<String, String> indicesByDowngrade;
|
||||
try (SQLiteDatabase db = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 23).getReadableDatabase()) {
|
||||
tablesByDowngrade = getSQL(db, "table");
|
||||
indicesByDowngrade = getSQL(db, "index");
|
||||
try (CustomSQLiteOpenHelper db = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 23)) {
|
||||
tablesByDowngrade = getSQL(db.getReadableDatabase(), "table");
|
||||
indicesByDowngrade = getSQL(db.getReadableDatabase(), "index");
|
||||
}
|
||||
|
||||
// then - verify table structure
|
||||
@@ -159,9 +157,9 @@ public class CustomSQLiteOpenHelperTest {
|
||||
|
||||
@Test
|
||||
public void track_uuid_unique() {
|
||||
try (SQLiteDatabase db = new CustomSQLiteOpenHelper(context, DATABASE_NAME).getWritableDatabase()) {
|
||||
db.execSQL("INSERT INTO tracks (uuid) VALUES (0x00)");
|
||||
db.execSQL("INSERT INTO tracks (uuid) VALUES (0x00)");
|
||||
try (CustomSQLiteOpenHelper db = new CustomSQLiteOpenHelper(context, DATABASE_NAME)) {
|
||||
db.getWritableDatabase().execSQL("INSERT INTO tracks (uuid) VALUES (0x00)");
|
||||
db.getWritableDatabase().execSQL("INSERT INTO tracks (uuid) VALUES (0x00)");
|
||||
fail("unique constraint not enforced");
|
||||
} catch (SQLiteConstraintException e) {
|
||||
assertTrue(e.getMessage().contains("UNIQUE constraint failed: tracks.uuid"));
|
||||
@@ -172,7 +170,8 @@ public class CustomSQLiteOpenHelperTest {
|
||||
public void upgrade_data_to_30() {
|
||||
// given: a track in version 29
|
||||
createVersion23();
|
||||
try (SQLiteDatabase db29 = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 29).getWritableDatabase()) {
|
||||
try (CustomSQLiteOpenHelper db = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 29)) {
|
||||
SQLiteDatabase db29 = db.getWritableDatabase();
|
||||
db29.beginTransaction();
|
||||
db29.execSQL("INSERT INTO tracks (_id) VALUES (1)");
|
||||
|
||||
@@ -205,7 +204,8 @@ public class CustomSQLiteOpenHelperTest {
|
||||
}
|
||||
|
||||
// when / then
|
||||
try (SQLiteDatabase db30 = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 30).getWritableDatabase()) {
|
||||
try (CustomSQLiteOpenHelper db = new CustomSQLiteOpenHelper(context, DATABASE_NAME, 30)) {
|
||||
SQLiteDatabase db30 = db.getWritableDatabase();
|
||||
{
|
||||
// Track 1
|
||||
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
||||
@@ -265,7 +265,7 @@ public class CustomSQLiteOpenHelperTest {
|
||||
|
||||
private void createVersion23() {
|
||||
// Manually create database schema with version 23 (base version)
|
||||
SQLiteDatabase dbBase = new SQLiteOpenHelper(context, DATABASE_NAME, null, 23) {
|
||||
try(SQLiteOpenHelper dbBase = new SQLiteOpenHelper(context, DATABASE_NAME, null, 23) {
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
}
|
||||
@@ -273,12 +273,10 @@ public class CustomSQLiteOpenHelperTest {
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
}
|
||||
}.getWritableDatabase();
|
||||
|
||||
dbBase.execSQL(TRACKS_CREATE_TABLE_V23);
|
||||
dbBase.execSQL(TRACKPOINTS_CREATE_TABLE_V23);
|
||||
dbBase.execSQL(WAYPOINTS_CREATE_TABLE_V23);
|
||||
|
||||
dbBase.close();
|
||||
}) {
|
||||
dbBase.getWritableDatabase().execSQL(TRACKS_CREATE_TABLE_V23);
|
||||
dbBase.getWritableDatabase().execSQL(TRACKPOINTS_CREATE_TABLE_V23);
|
||||
dbBase.getWritableDatabase().execSQL(WAYPOINTS_CREATE_TABLE_V23);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
|
||||
@@ -20,7 +21,7 @@ public class TrackSelectionTest extends TestCase {
|
||||
TrackSelection filter = new TrackSelection();
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertNull(selection.selection());
|
||||
@@ -34,12 +35,11 @@ public class TrackSelectionTest extends TestCase {
|
||||
TrackSelection filter = new TrackSelection().addTrackId(trackId);
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "_id IN (?)");
|
||||
assertEquals(selection.selectionArgs().length, 1);
|
||||
assertEquals(selection.selectionArgs()[0], "1");
|
||||
assertEquals("_id IN (?)", selection.selection());
|
||||
assertEquals(List.of("1"), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,28 +54,24 @@ public class TrackSelectionTest extends TestCase {
|
||||
.addTrackId(trackId3);
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "_id IN (?,?,?)");
|
||||
assertEquals(selection.selectionArgs().length, 3);
|
||||
assertEquals(selection.selectionArgs()[0], "1");
|
||||
assertEquals(selection.selectionArgs()[1], "2");
|
||||
assertEquals(selection.selectionArgs()[2], "3");
|
||||
assertEquals("_id IN (?,?,?)", selection.selection());
|
||||
assertEquals(List.of("1", "2", "3"), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterBuildSelection_onlyOneCategory() {
|
||||
public void testFilterBuildSelection_onlyOneactivity_type_localized() {
|
||||
// given
|
||||
TrackSelection filter = new TrackSelection().addActivityType("running");
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "category IN (?)");
|
||||
assertEquals(selection.selectionArgs().length, 1);
|
||||
assertEquals(selection.selectionArgs()[0], "running");
|
||||
assertEquals("activity_type_localized IN (?)", selection.selection());
|
||||
assertEquals(List.of("running"), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,15 +84,11 @@ public class TrackSelectionTest extends TestCase {
|
||||
.addActivityType("trail walking");
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "category IN (?,?,?,?)");
|
||||
assertEquals(selection.selectionArgs().length, 4);
|
||||
assertEquals(selection.selectionArgs()[0], "running");
|
||||
assertEquals(selection.selectionArgs()[1], "road biking");
|
||||
assertEquals(selection.selectionArgs()[2], "mountain biking");
|
||||
assertEquals(selection.selectionArgs()[3], "trail walking");
|
||||
assertEquals("activity_type_localized IN (?,?,?,?)", selection.selection());
|
||||
assertEquals(List.of("running", "road biking", "mountain biking", "trail walking"), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,9 +101,9 @@ public class TrackSelectionTest extends TestCase {
|
||||
TrackSelection filterOk = new TrackSelection().addDateRange(instant, instant.plus(Duration.ofDays(1)));
|
||||
|
||||
// when
|
||||
SelectionData selectionWrong1 = filterWrong1.buildSelection();
|
||||
SelectionData selectionWrong2 = filterWrong2.buildSelection();
|
||||
SelectionData selectionOk = filterOk.buildSelection();
|
||||
ContentProviderUtils.SelectionData selectionWrong1 = filterWrong1.buildSelection();
|
||||
ContentProviderUtils.SelectionData selectionWrong2 = filterWrong2.buildSelection();
|
||||
ContentProviderUtils.SelectionData selectionOk = filterOk.buildSelection();
|
||||
|
||||
// Then
|
||||
assertNull(selectionWrong1.selection());
|
||||
@@ -120,10 +112,8 @@ public class TrackSelectionTest extends TestCase {
|
||||
assertNull(selectionWrong2.selection());
|
||||
assertNull(selectionWrong2.selectionArgs());
|
||||
|
||||
assertEquals(selectionOk.selection(), "starttime BETWEEN ? AND ?");
|
||||
assertEquals(selectionOk.selectionArgs().length, 2);
|
||||
assertEquals(selectionOk.selectionArgs()[0], Long.toString(instant.toEpochMilli()));
|
||||
assertEquals(selectionOk.selectionArgs()[1], Long.toString(instant.toEpochMilli() + oneDay));
|
||||
assertEquals("time_start BETWEEN ? AND ?", selectionOk.selection());
|
||||
assertEquals(List.of(Long.toString(instant.toEpochMilli()), Long.toString(instant.toEpochMilli() + oneDay)) , selectionOk.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -140,16 +130,11 @@ public class TrackSelectionTest extends TestCase {
|
||||
.addActivityType("road biking");
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "_id IN (?,?,?) AND category IN (?,?)");
|
||||
assertEquals(selection.selectionArgs().length, 5);
|
||||
assertEquals(selection.selectionArgs()[0], "1");
|
||||
assertEquals(selection.selectionArgs()[1], "2");
|
||||
assertEquals(selection.selectionArgs()[2], "3");
|
||||
assertEquals(selection.selectionArgs()[3], "running");
|
||||
assertEquals(selection.selectionArgs()[4], "road biking");
|
||||
assertEquals("_id IN (?,?,?) AND activity_type_localized IN (?,?)", selection.selection());
|
||||
assertEquals(List.of("1", "2", "3", "running", "road biking"), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -169,16 +154,11 @@ public class TrackSelectionTest extends TestCase {
|
||||
.addDateRange(instant, instant.plusMillis(oneDay));
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "_id IN (?,?,?) AND starttime BETWEEN ? AND ?");
|
||||
assertEquals(selection.selectionArgs().length, 5);
|
||||
assertEquals(selection.selectionArgs()[0], "1");
|
||||
assertEquals(selection.selectionArgs()[1], "2");
|
||||
assertEquals(selection.selectionArgs()[2], "3");
|
||||
assertEquals(selection.selectionArgs()[3], Long.toString(instant.toEpochMilli()));
|
||||
assertEquals(selection.selectionArgs()[4], Long.toString(instant.toEpochMilli() + oneDay));
|
||||
assertEquals("_id IN (?,?,?) AND time_start BETWEEN ? AND ?", selection.selection());
|
||||
assertEquals(List.of("1", "2", "3", Long.toString(instant.toEpochMilli()), Long.toString(instant.toEpochMilli() + oneDay)), selection.selectionArgs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -193,14 +173,10 @@ public class TrackSelectionTest extends TestCase {
|
||||
.addDateRange(instant, instant.plusMillis(oneDay));
|
||||
|
||||
// when
|
||||
SelectionData selection = filter.buildSelection();
|
||||
ContentProviderUtils.SelectionData selection = filter.buildSelection();
|
||||
|
||||
// Then
|
||||
assertEquals(selection.selection(), "category IN (?,?) AND starttime BETWEEN ? AND ?");
|
||||
assertEquals(selection.selectionArgs().length, 4);
|
||||
assertEquals(selection.selectionArgs()[0], "running");
|
||||
assertEquals(selection.selectionArgs()[1], "road biking");
|
||||
assertEquals(selection.selectionArgs()[2], Long.toString(instant.toEpochMilli()));
|
||||
assertEquals(selection.selectionArgs()[3], Long.toString(instant.toEpochMilli() + oneDay));
|
||||
assertEquals("activity_type_localized IN (?,?) AND time_start BETWEEN ? AND ?", selection.selection());
|
||||
assertEquals(List.of("running", "road biking", Long.toString(instant.toEpochMilli()), Long.toString(instant.toEpochMilli() + oneDay)), selection.selectionArgs());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
public class TrackPointTest {
|
||||
|
||||
@Test
|
||||
public void distanceToPrevious() {
|
||||
public void distanceToPrevious_gps() {
|
||||
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(0),
|
||||
@@ -38,20 +38,123 @@ public class TrackPointTest {
|
||||
|
||||
// without sensor distance
|
||||
assertEquals(11.13, tp2.distanceToPrevious(tp1).toM(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToPrevious_sensor_distance_first() {
|
||||
TrackPoint tp1 = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(0),
|
||||
0d,
|
||||
0.0001,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
Distance.of(5),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
TrackPoint tp2 = new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(1),
|
||||
0d,
|
||||
0.0002,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
|
||||
// tp1 has sensor distance
|
||||
tp1.setSensorDistance(Distance.of(5));
|
||||
tp1.setSensorDistance(null);
|
||||
assertEquals(11.13, tp2.distanceToPrevious(tp1).toM(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToPrevious_sensor_distance_second() {
|
||||
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(0),
|
||||
0d,
|
||||
0.0001,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
|
||||
TrackPoint tp2 = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(1),
|
||||
0d,
|
||||
0.0002,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
Distance.of(5),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
// tp2 has sensor distance
|
||||
tp1.setSensorDistance(null);
|
||||
tp2.setSensorDistance(Distance.of(5));
|
||||
assertEquals(5, tp2.distanceToPrevious(tp1).toM(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToPrevious_sensor_distance_both() {
|
||||
TrackPoint tp1 = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(0),
|
||||
0d,
|
||||
0.0001,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
Distance.of(10),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
TrackPoint tp2 = new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.ofEpochMilli(1),
|
||||
0d,
|
||||
0.0002,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
Distance.of(5),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
// tp1 and tp2 have sensor distance
|
||||
tp1.setSensorDistance(Distance.of(10));
|
||||
tp2.setSensorDistance(Distance.of(5));
|
||||
assertEquals(5, tp2.distanceToPrevious(tp1).toM(), 0.01);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -21,7 +21,7 @@ public class DistanceFormatterTest {
|
||||
@Test
|
||||
public void testFormatDistance_metric() {
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setDecimalPlaces(2)
|
||||
.setUnit(UnitSystem.METRIC)
|
||||
.build(context);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class DistanceFormatterTest {
|
||||
@Test
|
||||
public void testFormatDistance_imperial() {
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setDecimalPlaces(2)
|
||||
.setUnit(UnitSystem.IMPERIAL_FEET)
|
||||
.build(context);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DistanceFormatterTest {
|
||||
@Test
|
||||
public void testFormatDistance_nautical() {
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setDecimalPlaces(2)
|
||||
.setUnit(UnitSystem.NAUTICAL_IMPERIAL)
|
||||
.build(context);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ public class SpeedFormatterTest {
|
||||
@Test
|
||||
public void testGetSpeedParts_pace_metric() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.METRIC)
|
||||
.setReportSpeedOrPace(false)
|
||||
.build(context);
|
||||
@@ -29,73 +28,67 @@ public class SpeedFormatterTest {
|
||||
assertEquals("4:59", formatter.getSpeedParts(Speed.of(3.34)).first);
|
||||
assertEquals("5:00", formatter.getSpeedParts(Speed.of(3.33)).first);
|
||||
|
||||
assertEquals("min/km", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("min/km", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSpeedParts_pace_imperial() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.IMPERIAL_FEET)
|
||||
.setReportSpeedOrPace(false)
|
||||
.build(context);
|
||||
|
||||
assertEquals("8:02", formatter.getSpeedParts(Speed.of(3.34)).first);
|
||||
assertEquals("min/mi", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("min/mi", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSpeedParts_pace_nautical() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.NAUTICAL_IMPERIAL)
|
||||
.setReportSpeedOrPace(false)
|
||||
.build(context);
|
||||
|
||||
assertEquals("9:14", formatter.getSpeedParts(Speed.of(3.34)).first);
|
||||
assertEquals("min/NM", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("min/NM", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSpeedParts_speed_metric() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.METRIC)
|
||||
.setReportSpeedOrPace(true)
|
||||
.build(context);
|
||||
|
||||
assertEquals("11.9", formatter.getSpeedParts(Speed.of(3.31)).first);
|
||||
assertEquals("km/h", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("km/h", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSpeedParts_speed_imperial() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.IMPERIAL_FEET)
|
||||
.setReportSpeedOrPace(true)
|
||||
.build(context);
|
||||
|
||||
assertEquals("7.5", formatter.getSpeedParts(Speed.of(3.34)).first);
|
||||
assertEquals("mph", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("mph", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSpeedParts_speed_nautical() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.NAUTICAL_IMPERIAL)
|
||||
.setReportSpeedOrPace(true)
|
||||
.build(context);
|
||||
|
||||
assertEquals("6.5", formatter.getSpeedParts(Speed.of(3.34)).first);
|
||||
assertEquals("kn", formatter.getSpeedParts(Speed.zero()).second);
|
||||
assertEquals("kn", formatter.getSpeedParts(Speed.ZERO).second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatSpeed() {
|
||||
SpeedFormatter formatter = SpeedFormatter.Builder()
|
||||
.setDecimalCount(2)
|
||||
.setUnit(UnitSystem.METRIC)
|
||||
.setReportSpeedOrPace(false)
|
||||
.build(context);
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package de.dennisguse.opentracks.data.models;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class StatisticsTest {
|
||||
|
||||
@Test
|
||||
public void testMerge() {
|
||||
// given
|
||||
Statistics subject = new Statistics(
|
||||
Instant.ofEpochMilli(1000),
|
||||
Instant.ofEpochMilli(2500),
|
||||
Duration.ofMillis(1500),
|
||||
Duration.ofMillis(700),
|
||||
Distance.of(750.0),
|
||||
Speed.of(60.0),
|
||||
new AltitudeExtremities(1200, 1250),
|
||||
new AltitudeGainLoss(50, 0),
|
||||
HeartRate.of(100),
|
||||
null
|
||||
);
|
||||
|
||||
Statistics append = new Statistics(
|
||||
Instant.ofEpochMilli(3000),
|
||||
Instant.ofEpochMilli(4000),
|
||||
Duration.ofMillis(1000),
|
||||
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
|
||||
Statistics result = subject.merge(append);
|
||||
|
||||
// then
|
||||
assertEquals(
|
||||
new Statistics(
|
||||
Instant.ofEpochMilli(1000),
|
||||
Instant.ofEpochMilli(4000),
|
||||
Duration.ofMillis(2500),
|
||||
Duration.ofMillis(1300),
|
||||
Distance.of(1100),
|
||||
Speed.of(60),
|
||||
new AltitudeExtremities(1200, 3575),
|
||||
new AltitudeGainLoss(900, 0),
|
||||
HeartRate.of(150),
|
||||
null
|
||||
)
|
||||
, result
|
||||
);
|
||||
}
|
||||
}
|
||||
+14
-6
@@ -4,11 +4,13 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
|
||||
//TODO Merge with TrackFilenameGeneratorTest whenever Junit5 gets available.
|
||||
@@ -33,12 +35,18 @@ public class TrackFilenameGenerator2Test {
|
||||
@Test(expected = TrackFilenameGenerator.TemplateInvalidException.class)
|
||||
public void testFilenameTemplate() {
|
||||
// given
|
||||
Track track = new Track();
|
||||
track.setName("Best Track");
|
||||
track.setUuid(UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6"));
|
||||
track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z"));
|
||||
Track track = new Track(
|
||||
null,
|
||||
UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6"),
|
||||
"Berlin",
|
||||
"",
|
||||
"",
|
||||
ActivityType.CYCLING,
|
||||
ZoneOffset.UTC,
|
||||
Statistics.DEFAULT
|
||||
);
|
||||
|
||||
// when
|
||||
String filename = subject.format(track, TrackFileFormat.GPX);
|
||||
subject.format(track, TrackFileFormat.GPX);
|
||||
}
|
||||
}
|
||||
+12
-4
@@ -10,6 +10,7 @@ import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.TimeZone;
|
||||
@@ -17,6 +18,7 @@ import java.util.UUID;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TimezoneRule;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
@@ -47,10 +49,16 @@ public class TrackFilenameGeneratorTest {
|
||||
@Test
|
||||
public void testFilenameTemplate() {
|
||||
// given
|
||||
Track track = new Track();
|
||||
track.setName("Best Track");
|
||||
track.setUuid(UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"));
|
||||
track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z"));
|
||||
Track track = new Track(
|
||||
null,
|
||||
UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"),
|
||||
"Best Track",
|
||||
"",
|
||||
"",
|
||||
null,
|
||||
ZoneOffset.UTC,
|
||||
new Statistics(Instant.parse("2020-02-02T02:02:02Z"), Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, null, null, null, null)
|
||||
);
|
||||
|
||||
// when
|
||||
String filename = subject.format(track, TrackFileFormat.GPX);
|
||||
|
||||
+327
-217
@@ -1,7 +1,6 @@
|
||||
package de.dennisguse.opentracks.io.file.importer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@@ -27,7 +26,6 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -52,6 +50,7 @@ import de.dennisguse.opentracks.content.data.TestDataUtil;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeExtremities;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
@@ -60,22 +59,25 @@ import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Power;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Temperature;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackBuilder;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
|
||||
import de.dennisguse.opentracks.sensors.BluetoothHandlerManagerCyclingPower;
|
||||
import de.dennisguse.opentracks.sensors.SensorManager;
|
||||
import de.dennisguse.opentracks.sensors.driver.CyclingPowerBluetooth;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingDistanceSpeed;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingPower;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorHeartRate;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.Raw;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorTemperature;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
|
||||
/**
|
||||
* Export a track to {@link TrackFileFormat} and verify that the import is identical.
|
||||
@@ -87,7 +89,7 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
public class ExportImportTest {
|
||||
|
||||
@Rule
|
||||
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS);
|
||||
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(50, TimeUnit.SECONDS); //TODO 5s
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mGrantPermissionRule = TestUtil.createGrantPermissionRule();
|
||||
@@ -96,13 +98,15 @@ public class ExportImportTest {
|
||||
@Rule
|
||||
public TimezoneRule timezoneRule = new TimezoneRule(TimeZone.getTimeZone("Europe/Berlin"));
|
||||
|
||||
private static final Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@BeforeClass
|
||||
public static void preSetUp() {
|
||||
// Prepare looper for Android's message queue
|
||||
if (Looper.myLooper() == null) Looper.prepare();
|
||||
}
|
||||
|
||||
private final Context context = ApplicationProvider.getApplicationContext();
|
||||
PreferencesUtils.resetPreferences(context, true);
|
||||
}
|
||||
|
||||
private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
|
||||
@@ -122,11 +126,13 @@ public class ExportImportTest {
|
||||
private TrackImporter trackImporter;
|
||||
|
||||
@Before
|
||||
public void fileSetup() throws IOException {
|
||||
public void fileSetup() throws IOException, TimeoutException {
|
||||
tmpFile = File.createTempFile("test", "test", context.getFilesDir());
|
||||
tmpFileUri = Uri.fromFile(tmpFile);
|
||||
|
||||
trackImporter = new TrackImporter(context, contentProviderUtils, Distance.of(200), true);
|
||||
|
||||
setUp();
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -150,24 +156,50 @@ public class ExportImportTest {
|
||||
Distance sensorDistance = Distance.of(10); // recording distance interval
|
||||
|
||||
sendLocation(trackPointCreator, "2020-02-02T02:02:03Z", 3.1234567, 14.0014567, 10, 13, 15, 1020.25, 1f);
|
||||
contentProviderUtils.insertMarker(new Marker(trackId, service.getLastStoredTrackPointWithLocation(), "Marker 1", "Marker 1 desc", "Marker 1 category", null, null));
|
||||
contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"Marker 1",
|
||||
"Marker 1 desc",
|
||||
"Marker 1 typeLocalized",
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:03Z"),
|
||||
3.1234567, 14.0014567,
|
||||
Distance.of(10),
|
||||
Altitude.WGS84.of(1020.25),
|
||||
Distance.of(13),
|
||||
null,
|
||||
Speed.of(15)
|
||||
),
|
||||
null
|
||||
));
|
||||
|
||||
// A sensor-only TrackPoint
|
||||
trackPointCreator.setClock("2020-02-02T02:02:04Z");
|
||||
mockSensorData(trackPointCreator, 15f, sensorDistance, 66f, 3f, 50f, 1f);
|
||||
mockSensorData(trackPointCreator, 15f, sensorDistance, 66f, 3f, 50f, 1f, 27);
|
||||
|
||||
trackPointCreator.setClock("2020-02-02T02:02:14Z");
|
||||
mockSensorData(trackPointCreator, 15f, null, 67f, 3f, 50f, null);
|
||||
trackPointCreator.setClock("2020-02-02T02:02:14Z"); //ignored
|
||||
mockSensorData(trackPointCreator, 15f, null, 67f, 3f, 50f, null, 28);
|
||||
trackPointCreator.setClock("2020-02-02T02:02:15Z");
|
||||
mockSensorData(trackPointCreator, null, null, 68f, 3f, 50f, null);
|
||||
mockSensorData(trackPointCreator, null, null, 68f, 3f, 50f, null, 29);
|
||||
trackPointCreator.setClock("2020-02-02T02:02:16Z");
|
||||
mockSensorData(trackPointCreator, 5f, Distance.of(2), 69f, 3f, 50f, null); // Distance will be added to next TrackPoint
|
||||
mockSensorData(trackPointCreator, 5f, Distance.of(2), 69f, 3f, 50f, null, 30); //Distance will be added to next TrackPoint
|
||||
|
||||
sendLocation(trackPointCreator, "2020-02-02T02:02:17Z", 3.1234567, 14.0014567, 10, 13, 15, 1020.25, 0f);
|
||||
contentProviderUtils.insertMarker(new Marker(trackId, service.getLastStoredTrackPointWithLocation(), "Marker 2", "Marker 2 desc", "Marker 2 category", null, null));
|
||||
contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackId,
|
||||
"Marker 2",
|
||||
"Marker 2 desc",
|
||||
"Marker 2 typeLocalized",
|
||||
service.getLastStoredTrackPointWithLocation().position(),
|
||||
null
|
||||
));
|
||||
|
||||
trackPointCreator.setClock("2020-02-02T02:02:18Z");
|
||||
trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(trackPointCreator);
|
||||
trackPointCreator.getSensorManager().clear();
|
||||
service.endCurrentTrack();
|
||||
|
||||
trackPointCreator.setClock("2020-02-02T02:03:20Z");
|
||||
@@ -182,129 +214,170 @@ public class ExportImportTest {
|
||||
|
||||
sendLocation(trackPointCreator, "2020-02-02T02:03:50Z", 3.1234567, 16.001, 10, 27, 15, 999.123, 0f);
|
||||
|
||||
trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(trackPointCreator);
|
||||
trackPointCreator.getSensorManager().clear();
|
||||
trackPointCreator.setClock("2020-02-02T02:04:00Z");
|
||||
service.endCurrentTrack();
|
||||
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
track.setActivityType(TRACK_ACTIVITY_TYPE);
|
||||
track.setActivityTypeLocalized(TRACK_ACTIVITY_TYPE_LOCALIZED);
|
||||
track.setDescription(TRACK_DESCRIPTION);
|
||||
contentProviderUtils.updateTrack(track);
|
||||
TrackBuilder trackBuilder = new TrackBuilder(contentProviderUtils.getTrack(trackId));
|
||||
trackBuilder.setActivityType(TRACK_ACTIVITY_TYPE);
|
||||
trackBuilder.setActivityTypeLocalized(TRACK_ACTIVITY_TYPE_LOCALIZED);
|
||||
trackBuilder.setDescription(TRACK_DESCRIPTION);
|
||||
contentProviderUtils.updateTrack(trackBuilder.getTrack());
|
||||
|
||||
track = contentProviderUtils.getTrack(trackId);
|
||||
trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId);
|
||||
markers = contentProviderUtils.getMarkers(trackId);
|
||||
markers = TestDataUtil.getMarkers(contentProviderUtils, trackId);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
public void track() throws TimeoutException {
|
||||
setUp();
|
||||
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
TrackStatistics trackStatistics = track.getTrackStatistics();
|
||||
Statistics trackStatistics = track.statistics();
|
||||
|
||||
assertEquals(ZoneOffset.of("+01:00"), track.getZoneOffset());
|
||||
assertEquals(Instant.parse("2020-02-02T02:02:02Z"), trackStatistics.getStartTime());
|
||||
assertEquals(Instant.parse("2020-02-02T02:04:00Z"), trackStatistics.getStopTime());
|
||||
|
||||
assertEquals(Duration.ofSeconds(56), trackStatistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(26), trackStatistics.getMovingTime()); //TODO Likely too low
|
||||
|
||||
// Distance
|
||||
assertEquals(222049.34375, trackStatistics.getTotalDistance().toM(), 0.01); //TODO Too low
|
||||
|
||||
// Speed
|
||||
assertEquals(8540.359, trackStatistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(3965.166, trackStatistics.getAverageSpeed().toMPS(), 0.01);
|
||||
assertEquals(8540.359, trackStatistics.getAverageMovingSpeed().toMPS(), 0.01);
|
||||
|
||||
// Altitude
|
||||
assertEquals(999.122, trackStatistics.getMinAltitude(), 0.01);
|
||||
assertEquals(1020.25, trackStatistics.getMaxAltitude(), 0.01);
|
||||
|
||||
assertEquals(2, trackStatistics.getTotalAltitudeGain(), 0.01);
|
||||
assertEquals(2, trackStatistics.getTotalAltitudeLoss(), 0.01);
|
||||
assertEquals(ZoneOffset.of("+01:00"), track.zoneOffset());
|
||||
|
||||
List<TrackPoint> actual = TestDataUtil.getTrackPoints(contentProviderUtils, trackId);
|
||||
new TrackPointAssert().assertEquals(List.of(
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:02Z")),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:03Z"),
|
||||
3.123456, 14.001456, Distance.of(10),
|
||||
Altitude.WGS84.of(1020.25), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Instant.parse("2020-02-02T02:02:04Z"))
|
||||
.setSensorDistance(Distance.of(10))
|
||||
.setSpeed(Speed.of(15))
|
||||
.setHeartRate(HeartRate.of(66))
|
||||
.setCadence(3)
|
||||
.setPower(50)
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:15Z"))
|
||||
.setHeartRate(HeartRate.of(68))
|
||||
.setCadence(3)
|
||||
.setPower(50),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:04Z"),
|
||||
null, null, null,
|
||||
null, null,
|
||||
null,
|
||||
Speed.of(15)),
|
||||
Distance.of(10),
|
||||
HeartRate.of(66),
|
||||
Temperature.of(27),
|
||||
Cadence.of(3),
|
||||
Power.of(50),
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
Position.of(Instant.parse("2020-02-02T02:02:15Z")),
|
||||
null,
|
||||
HeartRate.of(68),
|
||||
Temperature.of(29),
|
||||
Cadence.of(3),
|
||||
Power.of(50),
|
||||
null
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:17Z"),
|
||||
3.123456, 14.001456, Distance.of(10),
|
||||
Altitude.WGS84.of(1020.25), null,
|
||||
null,
|
||||
Speed.of(5)))
|
||||
.setSensorDistance(Distance.of(2))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f)
|
||||
.setHeartRate(HeartRate.of(69))
|
||||
.setCadence(3)
|
||||
.setPower(50),
|
||||
Speed.of(5)),
|
||||
Distance.of(2),
|
||||
HeartRate.of(69),
|
||||
Temperature.of(30),
|
||||
Cadence.of(3),
|
||||
Power.of(50),
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:02:18Z")),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:03:20Z")),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:21Z"),
|
||||
3.123456, 14.002456, Distance.of(10),
|
||||
Altitude.WGS84.of(999.1229858398438), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(Instant.parse("2020-02-02T02:03:22Z"),
|
||||
3.123456, 16d, Distance.of(10),
|
||||
Altitude.WGS84.of(999.1229858398438), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.IDLE, Instant.parse("2020-02-02T02:03:30Z"))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.IDLE,
|
||||
Position.of(Instant.parse("2020-02-02T02:03:30Z")),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:50Z"),
|
||||
3.123456, 16.001, Distance.of(10),
|
||||
Altitude.WGS84.of(999.1229858398438), null,
|
||||
null, Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
null, Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:04:00Z"))
|
||||
), actual);
|
||||
|
||||
assertEquals(new Statistics(
|
||||
Instant.parse("2020-02-02T02:02:02Z"),
|
||||
Instant.parse("2020-02-02T02:04:00Z"),
|
||||
Duration.ofSeconds(56),
|
||||
Duration.ofSeconds(26), //TODO Likely too low
|
||||
Distance.of(222049.34375), //TODO Too low
|
||||
Speed.of(22203.734375),
|
||||
new AltitudeExtremities(999.1229858398438, 1020.25),
|
||||
new AltitudeGainLoss(2, 2),
|
||||
null,
|
||||
null
|
||||
),
|
||||
trackStatistics);
|
||||
}
|
||||
|
||||
//TODO Does not test marker images
|
||||
@LargeTest
|
||||
@Test
|
||||
public void kmz_with_trackdetail_and_sensordata() throws TimeoutException, IOException {
|
||||
setUp();
|
||||
|
||||
public void kmz_with_trackdetail_and_sensordata() throws IOException {
|
||||
// given
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
@@ -323,41 +396,32 @@ public class ExportImportTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(track.getActivityType(), importedTrack.getActivityType());
|
||||
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
|
||||
assertEquals(track.getDescription(), importedTrack.getDescription());
|
||||
assertEquals(track.getName(), importedTrack.getName());
|
||||
assertEquals(track.activityType(), importedTrack.activityType());
|
||||
assertEquals(track.activityTypeLocalized(), importedTrack.activityTypeLocalized());
|
||||
assertEquals(track.description(), importedTrack.description());
|
||||
assertEquals(track.name(), importedTrack.name());
|
||||
|
||||
// 2. trackpoints
|
||||
TrackPointAssert a = new TrackPointAssert();
|
||||
List<TrackPoint> actual = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
a.assertEquals(trackPoints, actual);
|
||||
new TrackPointAssert().assertEquals(trackPoints, actual);
|
||||
|
||||
// 3. trackstatistics
|
||||
TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics();
|
||||
|
||||
// Time
|
||||
assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset());
|
||||
assertEquals(Instant.parse("2020-02-02T02:02:02Z"), importedTrackStatistics.getStartTime());
|
||||
assertEquals(Instant.parse("2020-02-02T02:04:00Z"), importedTrackStatistics.getStopTime());
|
||||
|
||||
assertEquals(Duration.ofSeconds(56), importedTrackStatistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(26), importedTrackStatistics.getMovingTime());
|
||||
|
||||
// Distance
|
||||
assertEquals(222049.421, importedTrackStatistics.getTotalDistance().toM(), 0.01);
|
||||
|
||||
// Speed
|
||||
assertEquals(8540.362, importedTrackStatistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(3965.168, importedTrackStatistics.getAverageSpeed().toMPS(), 0.01);
|
||||
assertEquals(8540.362, importedTrackStatistics.getAverageMovingSpeed().toMPS(), 0.01);
|
||||
|
||||
// Altitude
|
||||
assertEquals(999.122, importedTrackStatistics.getMinAltitude(), 0.01);
|
||||
assertEquals(1020.25, importedTrackStatistics.getMaxAltitude(), 0.01);
|
||||
assertEquals(2, importedTrackStatistics.getTotalAltitudeGain(), 0.01);
|
||||
assertEquals(2, importedTrackStatistics.getTotalAltitudeLoss(), 0.01);
|
||||
Statistics importedTrackStatistics = importedTrack.statistics();
|
||||
|
||||
assertEquals(track.zoneOffset(), importedTrack.zoneOffset());
|
||||
assertEquals(new Statistics(
|
||||
Instant.parse("2020-02-02T02:02:02Z"),
|
||||
Instant.parse("2020-02-02T02:04:00Z"),
|
||||
Duration.ofSeconds(56),
|
||||
Duration.ofSeconds(26), //TODO Likely too low
|
||||
Distance.of(222049.421875), //TODO Too low
|
||||
Speed.of(22203.7421875),
|
||||
new AltitudeExtremities(999.1229858398438, 1020.25),
|
||||
new AltitudeGainLoss(2, 2),
|
||||
null,
|
||||
null
|
||||
),
|
||||
importedTrackStatistics);
|
||||
|
||||
// 4. markers
|
||||
assertMarkers();
|
||||
@@ -365,9 +429,7 @@ public class ExportImportTest {
|
||||
|
||||
@LargeTest
|
||||
@Test(expected = ImportAlreadyExistsException.class)
|
||||
public void kml_with_trackdetail_and_sensordata_duplicate_trackUUID() throws TimeoutException, IOException {
|
||||
setUp();
|
||||
|
||||
public void kml_with_trackdetail_and_sensordata_duplicate_trackUUID() throws IOException {
|
||||
// given
|
||||
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
editor.putBoolean(context.getString(R.string.import_prevent_reimport_key), true);
|
||||
@@ -392,8 +454,6 @@ public class ExportImportTest {
|
||||
@LargeTest
|
||||
@Test
|
||||
public void gpx() throws TimeoutException, IOException {
|
||||
setUp();
|
||||
|
||||
// given
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
@@ -413,10 +473,10 @@ public class ExportImportTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(track.getActivityType(), importedTrack.getActivityType());
|
||||
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
|
||||
assertEquals(track.getDescription(), importedTrack.getDescription());
|
||||
assertEquals(track.getName(), importedTrack.getName());
|
||||
assertEquals(track.activityType(), importedTrack.activityType());
|
||||
assertEquals(track.activityTypeLocalized(), importedTrack.activityTypeLocalized());
|
||||
assertEquals(track.description(), importedTrack.description());
|
||||
assertEquals(track.name(), importedTrack.name());
|
||||
|
||||
// 2. trackpoints
|
||||
// The GPX exporter does not support exporting TrackPoints without lat/lng.
|
||||
@@ -426,82 +486,105 @@ public class ExportImportTest {
|
||||
.setDelta(0.05); // speed is not fully
|
||||
List<TrackPoint> actual = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
a.assertEquals(List.of(
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:03Z"),
|
||||
3.123456, 14.001456d, Distance.of(10),
|
||||
Altitude.WGS84.of(1020.2), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:17Z"),
|
||||
3.123456, 14.001456, Distance.of(10),
|
||||
Altitude.WGS84.of(1020.2), null,
|
||||
null,
|
||||
Speed.of(5)))
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f)
|
||||
.setSensorDistance(Distance.of(12))
|
||||
.setHeartRate(69)
|
||||
.setPower(50f)
|
||||
.setCadence(3f),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
Speed.of(5)),
|
||||
Distance.of(12),
|
||||
HeartRate.of(69),
|
||||
Temperature.of(30),
|
||||
Cadence.of(3),
|
||||
Power.of(50),
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:21Z"),
|
||||
3.123456, 14.002456, Distance.of(10),
|
||||
Altitude.WGS84.of(999.0999755859375), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:22Z"),
|
||||
3.123456, 16d, Distance.of(10),
|
||||
Altitude.WGS84.of(999.0999755859375), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:50Z"),
|
||||
3.123456, 16.001, Distance.of(10),
|
||||
Altitude.WGS84.of(999.0999755859375), null,
|
||||
null,
|
||||
Speed.of(10)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f)
|
||||
.setSpeed(Speed.of(15))
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
)
|
||||
), actual);
|
||||
|
||||
// 3. trackstatistics
|
||||
TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics();
|
||||
assertEquals(track.zoneOffset(), importedTrack.zoneOffset());
|
||||
|
||||
// Time
|
||||
assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset());
|
||||
assertEquals(Instant.parse("2020-02-02T02:02:03Z"), importedTrackStatistics.getStartTime());
|
||||
assertEquals(Instant.parse("2020-02-02T02:03:50Z"), importedTrackStatistics.getStopTime());
|
||||
|
||||
assertEquals(Duration.ofSeconds(107), importedTrackStatistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(107), importedTrackStatistics.getMovingTime());
|
||||
|
||||
// Distance
|
||||
assertEquals(222271.734, importedTrackStatistics.getTotalDistance().toM(), 0.01);
|
||||
|
||||
// Speed
|
||||
assertEquals(2077.305, importedTrackStatistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(2077.305, importedTrackStatistics.getAverageSpeed().toMPS(), 0.01);
|
||||
assertEquals(2077.305, importedTrackStatistics.getAverageMovingSpeed().toMPS(), 0.01);
|
||||
|
||||
// Altitude
|
||||
assertEquals(999.099, importedTrackStatistics.getMinAltitude(), 0.01);
|
||||
assertEquals(1020.2, importedTrackStatistics.getMaxAltitude(), 0.01);
|
||||
assertEquals(2, importedTrackStatistics.getTotalAltitudeGain(), 0.01);
|
||||
assertEquals(2, importedTrackStatistics.getTotalAltitudeLoss(), 0.01);
|
||||
Statistics importedTrackStatistics = importedTrack.statistics();
|
||||
assertEquals(new Statistics(
|
||||
Instant.parse("2020-02-02T02:02:03Z"),
|
||||
Instant.parse("2020-02-02T02:03:50Z"),
|
||||
Duration.ofSeconds(107),
|
||||
Duration.ofSeconds(107),
|
||||
Distance.of(222271.734375),
|
||||
Speed.of(2077.305908203125),
|
||||
new AltitudeExtremities(999.0999755859375, 1020.2000122070312),
|
||||
new AltitudeGainLoss(2, 2),
|
||||
null,
|
||||
null
|
||||
),
|
||||
importedTrackStatistics);
|
||||
|
||||
// 4. markers
|
||||
assertMarkers();
|
||||
@@ -509,9 +592,7 @@ public class ExportImportTest {
|
||||
|
||||
@LargeTest
|
||||
@Test(expected = ImportAlreadyExistsException.class)
|
||||
public void gpx_duplicate_trackUUID() throws TimeoutException, IOException {
|
||||
setUp();
|
||||
|
||||
public void gpx_duplicate_trackUUID() throws IOException {
|
||||
// given
|
||||
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
editor.putBoolean(context.getString(R.string.import_prevent_reimport_key), true);
|
||||
@@ -537,9 +618,7 @@ public class ExportImportTest {
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
public void csv_export_only() throws TimeoutException, IOException {
|
||||
setUp();
|
||||
|
||||
public void csv_export_only() throws IOException {
|
||||
// given
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
@@ -566,35 +645,34 @@ public class ExportImportTest {
|
||||
}
|
||||
|
||||
private void assertMarkers() {
|
||||
assertEquals(markers.size(), contentProviderUtils.getMarkers(importTrackId).size());
|
||||
List<Marker> importedMarkers = TestDataUtil.getMarkers(contentProviderUtils, importTrackId);
|
||||
assertEquals(markers.size(), importedMarkers.size());
|
||||
|
||||
List<Marker> importedMarkers = contentProviderUtils.getMarkers(importTrackId);
|
||||
for (int i = 0; i < markers.size(); i++) {
|
||||
Marker marker = markers.get(i);
|
||||
Marker importMarker = importedMarkers.get(i);
|
||||
assertEquals(marker.getCategory(), importMarker.getCategory());
|
||||
assertEquals(marker.getDescription(), importMarker.getDescription());
|
||||
// assertEquals(marker.getIcon(), importMarker.getIcon()); // TODO for KML
|
||||
assertEquals(marker.getName(), importMarker.getName());
|
||||
assertFalse(importMarker.hasPhoto());
|
||||
assertEquals(marker.typeLocalized(), importMarker.typeLocalized());
|
||||
assertEquals(marker.description(), importMarker.description());
|
||||
assertEquals(marker.name(), importMarker.name());
|
||||
assertNull(importMarker.photoUrl());
|
||||
|
||||
assertEquals(marker.getPosition().latitude(), importMarker.getPosition().latitude(), 0.001);
|
||||
assertEquals(marker.getPosition().longitude(), importMarker.getPosition().longitude(), 0.001);
|
||||
assertEquals(marker.getPosition().altitude().toM(), importMarker.getPosition().altitude().toM(), 0.1);
|
||||
assertEquals(marker.position().latitude(), importMarker.position().latitude(), 0.001);
|
||||
assertEquals(marker.position().longitude(), importMarker.position().longitude(), 0.001);
|
||||
assertEquals(marker.position().altitude().toM(), importMarker.position().altitude().toM(), 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
private void mockSensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, float heartRate, float cadence, Float power, Float altitudeGain) {
|
||||
SensorDataSet sensorDataSet = trackPointCreator.getSensorManager().sensorDataSet;
|
||||
private static void mockSensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, float heartRate, float cadence, Float power, Float altitudeGain, float temperature) {
|
||||
SensorManager sensorManager = trackPointCreator.getSensorManager();
|
||||
|
||||
AggregatorCyclingPower cyclingPower = new AggregatorCyclingPower("", "");
|
||||
cyclingPower.add(new Raw<>(trackPointCreator.createNow(), new BluetoothHandlerManagerCyclingPower.Data(Power.of(power), null)));
|
||||
sensorDataSet.add(cyclingPower);
|
||||
cyclingPower.add(trackPointCreator.getNow(), new CyclingPowerBluetooth.Data(Power.of(power), null));
|
||||
sensorManager.setAggregator(cyclingPower);
|
||||
|
||||
|
||||
AggregatorHeartRate avgHeartRate = new AggregatorHeartRate("", "");
|
||||
avgHeartRate.add(new Raw<>(trackPointCreator.createNow(), HeartRate.of(heartRate)));
|
||||
sensorDataSet.add(avgHeartRate);
|
||||
avgHeartRate.add(trackPointCreator.getNow(), HeartRate.of(heartRate));
|
||||
sensorManager.setAggregator(avgHeartRate);
|
||||
|
||||
AggregatorCyclingCadence cyclingCadence = new AggregatorCyclingCadence("", "") {
|
||||
@NonNull
|
||||
@@ -608,33 +686,65 @@ public class ExportImportTest {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
sensorDataSet.add(cyclingCadence);
|
||||
sensorManager.setAggregator(cyclingCadence);
|
||||
|
||||
if (distance != null && speed != null) {
|
||||
AggregatorCyclingDistanceSpeed distanceSpeed = Mockito.mock(AggregatorCyclingDistanceSpeed.class);
|
||||
Mockito.when(distanceSpeed.hasReceivedData()).thenReturn(true);
|
||||
Mockito.when(distanceSpeed.getAggregatedValue(Mockito.any())).thenReturn(new AggregatorCyclingDistanceSpeed.Data(null, distance, Speed.of(speed)));
|
||||
sensorDataSet.add(distanceSpeed);
|
||||
AggregatorCyclingDistanceSpeed aggregatorCyclingDistanceSpeed = new AggregatorCyclingDistanceSpeed("", "") {
|
||||
@NonNull
|
||||
@Override
|
||||
public Data getAggregatedValue(Instant now) {
|
||||
return new AggregatorCyclingDistanceSpeed.Data(null, distance, Speed.of(speed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReceivedData() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
sensorManager.setAggregator(aggregatorCyclingDistanceSpeed);
|
||||
} else {
|
||||
sensorDataSet.add(new AggregatorCyclingDistanceSpeed("", ""));
|
||||
sensorManager.setAggregator(new AggregatorCyclingDistanceSpeed("", ""));
|
||||
}
|
||||
|
||||
mockAltitudeChange(trackPointCreator, altitudeGain);
|
||||
|
||||
trackPointCreator.onChange(sensorDataSet);
|
||||
sensorManager.setAggregator(new AggregatorTemperature("", "'") {
|
||||
@NonNull
|
||||
@Override
|
||||
public Temperature getAggregatedValue(Instant now) {
|
||||
return Temperature.of(temperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReceivedData() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
trackPointCreator.onChange();
|
||||
}
|
||||
|
||||
private void mockAltitudeChange(TrackPointCreator trackPointCreator, Float altitudeGain) {
|
||||
SensorDataSet sensorDataSet = trackPointCreator.getSensorManager().sensorDataSet;
|
||||
private static void mockAltitudeChange(TrackPointCreator trackPointCreator, Float altitudeGain) {
|
||||
SensorManager sensorManager = trackPointCreator.getSensorManager();
|
||||
|
||||
if (altitudeGain != null) {
|
||||
AggregatorBarometer barometer = Mockito.mock(AggregatorBarometer.class);
|
||||
Mockito.when(barometer.hasReceivedData()).thenReturn(true);
|
||||
Mockito.when(barometer.getAggregatedValue(Mockito.any())).thenReturn(new AltitudeGainLoss(altitudeGain, altitudeGain));
|
||||
sensorDataSet.add(barometer);
|
||||
} else {
|
||||
sensorDataSet.add(new AggregatorBarometer("test", null));
|
||||
if (altitudeGain == null) {
|
||||
sensorManager.getAltitudeChangeHandler().setAggregator(new AggregatorBarometer("test", null));
|
||||
return;
|
||||
}
|
||||
|
||||
AggregatorBarometer aggregatorBarometer = new AggregatorBarometer("", "") {
|
||||
@NonNull
|
||||
@Override
|
||||
public AltitudeGainLoss getAggregatedValue(Instant now) {
|
||||
return new AltitudeGainLoss(altitudeGain, altitudeGain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReceivedData() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
sensorManager.getAltitudeChangeHandler().setAggregator(aggregatorBarometer);
|
||||
}
|
||||
|
||||
private void sendLocation(TrackPointCreator trackPointCreator, String time, double latitude, double longitude, float accuracy, float verticalAccuracy, float speed, double altitude, Float altitudeGain) {
|
||||
@@ -649,6 +759,6 @@ public class ExportImportTest {
|
||||
mockAltitudeChange(trackPointCreator, altitudeGain);
|
||||
|
||||
trackPointCreator.setClock(time);
|
||||
trackPointCreator.getSensorManager().getGpsManager().onLocationChanged(location);
|
||||
trackPointCreator.getSensorManager().getGpsHandler().onDataReceived(location);
|
||||
}
|
||||
}
|
||||
+85
-118
@@ -27,14 +27,18 @@ import de.dennisguse.opentracks.content.data.TestDataUtil;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Power;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
|
||||
/**
|
||||
* Test that legacy KML/GPX formats can still be imported.
|
||||
@@ -61,73 +65,6 @@ public class GPXTrackImporterTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that data that contains pause (lat=100, lng=0) and resume (lat=200, lng=0) locations are restored to a segment break.
|
||||
*/
|
||||
@LargeTest
|
||||
@Test
|
||||
public void gpx_with_pause_resume() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GPXTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.legacy_gpx_pause_resume);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
importTrackId = importer.importFile(inputStream).get(0);
|
||||
|
||||
// then
|
||||
// 2. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("the category", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("the description", importedTrack.getDescription());
|
||||
assertEquals("2021-01-07 22:51", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
|
||||
//TODO Check trackstatistics
|
||||
|
||||
// 3. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
assertEquals(6, importedTrackPoints.size());
|
||||
|
||||
// first segment
|
||||
TrackPointAssert a = new TrackPointAssert();
|
||||
a.assertEquals(List.of(
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2021-01-07T21:51:59.179Z"),
|
||||
3d, 14d, null,
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
null)),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2021-01-07T21:52:00.653Z"),
|
||||
3d, 14.001, null,
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(75.4192))),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2021-01-07T21:52:01.010Z"),
|
||||
3d, 14.002, null,
|
||||
Altitude.WGS84.of(10), null,
|
||||
null, Speed.of(311.3948))),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2021-01-07T21:52:02.658Z")),
|
||||
|
||||
// created resume trackpoint with time of next valid trackpoint
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2021-01-07T21:52:03.873Z")),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2021-01-07T21:52:04.103Z"),
|
||||
3d, 14.003, null,
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
null))
|
||||
), importedTrackPoints);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
public void gpx_without_speed() throws IOException {
|
||||
@@ -143,15 +80,15 @@ public class GPXTrackImporterTest {
|
||||
// 2. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals("", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("", importedTrack.getDescription());
|
||||
assertEquals("20210907_213924.gpx", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("", importedTrack.activityTypeLocalized());
|
||||
assertEquals("", importedTrack.description());
|
||||
assertEquals("20210907_213924.gpx", importedTrack.name());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.activityType());
|
||||
|
||||
// 3. trackstatistics
|
||||
TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
|
||||
assertEquals(0.75, trackStatistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime());
|
||||
Statistics trackStatistics = importedTrack.statistics();
|
||||
assertEquals(0.75, trackStatistics.maxSpeed().toMPS(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(101), trackStatistics.movingDuration());
|
||||
|
||||
// 4. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
@@ -198,15 +135,15 @@ public class GPXTrackImporterTest {
|
||||
// 2. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals("", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("", importedTrack.getDescription());
|
||||
assertEquals("20210907_213924.gpx", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("", importedTrack.activityTypeLocalized());
|
||||
assertEquals("", importedTrack.description());
|
||||
assertEquals("20210907_213924.gpx", importedTrack.name());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.activityType());
|
||||
|
||||
// 3. trackstatistics
|
||||
TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
|
||||
assertEquals(5.0, trackStatistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime());
|
||||
Statistics trackStatistics = importedTrack.statistics();
|
||||
assertEquals(5.0, trackStatistics.maxSpeed().toMPS(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(101), trackStatistics.movingDuration());
|
||||
|
||||
// 4. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
@@ -260,56 +197,86 @@ public class GPXTrackImporterTest {
|
||||
TrackPointAssert a = new TrackPointAssert()
|
||||
.setDelta(0.05); // speed is not fully
|
||||
a.assertEquals(List.of(
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:03Z"),
|
||||
3d, 14d, Distance.of(10),
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:02:17Z"),
|
||||
3d, 14.001, Distance.of(10),
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(5)))
|
||||
.setAltitudeLoss(1f)
|
||||
.setAltitudeGain(1f)
|
||||
.setSensorDistance(Distance.of(12))
|
||||
.setHeartRate(69)
|
||||
.setPower(50f)
|
||||
.setCadence(3f),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
Speed.of(5)),
|
||||
Distance.of(12),
|
||||
HeartRate.of(69),
|
||||
null,
|
||||
Cadence.of(3),
|
||||
Power.of(50),
|
||||
new AltitudeGainLoss(1, 1)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:21Z"),
|
||||
3d, 14.002, Distance.of(10),
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:22Z"),
|
||||
3d, 16d, Distance.of(10),
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(15)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
),
|
||||
new TrackPoint(
|
||||
null,
|
||||
TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-02-02T02:03:50Z"),
|
||||
3d, 16.001, Distance.of(10),
|
||||
Altitude.WGS84.of(10), null,
|
||||
null,
|
||||
Speed.of(10)))
|
||||
.setAltitudeLoss(0f)
|
||||
.setAltitudeGain(0f)
|
||||
.setSpeed(Speed.of(15))
|
||||
Speed.of(15)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new AltitudeGainLoss(0, 0)
|
||||
)
|
||||
), actual);
|
||||
}
|
||||
|
||||
@@ -319,19 +286,19 @@ public class GPXTrackImporterTest {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GPXTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
|
||||
InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
|
||||
try (InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone)) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
// when
|
||||
// 1. import
|
||||
importTrackId = importer.importFile(inputStream).get(0);
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
importTrackId = importer.importFile(inputStream).get(0);
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
TrackExporter trackExporter = TrackFileFormat.GPX.createTrackExporter(context, contentProviderUtils);
|
||||
trackExporter.writeTrack(List.of(importedTrack), outputStream);
|
||||
|
||||
TrackExporter trackExporter = TrackFileFormat.GPX.createTrackExporter(context, contentProviderUtils);
|
||||
trackExporter.writeTrack(List.of(importedTrack), outputStream);
|
||||
|
||||
// then
|
||||
assertEquals(new String(inputStreamExpected.readAllBytes(), StandardCharsets.UTF_8), outputStream.toString());
|
||||
// then
|
||||
assertEquals(new String(inputStreamExpected.readAllBytes(), StandardCharsets.UTF_8), outputStream.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
-27
@@ -73,13 +73,13 @@ public class KMLTrackImporterTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals("", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("", importedTrack.getDescription());
|
||||
assertEquals("", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("", importedTrack.activityTypeLocalized());
|
||||
assertEquals("", importedTrack.description());
|
||||
assertEquals("", importedTrack.name());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.activityType());
|
||||
|
||||
// 2. markers
|
||||
assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size());
|
||||
assertEquals(0, TestDataUtil.getMarkers(contentProviderUtils, importTrackId).size());
|
||||
|
||||
// 3. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
@@ -129,13 +129,13 @@ public class KMLTrackImporterTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals("", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("", importedTrack.getDescription());
|
||||
assertEquals("", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("", importedTrack.activityTypeLocalized());
|
||||
assertEquals("", importedTrack.description());
|
||||
assertEquals("", importedTrack.name());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.activityType());
|
||||
|
||||
// 2. markers
|
||||
assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size());
|
||||
assertEquals(0, TestDataUtil.getMarkers(contentProviderUtils, importTrackId).size());
|
||||
|
||||
// 3. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
@@ -170,13 +170,14 @@ public class KMLTrackImporterTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals("unknown", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("Test Track", importedTrack.getDescription());
|
||||
assertEquals("2020-11-28 18:06", importedTrack.getName());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("unknown", importedTrack.activityTypeLocalized());
|
||||
assertEquals("Test Track", importedTrack.description());
|
||||
assertEquals("2020-11-28 18:06", importedTrack.name());
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.activityType());
|
||||
|
||||
// 2. markers
|
||||
assertEquals(1, contentProviderUtils.getMarkers(importTrackId).size());
|
||||
//TODO Check actual content (Marker should be record for this)
|
||||
assertEquals(1, TestDataUtil.getMarkers(contentProviderUtils, importTrackId).size());
|
||||
|
||||
// 3. trackpoints
|
||||
List<TrackPoint> importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId);
|
||||
@@ -189,24 +190,21 @@ public class KMLTrackImporterTest {
|
||||
12.340097, 1.234156, null,
|
||||
Altitude.WGS84.of(469.286376953125), null,
|
||||
null,
|
||||
Speed.of(0.539)))
|
||||
.setAltitudeGain(0f),
|
||||
Speed.of(0.539))),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-11-28T17:06:25.448Z"),
|
||||
12.340036, 1.23415, null,
|
||||
Altitude.WGS84.of(439.1626281738281), null,
|
||||
null,
|
||||
Speed.of(0.1577)))
|
||||
.setAltitudeGain(0f),
|
||||
Speed.of(0.1577))),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-11-28T17:06:47.888Z"),
|
||||
12.340057, 1.23405, null,
|
||||
Altitude.WGS84.of(421.8070983886719), null,
|
||||
null,
|
||||
Speed.of(0)))
|
||||
.setAltitudeGain(0f),
|
||||
Speed.ZERO)),
|
||||
// created resume trackpoint with time of next valid trackpoint
|
||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC,
|
||||
new Position(
|
||||
@@ -214,24 +212,21 @@ public class KMLTrackImporterTest {
|
||||
12.340057, 1.23405, null,
|
||||
Altitude.WGS84.of(419.93902587890625), null,
|
||||
null,
|
||||
Speed.of(0)))
|
||||
.setAltitudeGain(0f),
|
||||
Speed.ZERO)),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-11-28T17:06:56.905Z"),
|
||||
12.340057, 1.23405, null,
|
||||
Altitude.WGS84.of(419.9036560058594), null,
|
||||
null,
|
||||
Speed.of(0)))
|
||||
.setAltitudeGain(0f),
|
||||
Speed.ZERO)),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT,
|
||||
new Position(
|
||||
Instant.parse("2020-11-28T17:07:20.870Z"),
|
||||
12.340082, 1.234046, null,
|
||||
Altitude.WGS84.of(417.99432373046875), null,
|
||||
null,
|
||||
Speed.of(0)))
|
||||
.setAltitudeGain(0f)
|
||||
Speed.ZERO))
|
||||
), importedTrackPoints);
|
||||
}
|
||||
|
||||
|
||||
+27
-41
@@ -16,61 +16,47 @@ public class TrackPointAssert {
|
||||
public void assertEquals(TrackPoint expected, TrackPoint actual) {
|
||||
Assert.assertEquals("time", expected.getTime(), actual.getTime());
|
||||
|
||||
Assert.assertEquals("type", expected.getType(), actual.getType());
|
||||
Assert.assertEquals("type", expected.type(), actual.type());
|
||||
|
||||
Assert.assertEquals("has location,", expected.hasLocation(), actual.hasLocation());
|
||||
if (expected.hasLocation()) {
|
||||
Assert.assertEquals("latitude", expected.getPosition().latitude(), actual.getPosition().latitude(), 0.001);
|
||||
Assert.assertEquals("longitude", expected.getPosition().longitude(), actual.getPosition().longitude(), 0.001);
|
||||
Assert.assertEquals("has location,", expected.position().hasLocation(), actual.position().hasLocation());
|
||||
if (expected.position().hasLocation()) {
|
||||
Assert.assertEquals("latitude", expected.position().latitude(), actual.position().latitude(), 0.001);
|
||||
Assert.assertEquals("longitude", expected.position().longitude(), actual.position().longitude(), 0.001);
|
||||
}
|
||||
|
||||
Assert.assertEquals("has altitude", expected.hasAltitude(), actual.hasAltitude());
|
||||
if (expected.hasAltitude()) {
|
||||
Assert.assertEquals("altitude", expected.getAltitude().toM(), actual.getAltitude().toM(), delta);
|
||||
Assert.assertEquals("has altitude", expected.position().hasAltitude(), actual.position().hasAltitude());
|
||||
if (expected.position().hasAltitude()) {
|
||||
Assert.assertEquals("altitude", expected.position().altitude().toM(), actual.position().altitude().toM(), delta);
|
||||
}
|
||||
|
||||
Assert.assertEquals("has altitudeGain", expected.hasAltitudeGain(), actual.hasAltitudeGain());
|
||||
if (expected.hasAltitudeGain()) {
|
||||
Assert.assertEquals("altitudeGain", expected.getAltitudeGain(), actual.getAltitudeGain(), delta);
|
||||
}
|
||||
Assert.assertEquals("has altitudeLoss", expected.hasAltitudeLoss(), actual.hasAltitudeLoss());
|
||||
if (expected.hasAltitudeLoss()) {
|
||||
Assert.assertEquals("altitudeLoss", expected.getAltitudeLoss(), actual.getAltitudeLoss(), delta);
|
||||
Assert.assertEquals("altitudeGainLoss", expected.altitudeGainLoss(), actual.altitudeGainLoss());
|
||||
|
||||
Assert.assertEquals("has speed", expected.position().hasSpeed(), actual.position().hasSpeed());
|
||||
if (expected.position().hasSpeed()) {
|
||||
Assert.assertEquals("speed", expected.position().speed().toMPS(), actual.position().speed().toMPS(), delta);
|
||||
}
|
||||
|
||||
Assert.assertEquals("has speed", expected.hasSpeed(), actual.hasSpeed());
|
||||
if (expected.hasSpeed()) {
|
||||
Assert.assertEquals("speed", expected.getSpeed().toMPS(), actual.getSpeed().toMPS(), delta);
|
||||
Assert.assertEquals("has horizontalAccuracy", expected.position().hasHorizontalAccuracy(), actual.position().hasHorizontalAccuracy());
|
||||
if (expected.position().hasHorizontalAccuracy()) {
|
||||
Assert.assertEquals("horizontalAccuracy", expected.position().horizontalAccuracy().toM(), actual.position().horizontalAccuracy().toM(), delta);
|
||||
}
|
||||
Assert.assertEquals("has verticalAccuracy", expected.position().hasVerticalAccuracy(), actual.position().hasVerticalAccuracy());
|
||||
if (expected.position().hasVerticalAccuracy()) {
|
||||
Assert.assertEquals("verticalAccuracy", expected.position().verticalAccuracy().toM(), actual.position().verticalAccuracy().toM(), delta);
|
||||
}
|
||||
|
||||
Assert.assertEquals("has horizontalAccuracy", expected.hasHorizontalAccuracy(), actual.hasHorizontalAccuracy());
|
||||
if (expected.hasHorizontalAccuracy()) {
|
||||
Assert.assertEquals("horizontalAccuracy", expected.getHorizontalAccuracy().toM(), actual.getHorizontalAccuracy().toM(), delta);
|
||||
}
|
||||
Assert.assertEquals("has verticalAccuracy", expected.hasVerticalAccuracy(), actual.hasVerticalAccuracy());
|
||||
if (expected.hasVerticalAccuracy()) {
|
||||
Assert.assertEquals("verticalAccuracy", expected.getVerticalAccuracy().toM(), actual.getVerticalAccuracy().toM(), delta);
|
||||
Assert.assertEquals("has sensorDistance", expected.sensorDistance() != null, actual.sensorDistance() != null);
|
||||
if (expected.sensorDistance() != null) {
|
||||
Assert.assertEquals("sensorDistance", expected.sensorDistance().toM(), actual.sensorDistance().toM(), delta);
|
||||
}
|
||||
|
||||
Assert.assertEquals("has sensorDistance", expected.hasSensorDistance(), actual.hasSensorDistance());
|
||||
if (expected.hasSensorDistance()) {
|
||||
Assert.assertEquals("sensorDistance", expected.getSensorDistance().toM(), actual.getSensorDistance().toM(), delta);
|
||||
}
|
||||
Assert.assertEquals("heartRate", expected.heartRate(), actual.heartRate());
|
||||
|
||||
Assert.assertEquals("has heartrate", expected.hasHeartRate(), actual.hasHeartRate());
|
||||
if (expected.hasHeartRate()) {
|
||||
Assert.assertEquals("heartrate", expected.getHeartRate(), actual.getHeartRate());
|
||||
}
|
||||
Assert.assertEquals("temperature", expected.temperature(), actual.temperature());
|
||||
|
||||
Assert.assertEquals("has power", expected.hasPower(), actual.hasPower());
|
||||
if (expected.hasPower()) {
|
||||
Assert.assertEquals("power", expected.getPower(), actual.getPower());
|
||||
}
|
||||
Assert.assertEquals("power", expected.power(), actual.power());
|
||||
|
||||
Assert.assertEquals("has cadence", expected.hasCadence(), actual.hasCadence());
|
||||
if (expected.hasCadence()) {
|
||||
Assert.assertEquals("cadence", expected.getCadence(), actual.getCadence());
|
||||
}
|
||||
Assert.assertEquals("cadence", expected.cadence(), actual.cadence());
|
||||
}
|
||||
|
||||
public void assertEquals(List<TrackPoint> expected, List<TrackPoint> actual) {
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
package de.dennisguse.opentracks.publicapi;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DataProviderTest {
|
||||
|
||||
private final ContentResolver resolver = ApplicationProvider.getApplicationContext().getContentResolver();
|
||||
|
||||
@Test
|
||||
public void supportsVersion2_tracks() {
|
||||
// given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/tracks/1");
|
||||
String[] expectedTracksColumns = new String[]{
|
||||
"_id",
|
||||
"name",
|
||||
"description",
|
||||
"category",
|
||||
"activity_type_localized",
|
||||
"starttime",
|
||||
"stoptime",
|
||||
"totaltime",
|
||||
"movingtime",
|
||||
"totaldistance",
|
||||
"maxspeed",
|
||||
"avgspeed",
|
||||
"avgmovingspeed",
|
||||
"minelevation",
|
||||
"maxelevation",
|
||||
"elevationgain",
|
||||
"elevationloss"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedTracksColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
// then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.track", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedTracksColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion2_trackpoints() {
|
||||
// given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/trackpoints/1");
|
||||
String[] expectedTrackpointsColumns = {
|
||||
"_id",
|
||||
"trackid",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"time",
|
||||
"type",
|
||||
"speed"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedTrackpointsColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
// then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.trackpoint", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedTrackpointsColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion2_markers() {
|
||||
// given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/markers/1");
|
||||
String[] expectedMarkersColumns = {
|
||||
"_id",
|
||||
"name",
|
||||
"description",
|
||||
"category",
|
||||
"trackid",
|
||||
"longitude",
|
||||
"latitude",
|
||||
"photoUrl",
|
||||
"icon"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedMarkersColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
// then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.waypoint", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedMarkersColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion3_tracks() {
|
||||
// given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/tracks/1");
|
||||
String[] expectedTracksColumns = {
|
||||
"_id",
|
||||
"name",
|
||||
"description",
|
||||
"activity_type",
|
||||
"activity_type_localized",
|
||||
"time_start",
|
||||
"time_stop",
|
||||
"duration_total",
|
||||
"duration_moving",
|
||||
"distance",
|
||||
"speed_max",
|
||||
"altitude_min",
|
||||
"altitude_max",
|
||||
"altitude_gain",
|
||||
"altitude_loss"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedTracksColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
// then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.track", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedTracksColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion3_trackpoints() {
|
||||
//given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/trackpoints/1");
|
||||
String[] expectedTrackpointsColumns = {
|
||||
"_id",
|
||||
"trackid",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"time",
|
||||
"type",
|
||||
"speed"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedTrackpointsColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
//then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.trackpoint", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedTrackpointsColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion3_markers() {
|
||||
// given
|
||||
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/dashboard/markers/1");
|
||||
String[] expectedMarkersColumns = {
|
||||
"_id",
|
||||
"name",
|
||||
"description",
|
||||
"marker_type_localized",
|
||||
"trackid",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"photoUrl"
|
||||
};
|
||||
|
||||
// when
|
||||
try (Cursor cursor = resolver.query(
|
||||
uri,
|
||||
expectedMarkersColumns,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)) {
|
||||
// then
|
||||
assertEquals("vnd.android.cursor.dir/vnd.de.dennisguse.waypoint", resolver.getType(uri));
|
||||
|
||||
assertNotNull(cursor);
|
||||
assertArrayEquals(expectedMarkersColumns, cursor.getColumnNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,9 +49,9 @@ public class PublicApiTest {
|
||||
List<Track> tracks = new ContentProviderUtils(context).getTracks();
|
||||
Assert.assertEquals(1, tracks.size());
|
||||
Track track = tracks.get(0);
|
||||
Assert.assertEquals("trackName", track.getName());
|
||||
Assert.assertEquals("activityTypeLocalized", track.getActivityTypeLocalized());
|
||||
Assert.assertEquals("airplane", track.getActivityType().getId());
|
||||
Assert.assertEquals("trackName", track.name());
|
||||
Assert.assertEquals("activityTypeLocalized", track.activityTypeLocalized());
|
||||
Assert.assertEquals("airplane", track.activityType().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user