-
Notifications
You must be signed in to change notification settings - Fork 319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade RouteProgress Step Data #812
Conversation
b0280ba
to
9ac2311
Compare
@@ -27,4 +33,12 @@ protected String loadJsonFixture(String filename) throws IOException { | |||
Scanner scanner = new Scanner(inputStream, UTF_8.name()).useDelimiter("\\A"); | |||
return scanner.hasNext() ? scanner.next() : ""; | |||
} | |||
|
|||
protected LegStep getFirstStep(DirectionsRoute route) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there somewhere else these could go? It seems very specific to be included in all tests
double distanceRemaining = distanceRemaining(); | ||
double distanceTraveled = calculateDistanceTraveled(step, distanceRemaining); | ||
distanceTraveled(distanceTraveled); | ||
float fractionTraveled = calculateFractionTraveled(step, distanceTraveled); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we calculating all of this before it's needed?
fddcfb8
to
104a209
Compare
38d18db
to
daf011a
Compare
9a9c914
to
7afd446
Compare
@Guardiola31337 @devotaaabel this is ready for 👀, will finish up adding tests tomorrow. |
@Guardiola31337 @devotaaabel tests finished! This is good to go 🚀 for 👀 |
205546f
to
35d0bdb
Compare
@@ -27,4 +42,55 @@ protected String loadJsonFixture(String filename) throws IOException { | |||
Scanner scanner = new Scanner(inputStream, UTF_8.name()).useDelimiter("\\A"); | |||
return scanner.hasNext() ? scanner.next() : ""; | |||
} | |||
|
|||
protected RouteProgress buildRouteProgress(DirectionsRoute route, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think instead of putting this in BaseTest
we should have classes that fake data for us, like RouteProgressFaker
, just so we don't clutter up BaseTest
with implementation specific code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted the building logic from
BaseTest
into classes that separate the building concerns.
How did you address @devotaaabel's comment? buildRouteProgress
is still in BaseTest
🤔 Could you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great tests refactoring work @danesfeder 👏
This is looking great. A few comments / cleanup.
.build(); | ||
double stepDistanceRemainingFinal = stepDistanceRemaining == null ? 100 : stepDistanceRemaining; | ||
return buildRouteProgress(aRoute, stepDistanceRemainingFinal, | ||
0, 0, 0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT unnecessary new line
@@ -141,14 +141,9 @@ private Location buildLocationUpdate(double lng, double lat, long time) { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using the RobolectricTestRunner
? If it's only for mocking Location
it could be mocked using Mockito following the same approach as in #784 👀
Lines 78 to 86 in 1e5c274
protected Location buildLocationUpdate(double lng, double lat, float speed, float horizontalAccuracy, long time) { | |
Location location = mock(Location.class); | |
when(location.getLongitude()).thenReturn(lng); | |
when(location.getLatitude()).thenReturn(lat); | |
when(location.getSpeed()).thenReturn(speed); | |
when(location.getAccuracy()).thenReturn(horizontalAccuracy); | |
when(location.getTime()).thenReturn(time); | |
return location; | |
} |
@@ -15,6 +29,7 @@ | |||
public static final double LARGE_DELTA = 0.1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀 visibility DELTA
👇
Access can be protected
@@ -15,6 +29,7 @@ | |||
public static final double LARGE_DELTA = 0.1; | |||
|
|||
public static final String ACCESS_TOKEN = "pk.XXX"; | |||
private static final int FIRST_POINT = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀
Private field 'FIRST_POINT' is never used
The same thing happens with LARGE_DELTA
, ACCESS_TOKEN
☝️ and compareJson
👇
@@ -52,6 +70,17 @@ static Point userSnappedToRoutePosition(Location location, List<Point> coordinat | |||
return ((Point) feature.geometry()); | |||
} | |||
|
|||
static Location buildSnappedLocation(MapboxNavigation mapboxNavigation, boolean snapToRouteEnabled, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only called once from NavigationEngine#handleRequest
. IMO, objects and methods should live/be where their context is. From my experience utility classes become a drawer easily and we should treat them carefully. What about moving this utility method to NavigationEngine
class or even a new class holding all the methods used in NavigationEngine
?
The same thing happens with checkMilestones
, isUserOffRoute
and shouldCheckFasterRoute
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the size of this PR already and that this is core logic we will be touching, let's save this refactor for another PR that touches this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please write a reminder down so we don't forget to 👀 this comment when touching NavigationHelper
😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better said we should 👀 all the comments when working with NavigationHelper
again 😛
@@ -324,28 +317,16 @@ public void setNavigationMetricListener_didNotGetTriggeredUntilArrival() throws | |||
navigationEventDispatcher.addMetricArrivalListener(arrivalListener); | |||
|
|||
// Progress that hasn't arrived |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why having comments in a test? Also 👇
@@ -36,77 +45,57 @@ | |||
import static junit.framework.Assert.assertNotSame; | |||
import static junit.framework.Assert.assertTrue; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
|
|||
@RunWith(RobolectricTestRunner.class) | |||
@Config(constants = BuildConfig.class, sdk = 25) | |||
public class NavigationHelperTest extends BaseTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall same comments pointed out above ☝️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RobolectricTestRunner
is needed to test the milestones being triggered - removing this results in a crash
assertTrue(nextManeuver.equals(route.legs().get(1).steps().get(0).maneuver().location())); | ||
} | ||
|
||
@Test | ||
public void createIntersectionList_returnsCompleteIntersectionList() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some blocks of duplicated code 👇
What about extracting them into private
"factory" methods and used them across the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're talking about:
RouteProgress routeProgress = buildMultiLegRouteProgress();
LegStep currentStep = routeProgress.currentLegProgress().currentStep();
LegStep upcomingStep = routeProgress.currentLegProgress().upComingStep();
This can't be extracted, as we need both current and upcoming steps for the Arrange
@@ -43,7 +43,6 @@ public void setup() throws Exception { | |||
|
|||
offRouteDetector = new OffRouteDetector(); | |||
offRouteDetector.setOffRouteCallback(mockCallback); | |||
setupStepPoints(offRouteDetector); | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall same comments pointed out above ☝️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what the comment above here means
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what the comment above here means
Didn't want to repeat myself but what I meant is that most of the comments already pointed out before apply here as well (e.g. #812 (comment) #812 (comment) #812 (comment)).
String body = loadJsonFixture(DIRECTIONS_PRECISION_6); | ||
DirectionsResponse response = gson.fromJson(body, DirectionsResponse.class); | ||
route = response.routes().get(0); | ||
public void setup() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with RouteLegProgressTest
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same thing happens with RouteProgressTest
, RouteStepProgressTest
, SnapToRouteTest
and ToleranceUtilsTest
.
- Begin current and upcoming StepIntersections
67cfb4d
to
5c96cda
Compare
@Guardiola31337 Outside of your comments surrounding @devotaaabel I extracted the building logic from Thanks for the great review! |
@@ -27,4 +42,55 @@ protected String loadJsonFixture(String filename) throws IOException { | |||
Scanner scanner = new Scanner(inputStream, UTF_8.name()).useDelimiter("\\A"); | |||
return scanner.hasNext() ? scanner.next() : ""; | |||
} | |||
|
|||
protected RouteProgress buildRouteProgress(DirectionsRoute route, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted the building logic from
BaseTest
into classes that separate the building concerns.
How did you address @devotaaabel's comment? buildRouteProgress
is still in BaseTest
🤔 Could you clarify?
|
||
@RunWith(RobolectricTestRunner.class) | ||
@Config(constants = BuildConfig.class, manifest = Config.DEFAULT_MANIFEST_NAME) | ||
public class DynamicCameraTest extends BaseTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general is hard to know where the assert values come from. I know that we're taking the values from "directions_v5_precision_6.json"
fixture but IMO it's not clear when you 👀 the tests at first glance. There is some kind of magic behind the scenes that forces you to 👀 the implementation to fully understand what's going on. We should remove that necessity.
@@ -52,6 +70,17 @@ static Point userSnappedToRoutePosition(Location location, List<Point> coordinat | |||
return ((Point) feature.geometry()); | |||
} | |||
|
|||
static Location buildSnappedLocation(MapboxNavigation mapboxNavigation, boolean snapToRouteEnabled, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please write a reminder down so we don't forget to 👀 this comment when touching NavigationHelper
😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great refactoring work @danesfeder 👏
A few more comments 😬
@@ -52,6 +70,17 @@ static Point userSnappedToRoutePosition(Location location, List<Point> coordinat | |||
return ((Point) feature.geometry()); | |||
} | |||
|
|||
static Location buildSnappedLocation(MapboxNavigation mapboxNavigation, boolean snapToRouteEnabled, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better said we should 👀 all the comments when working with NavigationHelper
again 😛
@@ -240,9 +495,48 @@ static Point nextManeuverPosition(int stepIndex, List<LegStep> steps, List<Point | |||
return !coords.isEmpty() ? coords.get(coords.size() - 1) : coords.get(coords.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it package private to test it.
Pretty sure it can be tested through the public
methods that use it 😉 but yeah let's revisit when touching NavigationHelper
again.
private void checkNewRoute(MapboxNavigation mapboxNavigation) { | ||
DirectionsRoute directionsRoute = mapboxNavigation.getRoute(); | ||
if (RouteUtils.isNewRoute(routeProgress, directionsRoute)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT unnecessary new line
If we want to remark two different operations, what about extracting blocks into well-named methods?
|
||
indices = NavigationIndices.create(FIRST_LEG_INDEX, FIRST_STEP_INDEX); | ||
processNewIndex(mapboxNavigation); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here ☝️
@@ -24,7 +23,6 @@ | |||
private Point lastReroutePoint; | |||
private OffRouteCallback callback; | |||
private RingBuffer<Integer> distancesAwayFromManeuver = new RingBuffer<>(3); | |||
private List<Point> stepPoints = new ArrayList<>(); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here ☝️
I meant same comments as in #812 (comment) but for OffRouteDetector
in this case.
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.robolectric.RobolectricTestRunner; | ||
import org.robolectric.annotation.Config; | ||
|
||
import java.util.List; | ||
|
||
import static junit.framework.Assert.assertNotNull; | ||
import static junit.framework.Assert.assertTrue; | ||
|
||
@RunWith(RobolectricTestRunner.class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using the RobolectricTestRunner
?
.build(); | ||
|
||
} | ||
|
||
@Test | ||
public void sanity() throws Exception { | ||
Snap snap = new SnapToRoute(); | ||
assertNotNull(snap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DirectionsRoute route = buildTestDirectionsRoute(); | ||
RouteProgress routeProgress = buildDefaultTestRouteProgress(); | ||
double distanceToIntersection = route.distance() - 39; | ||
LineString lineString = LineString.fromPolyline(route.geometry(), Constants.PRECISION_6); | ||
Point closePoint | ||
= TurfMeasurement.along(lineString, distanceToIntersection, TurfConstants.UNIT_METERS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT unnecessary new line
DirectionsRoute route = buildTestDirectionsRoute(); | ||
RouteProgress routeProgress = buildDefaultTestRouteProgress(); | ||
double distanceToIntersection = route.distance(); | ||
LineString lineString = LineString.fromPolyline(route.geometry(), Constants.PRECISION_6); | ||
Point closePoint | ||
= TurfMeasurement.along(lineString, distanceToIntersection, TurfConstants.UNIT_METERS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT unnecessary new line
.legIndex(0) | ||
.build(); | ||
routeProgress = routeProgress.toBuilder().stepIndex(lastStepIndex).build(); | ||
|
||
assertNull(routeProgress.currentLegProgress().upComingStep()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be in the Arrange
part 👀 upComingStep_returnsNull
is telling us what's the Act
here upComingStep
.
Also 👀 #812 (comment)
This applies to other modified tests included in this PR (RouteProgressTest
and RouteStepProgressTest
).
c94c73c
to
75fc29f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments not blocking the PR.
Really well done @danesfeder 👏
|
||
import static okhttp3.internal.Util.UTF_8; | ||
|
||
class TestRouteBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.findCurrentIntersection; | ||
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.findUpcomingIntersection; | ||
|
||
class TestRouteProgressBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.findCurrentIntersection; | ||
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.findUpcomingIntersection; | ||
|
||
class TestRouteProgressBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
import static okhttp3.internal.Util.UTF_8; | ||
|
||
class TestRouteBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
75fc29f
to
2d7dd24
Compare
Closes #325
In preparation for a tunnel and dead reckoning work, we need to expose more data in the
RouteProgress
object. This PR does this and updates the tests accordingly