kopia lustrzana https://github.com/ge0rg/aprsdroid
Refactored code to support unit testing of coordinates as well as instrumented
rodzic
1df09f4bed
commit
b491e99058
|
@ -1,9 +1,7 @@
|
||||||
package org.aprsdroid.app.testing;
|
package org.aprsdroid.app.testing;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -12,47 +10,7 @@ import androidx.test.espresso.ViewAssertion;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class DMSLocationAssertion implements ViewAssertion {
|
public class DMSLocationAssertion implements ViewAssertion {
|
||||||
private static final String NUMBER = "(-?\\d+(?:\\.\\d*)?)";
|
|
||||||
private static final String dms_latitude_pattern = NUMBER + "°\\s*" + NUMBER + "'\\s*" + NUMBER + "\"\\s*([NS])";
|
|
||||||
private static final String dms_longitude_pattern = NUMBER + "°\\s*" + NUMBER + "'\\s*" + NUMBER + "\"\\s*([EW])";
|
|
||||||
private static final Pattern dms_latitude_regex = Pattern.compile(dms_latitude_pattern, Pattern.CASE_INSENSITIVE);
|
|
||||||
private static final Pattern dms_longitude_regex = Pattern.compile(dms_longitude_pattern, Pattern.CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
private static float convertField(Matcher matcher, String name) {
|
|
||||||
float value = 0;
|
|
||||||
try {
|
|
||||||
int degrees = Integer.parseInt(Objects.requireNonNull(matcher.group(1)));
|
|
||||||
Assert.assertThat(name + " degrees", degrees, greaterThanOrEqualTo(0));
|
|
||||||
value = (float) degrees;
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
Assert.fail(name + " degree field not an integer");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
int minutes = Integer.parseInt(Objects.requireNonNull(matcher.group(2)));
|
|
||||||
Assert.assertThat(name + " minutes", minutes, greaterThanOrEqualTo(0));
|
|
||||||
value += (float) minutes / 60.0f;
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
Assert.fail(name + " minute field not an integer");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
float seconds = Float.parseFloat(Objects.requireNonNull(matcher.group(3)));
|
|
||||||
Assert.assertThat(name + " seconds", seconds, greaterThanOrEqualTo(0.0f));
|
|
||||||
value += seconds / 3600.0f;
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
Assert.fail(name + " seconds field not an number");
|
|
||||||
}
|
|
||||||
String direction = Objects.requireNonNull(matcher.group(4));
|
|
||||||
if (direction.equalsIgnoreCase("S") || direction.equalsIgnoreCase("W")) {
|
|
||||||
value *= -1.0f;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkCoordinates(float latitude, float longitude) {
|
protected void checkCoordinates(float latitude, float longitude) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,14 +20,8 @@ public class DMSLocationAssertion implements ViewAssertion {
|
||||||
throw noViewFoundException;
|
throw noViewFoundException;
|
||||||
Assert.assertThat(view, instanceOf(TextView.class));
|
Assert.assertThat(view, instanceOf(TextView.class));
|
||||||
TextView text = (TextView) view;
|
TextView text = (TextView) view;
|
||||||
Matcher latitude_match = dms_latitude_regex.matcher(text.getText());
|
float latitude = CoordinateMatcher.matchLatitude(text.getText());
|
||||||
Matcher longitude_match = dms_longitude_regex.matcher(text.getText());
|
float longitude = CoordinateMatcher.matchLongitude(text.getText());
|
||||||
Assert.assertTrue("Latitude not found", latitude_match.find());
|
|
||||||
Assert.assertTrue("Longitude not found", longitude_match.find());
|
|
||||||
Log.d("TAG-Map", "StrLat: " + latitude_match.group(0));
|
|
||||||
Log.d("TAG-Map", "StrLon: " + longitude_match.group(0));
|
|
||||||
float latitude = convertField(latitude_match, "Latitude");
|
|
||||||
float longitude = convertField(longitude_match, "Longitude");
|
|
||||||
checkCoordinates(latitude, longitude);
|
checkCoordinates(latitude, longitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,10 +140,10 @@ android {
|
||||||
jniLibs.srcDirs = ['libs']
|
jniLibs.srcDirs = ['libs']
|
||||||
}
|
}
|
||||||
androidTest {
|
androidTest {
|
||||||
java.srcDirs = ['androidTest/java']
|
java.srcDirs = ['androidTest/java', 'sharedTest/java']
|
||||||
}
|
}
|
||||||
test {
|
test {
|
||||||
java.srcDirs = ['test/java']
|
java.srcDirs = ['test/java', 'sharedTest/java']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lintOptions {
|
lintOptions {
|
||||||
|
@ -169,6 +169,8 @@ dependencies {
|
||||||
implementation 'com.squareup.okio:okio:2.1.0'
|
implementation 'com.squareup.okio:okio:2.1.0'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.13.1'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
|
testImplementation 'org.hamcrest:hamcrest-core:1.3'
|
||||||
|
testImplementation 'org.hamcrest:hamcrest-library:1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||||
androidTestImplementation 'androidx.test:rules:1.4.0'
|
androidTestImplementation 'androidx.test:rules:1.4.0'
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.aprsdroid.app.testing;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CoordinateMatcher {
|
||||||
|
private static final String NUMBER = "(-?\\d+(?:\\.\\d*)?)";
|
||||||
|
private static final String dms_latitude_pattern = NUMBER + "°\\s*" + NUMBER + "'\\s*" + NUMBER + "\"\\s*([NS])";
|
||||||
|
private static final String dms_longitude_pattern = NUMBER + "°\\s*" + NUMBER + "'\\s*" + NUMBER + "\"\\s*([EW])";
|
||||||
|
private static final Pattern dms_latitude_regex = Pattern.compile(dms_latitude_pattern, Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final Pattern dms_longitude_regex = Pattern.compile(dms_longitude_pattern, Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
private static float convertField(CharSequence string, Pattern regex, String name) {
|
||||||
|
Matcher matcher = regex.matcher(string);
|
||||||
|
Assert.assertTrue(name + " not found", matcher.find());
|
||||||
|
float value = 0;
|
||||||
|
try {
|
||||||
|
int degrees = Integer.parseInt(Objects.requireNonNull(matcher.group(1)));
|
||||||
|
Assert.assertThat(name + " degrees", degrees, greaterThanOrEqualTo(0));
|
||||||
|
value = (float) degrees;
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Assert.fail(name + " degree field not an integer");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int minutes = Integer.parseInt(Objects.requireNonNull(matcher.group(2)));
|
||||||
|
Assert.assertThat(name + " minutes", minutes, greaterThanOrEqualTo(0));
|
||||||
|
value += (float) minutes / 60.0f;
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Assert.fail(name + " minute field not an integer");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
float seconds = Float.parseFloat(Objects.requireNonNull(matcher.group(3)));
|
||||||
|
Assert.assertThat(name + " seconds", seconds, greaterThanOrEqualTo(0.0f));
|
||||||
|
value += seconds / 3600.0f;
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Assert.fail(name + " seconds field not an number");
|
||||||
|
}
|
||||||
|
String direction = Objects.requireNonNull(matcher.group(4));
|
||||||
|
if (direction.equalsIgnoreCase("S") || direction.equalsIgnoreCase("W")) {
|
||||||
|
value *= -1.0f;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float matchLatitude(CharSequence string) {
|
||||||
|
return convertField(string, dms_latitude_regex, "Latitude");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float matchLongitude(CharSequence string) {
|
||||||
|
return convertField(string, dms_longitude_regex, "Longitude");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package org.aprsdroid.app;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.closeTo;
|
||||||
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import org.aprsdroid.app.testing.CoordinateMatcher;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CoordinateTest {
|
||||||
|
// Reference data generated from https://www.pgc.umn.edu/apps/convert/
|
||||||
|
private static final String providedNLatitude = "77° 15' 30\" N";
|
||||||
|
private static final float expectedNLatitude = 77.258333f;
|
||||||
|
private static final String providedELongitude = "164° 45' 15\" E";
|
||||||
|
private static final float expectedELongitude = 164.754167f;
|
||||||
|
private static final String providedSLatitude = "45° 30' 45\" S";
|
||||||
|
private static final float expectedSLatitude = -45.5125f;
|
||||||
|
private static final String providedWLongitude = "97° 20' 40\" W";
|
||||||
|
private static final float expectedWLongitude = -97.344444f;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDMSLatitudeInN_whenParsingString_ThenShouldMatchDecimal() {
|
||||||
|
float value = CoordinateMatcher.matchLatitude(providedNLatitude);
|
||||||
|
assertThat("Latitude", (double)value, closeTo((double)expectedNLatitude, 1e-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDMSLongitudeInE_whenParsingString_ThenShouldMatchDecimal() {
|
||||||
|
float value = CoordinateMatcher.matchLongitude(providedELongitude);
|
||||||
|
assertThat("Longitude", (double)value, closeTo((double)expectedELongitude, 1e-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDMSLatitudeInS_whenParsingString_ThenShouldMatchDecimal() {
|
||||||
|
float value = CoordinateMatcher.matchLatitude(providedSLatitude);
|
||||||
|
assertThat("Latitude", (double)value, closeTo((double)expectedSLatitude, 1e-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDMSLongitudeInW_whenParsingString_ThenShouldMatchDecimal() {
|
||||||
|
float value = CoordinateMatcher.matchLongitude(providedWLongitude);
|
||||||
|
assertThat("Longitude", (double)value, closeTo((double)expectedWLongitude, 1e-7));
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue