diff options
| -rw-r--r-- | main/src/cgeo/geocaching/geopoint/HumanDistance.java | 64 | ||||
| -rw-r--r-- | tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java | 37 |
2 files changed, 64 insertions, 37 deletions
diff --git a/main/src/cgeo/geocaching/geopoint/HumanDistance.java b/main/src/cgeo/geocaching/geopoint/HumanDistance.java index 3c40555..25d1bb7 100644 --- a/main/src/cgeo/geocaching/geopoint/HumanDistance.java +++ b/main/src/cgeo/geocaching/geopoint/HumanDistance.java @@ -2,44 +2,48 @@ package cgeo.geocaching.geopoint; import cgeo.geocaching.Settings; +import org.apache.commons.lang3.tuple.ImmutablePair; + public class HumanDistance { - public static String getHumanDistance(final Float distanceKilometers) { - if (distanceKilometers == null) { - return "?"; - } + public static ImmutablePair<Double, String> scaleUnit(final double distanceKilometers) { + double distance; + String units; if (Settings.isUseMetricUnits()) { - if (distanceKilometers > 100) { - return String.format("%d", Math.round(distanceKilometers)) + " km"; - } else if (distanceKilometers > 10) { - return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 10.0) / 10.0)) + " km"; - } else if (distanceKilometers > 1) { - return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 100.0) / 100.0)) + " km"; - } else if (distanceKilometers > 0.1) { - return String.format("%d", Math.round(distanceKilometers * 1000.0)) + " m"; - } else if (distanceKilometers > 0.01) { - return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 10.0) / 10.0)) + " m"; + if (distanceKilometers >= 1) { + distance = distanceKilometers; + units = "km"; } else { - return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 100.0) / 100.0)) + " m"; + distance = distanceKilometers * 1000; + units = "m"; } } else { - final float miles = distanceKilometers / IConversion.MILES_TO_KILOMETER; - if (miles > 100) { - return String.format("%d", Math.round(miles)) + " mi"; - } else if (miles > 0.5) { - return String.format("%.1f", Double.valueOf(Math.round(miles * 10.0) / 10.0)) + " mi"; - } else if (miles > 0.1) { - return String.format("%.2f", Double.valueOf(Math.round(miles * 100.0) / 100.0)) + " mi"; - } - - final float feet = miles * 5280; - if (feet >= 100) { - return String.format("%d", Math.round(feet)) + " ft"; - } else if (feet >= 10) { - return String.format("%.1f", Double.valueOf(Math.round(feet * 10.0) / 10.0)) + " ft"; + distance = distanceKilometers / IConversion.MILES_TO_KILOMETER; + if (distance >= 0.1) { + units = "mi"; } else { - return String.format("%.2f", Double.valueOf(Math.round(feet * 100.0) / 100.0)) + " ft"; + distance *= 5280; + units = "ft"; } } + return new ImmutablePair<Double, String>(distance, units); + } + + public static String getHumanDistance(final Float distanceKilometers) { + if (distanceKilometers == null) { + return "?"; + } + + final ImmutablePair<Double, String> scaled = scaleUnit(distanceKilometers); + String formatString; + if (scaled.left >= 100) { + formatString = "%.0f"; + } else if (scaled.left >= 10) { + formatString = "%.1f"; + } else { + formatString = "%.2f"; + } + + return String.format(formatString + " %s", scaled.left, scaled.right); } } diff --git a/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java b/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java index 3c7cb98..0532495 100644 --- a/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java +++ b/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java @@ -4,16 +4,39 @@ import cgeo.geocaching.Settings; import android.test.AndroidTestCase; +import java.util.regex.Pattern; + public class HumanDistanceTest extends AndroidTestCase { - public static void testHumanDistance() { - assertEquals("?", HumanDistance.getHumanDistance(null)); - if (Settings.isUseMetricUnits()) { - assertEquals("123 km", HumanDistance.getHumanDistance(123.456f)); - assertEquals("123 m", HumanDistance.getHumanDistance(0.123456f)); + private static void assertMatch(final String ok, final float distance) { + final String humanDistance = HumanDistance.getHumanDistance(distance); + if (!Pattern.compile('^' + ok + '$').matcher(humanDistance).find()) { + fail("getHumanDistance(" + distance + + ") [metric: " + (Settings.isUseMetricUnits() ? "yes" : "no") + + "] fails to match " + ok + ": " + humanDistance); } - else { - assertEquals("77 mi", HumanDistance.getHumanDistance(123.456f)); + } + + // Make method non-static so that Settings is initialized + @SuppressWarnings("static-method") + public void testHumanDistance() { + assertEquals("?", HumanDistance.getHumanDistance(null)); + final boolean savedMetrics = Settings.isUseMetricUnits(); + try { + Settings.setUseMetricUnits(true); + assertMatch("123 km", 122.782f); + assertMatch("123 km", 123.456f); + assertMatch("12.3 km", 12.3456f); + assertMatch("1.23 km", 1.23456f); + assertMatch("123 m", 0.123456f); + Settings.setUseMetricUnits(false); + assertMatch("76.7 mi", 123.456f); + assertMatch("7.67 mi", 12.3456f); + assertMatch("0.77 mi", 1.23456f); + assertMatch("405 ft", 0.123456f); + assertMatch("40.5 ft", 0.0123456f); + } finally { + Settings.setUseMetricUnits(savedMetrics); } } } |
