-
Notifications
You must be signed in to change notification settings - Fork 53
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
Make route comparator tolerate all kinds of data #124
Conversation
evansiroky
commented
Jan 28, 2020
- Adds a few functions to determine validity of various route values.
- Refactors route sort order function to sort using various different data formats for routes
- Adds a test suite to check for all kinds of possible route data being sorted properly
lib/util/itinerary.js
Outdated
* cannot be parsed as integers will be placed beneath those that are valid. | ||
* 3. In case of the same routeShortName criteria, attempt to sort based off of | ||
* the string routeShortName or routeLongName if the routeShortName is | ||
* undefined. |
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'm confused... this JSdoc suggests that it checks the route sort order and then uses route short names to further sort (and so on for short name/long name). Where in the code is that actually handled? It appears that once a valid routeSortOrder comparison is made, the function simply returns.
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.
Bah, you're right.
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.
Dang, you really had me scratching my head!
Codecov Report
@@ Coverage Diff @@
## fix-route-order #124 +/- ##
==================================================
+ Coverage 10.65% 11.35% +0.7%
==================================================
Files 133 133
Lines 6090 6154 +64
Branches 1758 1781 +23
==================================================
+ Hits 649 699 +50
- Misses 4618 4634 +16
+ Partials 823 821 -2
Continue to review full report at Codecov.
|
All right, this one should actually work. |
// b is a valid number, b gets priority | ||
if (isNaN(aVal)) return 1 | ||
// a is a valid number, a gets priority | ||
if (isNaN(bVal)) return -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.
I'm a little worried about embedding this priority for numbers over strings in this comparator. If we decide that strings should come before numbers, we would have to refactor this function pretty heavily. There are a number of cases where we may actually want to give strings priority over ints (think about how TriMet lists their routes). Perhaps this function should also except a boolean arg stringsFirst
to indicate whether strings should be given higher priority in the sort (and these lines could use that arg)?
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 went ahead and added an option to forgo sorting by integer shortName. I think it'd be best to keep that because I can see it being quite common to have routes with "numeric" shortNames (ex: "3", "10", "20") and if we didn't sort by integer shortName, we'd get non-numerically sorted values (ex: "10", "20", "3").
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.
Sorry, I think maybe my initial point wasn't super clear. I do think we should sort shortNames as integers; however, I think that in some cases (maybe all) it might be preferable to have non-integer shortNames (and perhaps longNames) show up before integer shortNames in a list. E.g., Agency X may have numerically-named bus routes and color-named train lines. Because the train lines are more heavy utilized (and likely a shorter list) they might should show up first for better discoverability. So the order we're looking for would be:
BLUE
GREEN
RED
1
2
10
19
22
25
100
etc.
I don't think what we have here is doing that based on my reading and the snapshots.
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 so too. I'm also in favor of having one snapshot that has all the cases, so it shows what a normal route list could look like.
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.
@landonreed and @binh-dam-ibigroup, I just pushed a new commit that introduces two more comparator functions which I think will address these concerns. I've added a route type comparator that sorts based on route type. This will prioritize fixed guideway transit and ferries over buses. Secondly, I added a comparator that prioritizes routes with shortNames that begin with an alphabetic character.
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.
@landonreed and @evansiroky: Where would this case fit?
{ shortName: "10C" }
// a is not a comparable string, b gets priority | ||
if (!aVal) return 1 | ||
// b is not a comparable string, a gets priority | ||
if (!bVal) return -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.
Again, wondering about this embedded logic similar to https://github.com/opentripplanner/otp-react-redux/pull/124/files#r372464064
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 was initially wary of how you structured all of this, but it has really grown on me. Nice work!
A couple of comments on how things are structured. Big one is on clarifying the comment for routeComparator
and whether we should embed the strings after numbers logic in the make Comparator functions.
rename some functions, use consistent arguments and allow disabling integer route short name sorting
See additional changes and this comment: #124 (comment) |
I initially thought OTP-RR #124 was going to be a simple fix, hence the quick review; now it looks it like we are rewriting the route sorting entirely.
"shortName": "Yellow", | ||
"sortOrder": 2 | ||
} | ||
} |
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'm not sure if much is gained from moving this into a separate json file, especially since it gets destructured in the test file. Probably not worth another refactor though.
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.
It feels a bit like maybe some of the tests should just take JSON objects directly as arguments to the sortRoutes
func. Everything feels a bit scattered by having to check which routes are which back in this file. It seems like a few of the tests have become incorrectly named as a result of this disjointedness.
"longName": "Loop route", | ||
"mode": "BUS", | ||
"shortName": "2", | ||
"sortOrder": -999, |
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 this test might need to be renamed?
"longName": "Zig-zagging route", | ||
"mode": "BUS", | ||
"shortName": "30", | ||
"sortOrder": 2, |
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.
Test name mismatch?
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.
Looks really good. I just noted a few concerns about test name not quite matching the input data. This might be helped by placing the JSON test data directly into the test args rather than importing from the JSON file and referencing by variable names, but I'll leave that up to you.
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.
Just one change to the 30X express test route!
// b is a valid number, b gets priority | ||
if (isNaN(aVal)) return 1 | ||
// a is a valid number, a gets priority | ||
if (isNaN(bVal)) return -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.
@landonreed and @evansiroky: Where would this case fit?
{ shortName: "10C" }
"route9": { | ||
"longName": "Express route", | ||
"mode": "BUS", | ||
"shortName": "30", |
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.
Name this one with shortName "30X" to see how it will get sorted!
Just pushed a commit that renames a test and removes one that's no longer needed. |
...and I added a test case to prove that alphanumeric short names seem to get sorted properly. |
🎉 This PR is included in version 0.13.3 🎉 The release is available on: Your semantic-release bot 📦🚀 |