diff --git a/changelog/unreleased/bugfixes/dd.md b/changelog/unreleased/bugfixes/dd.md new file mode 100644 index 00000000000..36c084da236 --- /dev/null +++ b/changelog/unreleased/bugfixes/dd.md @@ -0,0 +1 @@ +- Supported displaying distances in yards for imperial UnitType in the UK locale. \ No newline at end of file diff --git a/libnavigation-core/api/current.txt b/libnavigation-core/api/current.txt index a11b0c34ac1..47d54b397a1 100644 --- a/libnavigation-core/api/current.txt +++ b/libnavigation-core/api/current.txt @@ -240,6 +240,7 @@ package com.mapbox.navigation.core.formatter { public final class MapboxDistanceUtil { method public com.mapbox.navigation.core.formatter.FormattedDistanceData formatDistance(double distanceInMeters, int roundingIncrement, com.mapbox.navigation.base.formatter.UnitType unitType, android.content.Context context, java.util.Locale locale); method public com.mapbox.navigation.core.formatter.FormattedDistanceData formatDistance(double distanceInMeters, int roundingIncrement, com.mapbox.navigation.base.formatter.UnitType unitType, android.content.Context context); + method public double formatDistance(double distanceInMeters, int roundingIncrement, com.mapbox.navigation.base.formatter.UnitType unitType, java.util.Locale locale = Locale.getDefault()); method public double formatDistance(double distanceInMeters, int roundingIncrement, com.mapbox.navigation.base.formatter.UnitType unitType); field public static final com.mapbox.navigation.core.formatter.MapboxDistanceUtil INSTANCE; } diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtil.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtil.kt index f61bfaa95a7..83e824e83a8 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtil.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtil.kt @@ -16,10 +16,7 @@ import kotlin.math.roundToInt */ object MapboxDistanceUtil { - private const val SMALL_DISTANCE_LOWER_BOUND_IN_MILES = 0.1 - private const val MEDIUM_DISTANCE_LOWER_BOUND_IN_MILES = 10.0 - private const val SMALL_DISTANCE_UPPER_THRESHOLD_IN_METERS = 400.0 - private const val MEDIUM_DISTANCE_UPPER_THRESHOLD_IN_METERS = 10000.0 + private val enLanguage = Locale("en").language /** * This will recalculate and format a distance based on the parameters inputted. The value @@ -39,38 +36,204 @@ object MapboxDistanceUtil { context: Context, locale: Locale ): FormattedDistanceData { - return when (getFormattingRange(distanceInMeters, unitType)) { - FormattingRange.INVALID -> formatDistanceAndSuffixForSmallUnit( + val formattingData = getFormattingData( + distanceInMeters, + roundingIncrement, + unitType, + locale + ) + val resources = context.applicationContext.resourcesWithLocale(locale) + val unitStringSuffix = getUnitString(resources, formattingData.turfDistanceUnit) + return FormattedDistanceData( + formattingData.distance, + formattingData.distanceAsString, + unitStringSuffix, + formattingData.unitType + ) + } + + private fun getFormattingData( + distanceInMeters: Double, + roundingIncrement: Int, + unitType: UnitType, + locale: Locale + ): FormattingData { + return when (unitType) { + UnitType.METRIC -> getMetricDistance(distanceInMeters, roundingIncrement, locale) + UnitType.IMPERIAL -> { + val distanceInMiles = TurfConversion.convertLength( + distanceInMeters, + TurfConstants.UNIT_METERS, + TurfConstants.UNIT_MILES + ) + if (locale.language == enLanguage && locale.country == "GB") { + getUKDistance(distanceInMiles, roundingIncrement, locale) + } else { + getUSDistance(distanceInMiles, roundingIncrement, locale) + } + } + } + } + + private fun getMetricDistance( + distanceInMeters: Double, + roundingIncrement: Int, + locale: Locale + ): FormattingData { + return when { + distanceInMeters !in 0.0..Double.MAX_VALUE -> smallValue( 0.0, roundingIncrement, - unitType, - context, - locale + TurfConstants.UNIT_METERS, + UnitType.METRIC ) - FormattingRange.SMALL -> formatDistanceAndSuffixForSmallUnit( + distanceInMeters < 1000.0 -> smallValue( distanceInMeters, roundingIncrement, - unitType, - context, + TurfConstants.UNIT_METERS, + UnitType.METRIC + ) + else -> { + val distanceInKm = TurfConversion.convertLength( + distanceInMeters, + TurfConstants.UNIT_METERS, + TurfConstants.UNIT_KILOMETERS + ) + when { + distanceInMeters < 3000.0 -> largeValue( + distanceInKm, + 1, + TurfConstants.UNIT_KILOMETERS, + UnitType.METRIC, + locale + ) + else -> largeValue( + distanceInKm, + 0, + TurfConstants.UNIT_KILOMETERS, + UnitType.METRIC, + locale + ) + } + } + } + } + + private fun getUKDistance( + distanceInMiles: Double, + roundingIncrement: Int, + locale: Locale + ): FormattingData { + return when { + distanceInMiles !in 0.0..Double.MAX_VALUE -> smallValue( + 0.0, + roundingIncrement, + TurfConstants.UNIT_YARDS, + UnitType.IMPERIAL + ) + distanceInMiles < 0.1 -> { + val distanceInYards = TurfConversion.convertLength( + distanceInMiles, + TurfConstants.UNIT_MILES, + TurfConstants.UNIT_YARDS + ) + smallValue( + distanceInYards, + roundingIncrement, + TurfConstants.UNIT_YARDS, + UnitType.IMPERIAL + ) + } + distanceInMiles < 3.0 -> largeValue( + distanceInMiles, + 1, + TurfConstants.UNIT_MILES, + UnitType.IMPERIAL, locale ) - FormattingRange.MEDIUM -> formatDistanceAndSuffixForLargeUnit( - distanceInMeters, + else -> largeValue( + distanceInMiles, + 0, + TurfConstants.UNIT_MILES, + UnitType.IMPERIAL, + locale + ) + } + } + + private fun getUSDistance( + distanceInMiles: Double, + roundingIncrement: Int, + locale: Locale, + ): FormattingData { + return when { + distanceInMiles !in 0.0..Double.MAX_VALUE -> smallValue( + 0.0, + roundingIncrement, + TurfConstants.UNIT_FEET, + UnitType.IMPERIAL + ) + distanceInMiles < 0.1 -> { + val distanceInFeet = TurfConversion.convertLength( + distanceInMiles, + TurfConstants.UNIT_MILES, + TurfConstants.UNIT_FEET + ) + smallValue( + distanceInFeet, + roundingIncrement, + TurfConstants.UNIT_FEET, + UnitType.IMPERIAL + ) + } + distanceInMiles < 3.0 -> largeValue( + distanceInMiles, 1, - unitType, - context, + TurfConstants.UNIT_MILES, + UnitType.IMPERIAL, locale ) - FormattingRange.LARGE -> formatDistanceAndSuffixForLargeUnit( - distanceInMeters, + else -> largeValue( + distanceInMiles, 0, - unitType, - context, + TurfConstants.UNIT_MILES, + UnitType.IMPERIAL, locale ) } } + private fun smallValue( + distance: Double, + roundingIncrement: Int, + unitTypeString: String, + unitType: UnitType + ): FormattingData { + val roundedValue = roundSmallDistance( + distance, + roundingIncrement, + ) + return FormattingData( + roundedValue.toDouble(), + roundedValue.toString(), + unitTypeString, + unitType + ) + } + + private fun largeValue( + distance: Double, + maxFractionDigits: Int, + unitTypeString: String, + unitType: UnitType, + locale: Locale + ): FormattingData { + val roundedValue = NumberFormat.getNumberInstance(locale).also { + it.maximumFractionDigits = maxFractionDigits + }.format(distance) + return FormattingData(distance, roundedValue, unitTypeString, unitType) + } + /** * This will recalculate and format a distance based on the parameters inputted. The value * will be rounded for visual display and a distance suffix like 'km' for kilometers or 'ft' for foot/feet will be included. @@ -105,132 +268,44 @@ object MapboxDistanceUtil { * @param unitType indicates whether the value should be returned as metric or imperial * @return an object containing values for displaying the formatted distance */ + @JvmOverloads fun formatDistance( distanceInMeters: Double, roundingIncrement: Int, - unitType: UnitType + unitType: UnitType, + locale: Locale = Locale.getDefault() ): Double { - return when (getFormattingRange(distanceInMeters, unitType)) { - FormattingRange.INVALID -> { - roundSmallDistance(distanceInMeters, roundingIncrement, unitType).toDouble() - } - FormattingRange.SMALL -> { - roundSmallDistance(distanceInMeters, roundingIncrement, unitType).toDouble() - } - FormattingRange.MEDIUM -> { - roundLargeDistance(distanceInMeters, unitType) - } - FormattingRange.LARGE -> { - roundLargeDistance(distanceInMeters, unitType) - } - } + return getFormattingData(distanceInMeters, roundingIncrement, unitType, locale).distance } private fun roundSmallDistance( distance: Double, roundingIncrement: Int, - unitType: UnitType ): Int { if (distance < 0) { return 0 } - val distanceUnit = TurfConversion.convertLength( - distance, - TurfConstants.UNIT_METERS, - getSmallTurfUnitType(unitType) - ) - val roundedValue = if (roundingIncrement > 0) { - val roundedDistance = distanceUnit.roundToInt() + val roundedDistance = distance.roundToInt() if (roundedDistance < roundingIncrement) { roundingIncrement } else { roundedDistance / roundingIncrement * roundingIncrement } } else { - distanceUnit + distance } return roundedValue.toInt() } - private fun roundLargeDistance( - distance: Double, - unitType: UnitType - ): Double { - return TurfConversion.convertLength( - distance, - TurfConstants.UNIT_METERS, - getLargeTurfUnitType(unitType) - ) - } - - private fun formatDistanceAndSuffixForSmallUnit( - distance: Double, - roundingIncrement: Int, - unitType: UnitType, - context: Context, - locale: Locale - ): FormattedDistanceData { - val resources = context.applicationContext.resourcesWithLocale(locale) - val unitStringSuffix = getUnitString(resources, getSmallTurfUnitType(unitType)) - if (distance < 0) { - return FormattedDistanceData(0.0, "0", unitStringSuffix, unitType) - } - val roundedValue = roundSmallDistance( - distance, - roundingIncrement, - unitType - ) - - return FormattedDistanceData( - roundedValue.toDouble(), - roundedValue.toString(), - unitStringSuffix, - unitType - ) - } - - private fun formatDistanceAndSuffixForLargeUnit( - distance: Double, - maxFractionDigits: Int, - unitType: UnitType, - context: Context, - locale: Locale - ): FormattedDistanceData { - val resources = context.applicationContext.resourcesWithLocale(locale) - val unitStringSuffix = getUnitString(resources, getLargeTurfUnitType(unitType)) - val distanceUnit = roundLargeDistance( - distance, - unitType - ) - val roundedValue = NumberFormat.getNumberInstance(locale).also { - it.maximumFractionDigits = maxFractionDigits - }.format(distanceUnit) - - return FormattedDistanceData(distanceUnit, roundedValue, unitStringSuffix, unitType) - } - - private fun getSmallTurfUnitType(unitType: UnitType): String { - return when (unitType) { - UnitType.IMPERIAL -> TurfConstants.UNIT_FEET - UnitType.METRIC -> TurfConstants.UNIT_METERS - } - } - - private fun getLargeTurfUnitType(unitType: UnitType): String { - return when (unitType) { - UnitType.IMPERIAL -> TurfConstants.UNIT_MILES - UnitType.METRIC -> TurfConstants.UNIT_KILOMETERS - } - } - private fun getUnitString(resources: Resources, @TurfConstants.TurfUnitCriteria unit: String) = when (unit) { TurfConstants.UNIT_KILOMETERS -> resources.getString(R.string.mapbox_unit_kilometers) TurfConstants.UNIT_METERS -> resources.getString(R.string.mapbox_unit_meters) TurfConstants.UNIT_MILES -> resources.getString(R.string.mapbox_unit_miles) TurfConstants.UNIT_FEET -> resources.getString(R.string.mapbox_unit_feet) + TurfConstants.UNIT_YARDS -> resources.getString(R.string.mapbox_unit_yards) else -> "" } @@ -241,41 +316,10 @@ object MapboxDistanceUtil { return this.createConfigurationContext(config).resources } - private enum class FormattingRange { INVALID, SMALL, MEDIUM, LARGE } - - private fun getFormattingRange( - distanceInMeters: Double, - unitType: UnitType - ): FormattingRange { - if (distanceInMeters !in 0.0..Double.MAX_VALUE) { - return FormattingRange.INVALID - } - return when (unitType) { - UnitType.METRIC -> metricRange(distanceInMeters) - UnitType.IMPERIAL -> { - val distanceInMiles = TurfConversion.convertLength( - distanceInMeters, - TurfConstants.UNIT_METERS, - getLargeTurfUnitType(unitType) - ) - imperialRange(distanceInMiles) - } - } - } - - private fun metricRange(distance: Double): FormattingRange = when (distance) { - in 0.0..SMALL_DISTANCE_UPPER_THRESHOLD_IN_METERS -> FormattingRange.SMALL - in SMALL_DISTANCE_UPPER_THRESHOLD_IN_METERS..MEDIUM_DISTANCE_UPPER_THRESHOLD_IN_METERS -> - FormattingRange.MEDIUM - else -> FormattingRange.LARGE - } - - private fun imperialRange(distance: Double): FormattingRange { - return when (distance) { - in 0.0..SMALL_DISTANCE_LOWER_BOUND_IN_MILES -> FormattingRange.SMALL - in SMALL_DISTANCE_LOWER_BOUND_IN_MILES..MEDIUM_DISTANCE_LOWER_BOUND_IN_MILES -> - FormattingRange.MEDIUM - else -> FormattingRange.LARGE - } - } + private data class FormattingData( + val distance: Double, + val distanceAsString: String, + val turfDistanceUnit: String, + val unitType: UnitType, + ) } diff --git a/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceFormatterTest.kt b/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceFormatterTest.kt index 2390af88986..4b66305aa90 100644 --- a/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceFormatterTest.kt +++ b/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceFormatterTest.kt @@ -141,9 +141,9 @@ class MapboxDistanceFormatterTest { .unitType(UnitType.METRIC) .roundingIncrement(INCREMENT_FIFTY) .build() - ).formatDistance(400.5) + ).formatDistance(1200.5) - assertEquals("0.4 km", result.toString()) + assertEquals("1.2 km", result.toString()) } @Config(qualifiers = "en") diff --git a/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtilTest.kt b/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtilTest.kt index 5f60bd7c80b..747fa8b0882 100644 --- a/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtilTest.kt +++ b/libnavigation-core/src/test/java/com/mapbox/navigation/core/formatter/MapboxDistanceUtilTest.kt @@ -39,6 +39,54 @@ class MapboxDistanceUtilTest { assertEquals(12.0, result.distance, 0.1) } + @Config(qualifiers = "en") + @Test + fun `formatDistance large at lower bound value imperial with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 4828.03, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("3", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(3.0, result.distance, 0.1) + } + + @Config(qualifiers = "en") + @Test + fun `formatDistance large value UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 19312.1, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("12", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(12.0, result.distance, 0.1) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance large value UK at lower bound with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 4828.03, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("3", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(3.0, result.distance, 0.1) + } + @Config(qualifiers = "en") @Test fun `formatDistance large value metric with default locale`() { @@ -55,6 +103,22 @@ class MapboxDistanceUtilTest { assertEquals(19.3121, result.distance, 0.0) } + @Config(qualifiers = "en") + @Test + fun `formatDistance large value metric at lower bound with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 3000.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC, + ctx + ) + + assertEquals("3", result.distanceAsString) + assertEquals("km", result.distanceSuffix) + assertEquals(UnitType.METRIC, result.unitType) + assertEquals(3.0, result.distance, 0.0) + } + @Config(qualifiers = "en") @Test fun `formatDistance large value metric that is medium for imperial with default locale`() { @@ -87,6 +151,38 @@ class MapboxDistanceUtilTest { assertEquals(50.0, result.distance, 0.0) } + @Config(qualifiers = "en") + @Test + fun `formatDistance small value metric at lower bound with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 0.0, + Rounding.INCREMENT_FIVE, + UnitType.METRIC, + ctx + ) + + assertEquals("5", result.distanceAsString) + assertEquals("m", result.distanceSuffix) + assertEquals(UnitType.METRIC, result.unitType) + assertEquals(5.0, result.distance, 0.0) + } + + @Config(qualifiers = "en") + @Test + fun `formatDistance small value metric at upper bound with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 999.999, + Rounding.INCREMENT_FIVE, + UnitType.METRIC, + ctx + ) + + assertEquals("1000", result.distanceAsString) + assertEquals("m", result.distanceSuffix) + assertEquals(UnitType.METRIC, result.unitType) + assertEquals(1000.0, result.distance, 0.0) + } + @Config(qualifiers = "en") @Test fun `formatDistance small value metric that is medium for imperial with default locale`() { @@ -121,18 +217,81 @@ class MapboxDistanceUtilTest { @Config(qualifiers = "en") @Test - fun `formatDistance small value close to upper bound imperial with default locale`() { + fun `formatDistance small value imperial at lower bound with default locale`() { val result = MapboxDistanceUtil.formatDistance( - 150.0, + 0.0, Rounding.INCREMENT_FIVE, UnitType.IMPERIAL, ctx ) - assertEquals("490", result.distanceAsString) + assertEquals("5", result.distanceAsString) assertEquals("ft", result.distanceSuffix) assertEquals(UnitType.IMPERIAL, result.unitType) - assertEquals(490.0, result.distance, 0.1) + assertEquals(5.0, result.distance, 0.0) + } + + @Test + fun `formatDistance small value imperial at upper bound with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 160.5, + Rounding.INCREMENT_FIVE, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("525", result.distanceAsString) + assertEquals("ft", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(525.0, result.distance, 0.1) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance small value UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 101.0, + Rounding.INCREMENT_FIVE, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("110", result.distanceAsString) + assertEquals("yd", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(110.0, result.distance, 0.1) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance small value at upper bound UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 160.5, + Rounding.INCREMENT_FIVE, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("175", result.distanceAsString) + assertEquals("yd", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(175.0, result.distance, 0.1) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance small value at lower bound UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 0.0, + Rounding.INCREMENT_FIVE, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("5", result.distanceAsString) + assertEquals("yd", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(5.0, result.distance, 0.1) } @Config(qualifiers = "en") @@ -154,7 +313,7 @@ class MapboxDistanceUtilTest { @Config(qualifiers = "en") @Test - fun `formatDistance medium value metric with default locale`() { + fun `formatDistance medium value at lower bound metric with default locale`() { val result = MapboxDistanceUtil.formatDistance( 1000.0, Rounding.INCREMENT_FIFTY, @@ -172,21 +331,85 @@ class MapboxDistanceUtilTest { @Test fun `formatDistance medium fractional value metric with default locale`() { val result = MapboxDistanceUtil.formatDistance( - 400.5, + 1100.5, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC, + ctx + ) + + assertEquals("1.1", result.distanceAsString) + assertEquals("km", result.distanceSuffix) + assertEquals(UnitType.METRIC, result.unitType) + assertEquals(1.1005, result.distance, 0.0) + } + + @Config(qualifiers = "en") + @Test + fun `formatDistance medium value at upper bound metric with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 2904.89, Rounding.INCREMENT_FIFTY, UnitType.METRIC, ctx ) - assertEquals("0.4", result.distanceAsString) + assertEquals("2.9", result.distanceAsString) assertEquals("km", result.distanceSuffix) assertEquals(UnitType.METRIC, result.unitType) - assertEquals(0.4005, result.distance, 0.0) + assertEquals(2.90489, result.distance, 0.0000001) } @Config(qualifiers = "en") @Test - fun `formatDistance medium value close to upper bound imperial with default locale`() { + fun `formatDistance medium value imperial with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 1200.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("0.7", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(0.7456454, result.distance, 0.00001) + } + + @Config(qualifiers = "en") + @Test + fun `formatDistance medium value at upper bound imperial with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 4741.9, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("2.9", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(2.94648, result.distance, 0.00001) + } + + @Config(qualifiers = "en") + @Test + fun `formatDistance medium value at lower bound imperial with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 161.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("0.1", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(0.100041, result.distance, 0.00001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance medium value UK with default locale`() { val result = MapboxDistanceUtil.formatDistance( 15000.0, Rounding.INCREMENT_FIFTY, @@ -194,26 +417,42 @@ class MapboxDistanceUtilTest { ctx ) - assertEquals("9.3", result.distanceAsString) + assertEquals("9", result.distanceAsString) assertEquals("mi", result.distanceSuffix) assertEquals(UnitType.IMPERIAL, result.unitType) assertEquals(9.3205679, result.distance, 0.00001) } - @Config(qualifiers = "en") + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance medium value close to lower bound imperial with default locale`() { + fun `formatDistance medium value at lower bound UK with default locale`() { val result = MapboxDistanceUtil.formatDistance( - 350.0, + 161.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL, ctx ) - assertEquals("0.2", result.distanceAsString) + assertEquals("0.1", result.distanceAsString) assertEquals("mi", result.distanceSuffix) assertEquals(UnitType.IMPERIAL, result.unitType) - assertEquals(0.21748, result.distance, 0.00001) + assertEquals(0.100041, result.distance, 0.00001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance medium value at upper bound UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + 4741.9, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("2.9", result.distanceAsString) + assertEquals("mi", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(2.94648, result.distance, 0.00001) } @Config(qualifiers = "en") @@ -264,35 +503,51 @@ class MapboxDistanceUtilTest { assertEquals(50.0, result.distance, 0.0) } - @Config(qualifiers = "en") + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance zero value imperial with default locale`() { + fun `formatDistance invalid large value UK with default locale`() { val result = MapboxDistanceUtil.formatDistance( - 0.0, + -19312.1, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL, ctx ) assertEquals("50", result.distanceAsString) - assertEquals("ft", result.distanceSuffix) + assertEquals("yd", result.distanceSuffix) assertEquals(UnitType.IMPERIAL, result.unitType) assertEquals(50.0, result.distance, 0.0) } - @Config(qualifiers = "en") + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance zero value metric with default locale`() { + fun `formatDistance invalid medium value UK with default locale`() { val result = MapboxDistanceUtil.formatDistance( - 0.0, + -353.0, Rounding.INCREMENT_FIFTY, - UnitType.METRIC, + UnitType.IMPERIAL, ctx ) assertEquals("50", result.distanceAsString) - assertEquals("m", result.distanceSuffix) - assertEquals(UnitType.METRIC, result.unitType) + assertEquals("yd", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) + assertEquals(50.0, result.distance, 0.0) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance invalid small value UK with default locale`() { + val result = MapboxDistanceUtil.formatDistance( + -54.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL, + ctx + ) + + assertEquals("50", result.distanceAsString) + assertEquals("yd", result.distanceSuffix) + assertEquals(UnitType.IMPERIAL, result.unitType) assertEquals(50.0, result.distance, 0.0) } @@ -345,7 +600,7 @@ class MapboxDistanceUtilTest { } @Test - fun `formatDistance return small distance only`() { + fun `formatDistance imperial return small distance only`() { val result = MapboxDistanceUtil.formatDistance( 10.0, Rounding.INCREMENT_TEN, @@ -356,123 +611,388 @@ class MapboxDistanceUtilTest { } @Test - fun `formatDistance return small distance only close to upper bound`() { + fun `formatDistance imperial return small at lower bound distance only`() { val result = MapboxDistanceUtil.formatDistance( - 150.0, + 0.0, Rounding.INCREMENT_TEN, UnitType.IMPERIAL ) - assertEquals(490.0, result, 0.0) + assertEquals(10.0, result, 0.0) } @Test - fun `formatDistance return small distance only when input negative`() { + fun `formatDistance imperial return small at upper bound distance only`() { val result = MapboxDistanceUtil.formatDistance( - -10.0, + 4741.9, + Rounding.INCREMENT_TEN, + UnitType.IMPERIAL + ) + + assertEquals(2.94648, result, 0.00001) + } + + @Test + @Config(qualifiers = "en-rGB") + fun `formatDistance UK return small distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 101.0, + Rounding.INCREMENT_TEN, + UnitType.IMPERIAL + ) + + assertEquals(110.0, result, 0.0) + } + + @Test + @Config(qualifiers = "en-rGB") + fun `formatDistance UK return small at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 0.0, + Rounding.INCREMENT_TEN, + UnitType.IMPERIAL + ) + + assertEquals(10.0, result, 0.0) + } + + @Test + @Config(qualifiers = "en-rGB") + fun `formatDistance UK return small at upper bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 4741.9, Rounding.INCREMENT_TEN, UnitType.IMPERIAL ) - assertEquals(0.0, result, 0.0) + assertEquals(2.94648, result, 0.00001) } @Test - fun `formatDistance imperial return medium distance only close to lower bound`() { + fun `formatDistance imperial return small distance only when input negative`() { val result = MapboxDistanceUtil.formatDistance( - 350.0, + -10.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(0.21748, result, 0.000001) + assertEquals(50.0, result, 0.0) } @Test - fun `formatDistance imperial return medium distance only close to upper bound`() { + @Config(qualifiers = "en-rGB") + fun `formatDistance UK return small distance only when input negative`() { val result = MapboxDistanceUtil.formatDistance( - 15000.0, + -10.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(9.3205679, result, 0.00001) + assertEquals(50.0, result, 0.0) } @Test - fun `formatDistance return large distance only`() { + fun `formatDistance imperial return medium distance only`() { val result = MapboxDistanceUtil.formatDistance( - 1000.0, + 13000.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(8.0778255, result, 0.00001) + } + + @Test + fun `formatDistance imperial return medium at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 161.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(0.10004, result, 0.000001) + } + + @Test + fun `formatDistance imperial return medium at upper bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 4741.9, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(0.6213714106386318, result, 0.0) + assertEquals(2.94648, result, 0.00001) } + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance invalid large metric returns zero`() { + fun `formatDistance UK return medium distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 10456.3, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(6.49724, result, 0.00001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance UK return medium at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 161.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(0.10004, result, 0.000001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance UK return medium at upper bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 4741.9, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(2.94648, result, 0.00001) + } + + @Test + fun `formatDistance imperial return large at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 4828.032, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(3.0, result, 0.00001) + } + + @Test + fun `formatDistance imperial return large distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 10800.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(6.7108112, result, 0.000001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance UK return large distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 10800.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(6.7108089, result, 0.00001) + } + + @Config(qualifiers = "en-rGB") + @Test + fun `formatDistance UK return large at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 4828.032, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(3.0, result, 0.00001) + } + + @Test + fun `formatDistance imperial invalid large metric returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -15000.0, Rounding.INCREMENT_FIFTY, UnitType.METRIC ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) } + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance invalid large imperial returns zero`() { + fun `formatDistance UK invalid large returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -15000.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) } @Test - fun `formatDistance invalid medium metric returns zero`() { + fun `formatDistance invalid medium metric returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -1500.0, Rounding.INCREMENT_FIFTY, UnitType.METRIC ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) } @Test - fun `formatDistance invalid medium imperial returns zero`() { + fun `formatDistance invalid medium imperial returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -1500.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) } + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance invalid small metric returns zero`() { + fun `formatDistance invalid medium UK returns fifty`() { + val result = MapboxDistanceUtil.formatDistance( + -1500.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(50.0, result, 0.0) + } + + @Test + fun `formatDistance invalid small metric returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -150.0, Rounding.INCREMENT_FIFTY, UnitType.METRIC ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) + } + + @Test + fun `formatDistance invalid small imperial returns fifty`() { + val result = MapboxDistanceUtil.formatDistance( + -150.0, + Rounding.INCREMENT_FIFTY, + UnitType.IMPERIAL + ) + + assertEquals(50.0, result, 0.0) } + @Config(qualifiers = "en-rGB") @Test - fun `formatDistance invalid small imperial returns zero`() { + fun `formatDistance invalid small UK returns fifty`() { val result = MapboxDistanceUtil.formatDistance( -150.0, Rounding.INCREMENT_FIFTY, UnitType.IMPERIAL ) - assertEquals(0.0, result, 0.0) + assertEquals(50.0, result, 0.0) + } + + @Test + fun `formatDistance metric return small distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 123.456, + Rounding.INCREMENT_TEN, + UnitType.METRIC + ) + + assertEquals(120.0, result, 0.0) + } + + @Test + fun `formatDistance metric return small at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 0.0, + Rounding.INCREMENT_TEN, + UnitType.METRIC + ) + + assertEquals(10.0, result, 0.0) + } + + @Test + fun `formatDistance metric return small at upper bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 999.999, + Rounding.INCREMENT_TEN, + UnitType.METRIC + ) + + assertEquals(1000.0, result, 0.0) + } + + @Test + fun `formatDistance metric return small distance only when input negative`() { + val result = MapboxDistanceUtil.formatDistance( + -10.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(50.0, result, 0.0) + } + + @Test + fun `formatDistance metric return medium distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 2367.354, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(2.367354, result, 0.00001) + } + + @Test + fun `formatDistance metric return medium at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 1000.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(1.0, result, 0.000001) + } + + @Test + fun `formatDistance metric return medium at upper bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 2910.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(2.91, result, 0.00001) + } + + @Test + fun `formatDistance metric return large at lower bound distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 3000.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(3.0, result, 0.0) + } + + @Test + fun `formatDistance metric return large distance only`() { + val result = MapboxDistanceUtil.formatDistance( + 10800.0, + Rounding.INCREMENT_FIFTY, + UnitType.METRIC + ) + + assertEquals(10.8, result, 0.0) } } diff --git a/libnavigation-util/src/main/res/values/strings.xml b/libnavigation-util/src/main/res/values/strings.xml index 3794500c8fd..180d2f3b45b 100644 --- a/libnavigation-util/src/main/res/values/strings.xml +++ b/libnavigation-util/src/main/res/values/strings.xml @@ -3,4 +3,5 @@ m mi ft + yd