Compare commits

...

16 Commits

Author SHA1 Message Date
karenzshea
cfee0f1109 add unit test for annotations=true returning all annotations 2017-02-13 18:11:47 +00:00
karenzshea
c7ce758e1c parse parameters.annotations into AnnotationsType::All 2017-02-13 18:11:03 +00:00
Karen Shea
3ac4fb5933 add error logging for missing osrm file to library tests (#3704) 2017-02-13 17:22:42 +00:00
karenzshea
2afe5e971b use qi - parser to work with 0 speed file lines 2017-02-13 17:22:42 +00:00
karenzshea
519b744502 clang format 2017-02-13 17:22:42 +00:00
karenzshea
d3c2ac671f round speed to 1 decimal place 2017-02-13 17:22:42 +00:00
karenzshea
07a1a907f8 add unit test to check that speeds are equal to distance/duration 2017-02-13 17:22:42 +00:00
karenzshea
062cae82a0 return speed annotations 2017-02-13 17:22:42 +00:00
Quinn Chrzan
316c7781a3 Unit testing docs (#3698)
* Updating library-tests and associated documentation to be more informative

* Fixing heading markup for updated unit testing docs
2017-02-13 17:22:42 +00:00
Karen Shea
e11bcfece5 Update http.md 2017-02-13 17:22:42 +00:00
Moritz Kobitzsch
cb8dee3e60 comments 2017-02-13 17:22:42 +00:00
Moritz Kobitzsch
a1abe71d9f fix handling none-tags in presence of multiple turns within 2017-02-13 17:22:42 +00:00
Moritz Kobitzsch
d54c837e51 add failing test 2017-02-13 17:22:42 +00:00
Patrick Niklaus
106d17541d Fix side road penalties and add test 2017-02-13 17:22:42 +00:00
Michael Krasnyk
ad29b237e3 make annotations={true|false|(values)+} grammar 2017-02-13 17:22:42 +00:00
Patrick Niklaus
febefb4684 Enable 5.6 travis builds 2017-02-10 14:40:33 +00:00
18 changed files with 289 additions and 44 deletions

View File

@ -13,6 +13,7 @@ notifications:
branches:
only:
- master
- "5.6"
cache:
ccache: true

View File

@ -172,7 +172,7 @@ In addition to the [general options](#general-options) the following options are
|------------|---------------------------------------------|-------------------------------------------------------------------------------|
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|steps |`true`, `false` (default) |Return route steps for each route leg |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
@ -275,7 +275,7 @@ In addition to the [general options](#general-options) the following options are
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route steps for each route |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. |
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
@ -327,7 +327,7 @@ In addition to the [general options](#general-options) the following options are
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate |
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate |
|steps |`true`, `false` (default) |Return route instructions for each trip |
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
@ -518,7 +518,8 @@ With `steps=false` and `annotations=true`:
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
"speed": [0.3, 0.3, 0.3, 0.3, 0.3]
}
}
```
@ -534,6 +535,7 @@ Annotation of the whole route leg with fine-grained information about each segme
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
- `weight`: The weights between each pair of coordinates
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
#### Example

View File

@ -28,6 +28,29 @@ This dataset is a small extract and may not even contain all tags or edge cases.
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
See the library tests for how to add new dataset dependent tests.
To prepare the test data simply `cd test/data/` and then run `make`.
### Running Tests
To build the unit tests:
```
cd build
cmake ..
make tests
```
You should see the compiled binaries in `build/unit_tests`, you can then run each suite individually:
```
./engine-tests
```
For `library-tests` you will need to provide a path to the test data:
```
./library-tests ../../test/data/monaco.osrm
```
## Cucumber

View File

@ -45,3 +45,9 @@ Feature: Car - speeds
| primary | 60 | 47 km/h | 47 km/h |
| primary | 60 | 47 km/h | 47 km/h |
| primary | 60 | 47 km/h | 47 km/h |
Scenario: Car - Side road penalties
Then routability should be
| highway | side_road | forw | backw | forw_rate | backw_rate |
| primary | yes | 64 km/h | 64 km/h | 14 | 14 |

View File

@ -1158,3 +1158,45 @@ Feature: Turn Lane Guidance
When I route I should get
| waypoints | bearings | route | turns |
| 1,a | 90,2 180,180 | | |
@3379
Scenario: Don't Turn through potential through lanes
Given the node map
"""
d
|
a - - - - b - - - - - c
|
e
"""
And the ways
| nodes | name | oneway | turn:lanes:forward |
| ab | road | yes | left\|none\|none |
| bc | road | yes | |
| ebd | cross | no | |
When I route I should get
| waypoints | route | turns | lanes |
| a,e | road,cross,cross | depart,turn right,arrive | ,left:false none:false none:true, |
| a,c | road,road | depart,arrive | , |
@3379
Scenario: Don't Turn through potential through lanes
Given the node map
"""
d
|
a - - - - b - - - - - c
|
e
"""
And the ways
| nodes | name | oneway | turn:lanes:forward |
| ab | road | yes | none\|none\|right |
| bc | road | yes | |
| ebd | cross | no | |
When I route I should get
| waypoints | route | turns | lanes |
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
| a,c | road,road | depart,arrive | , |

View File

@ -28,3 +28,11 @@ Feature: osrm-contract command line options: datasources
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
Then datasource names should contain "lua profile,27_osrmcontract_passing_base_file_speeds"
And it should exit successfully
Scenario: osrm-contract - Passing base file
Given the speed file
"""
"""
And the data has been extracted
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
Then it should exit successfully

View File

@ -147,7 +147,7 @@ module.exports = function () {
// if header matches 'a:*', parse out the values for *
// and return in that header
headers.forEach((k) => {
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight'];
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed'];
if (k.match(/^a:/)) {
let a_type = k.slice(2);
if (whitelist.indexOf(a_type) == -1)

View File

@ -39,7 +39,7 @@ Feature: Weight tests
# FIXME include/engine/guidance/assemble_geometry.hpp:95
Scenario: Start and target on the same and adjacent edge
Given the query options
| annotations | distance,duration,weight,nodes |
| annotations | distance,duration,weight,nodes,speed |
Given the node map
"""
@ -53,11 +53,11 @@ Feature: Weight tests
| abc |
When I route I should get
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight |
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 |
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 |
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 |
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 | 6.7 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 | 6.5 |
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property

View File

@ -228,42 +228,59 @@ class RouteAPI : public BaseAPI
std::vector<util::json::Object> annotations;
if (parameters.annotations_type != RouteParameters::AnnotationsType::None)
// To maintain support for uses of the old default constructors, we check
// if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
{
requested_annotations = RouteParameters::AnnotationsType::All;
}
if (requested_annotations != RouteParameters::AnnotationsType::None)
{
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
{
auto &leg_geometry = leg_geometries[idx];
util::json::Object annotation;
if (parameters.annotations_type & RouteParameters::AnnotationsType::Duration)
// AnnotationsType uses bit flags, & operator checks if a property is set
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
{
annotation.values["speed"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return std::round(anno.distance / anno.duration * 10.) / 10.;
});
}
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
{
annotation.values["duration"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.duration;
});
}
if (parameters.annotations_type & RouteParameters::AnnotationsType::Distance)
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
{
annotation.values["distance"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.distance;
});
}
if (parameters.annotations_type & RouteParameters::AnnotationsType::Weight)
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
{
annotation.values["weight"] = GetAnnotations(
leg_geometry,
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
}
if (parameters.annotations_type & RouteParameters::AnnotationsType::Datasources)
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
annotation.values["datasources"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.datasource;
});
}
if (parameters.annotations_type & RouteParameters::AnnotationsType::Nodes)
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{
util::json::Array nodes;
nodes.values.reserve(leg_geometry.osm_node_ids.size());

View File

@ -75,7 +75,8 @@ struct RouteParameters : public BaseParameters
Distance = 0x04,
Weight = 0x08,
Datasources = 0x10,
All = Duration | Nodes | Distance | Weight | Datasources
Speed = 0x20,
All = Duration | Nodes | Distance | Weight | Datasources | Speed
};
RouteParameters() = default;

View File

@ -42,11 +42,13 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
{
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
engine::api::RouteParameters::AnnotationsType &route_param) {
AnnotationsType route_param) {
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
route_parameters.annotations = route_parameters.annotations_type !=
engine::api::RouteParameters::AnnotationsType::None;
route_parameters.annotations =
route_parameters.annotations_type != AnnotationsType::None;
};
geometries_type.add("geojson", engine::api::RouteParameters::GeometriesType::GeoJSON)(
@ -57,13 +59,10 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
"full", engine::api::RouteParameters::OverviewType::Full)(
"false", engine::api::RouteParameters::OverviewType::False);
annotations_type.add("true", engine::api::RouteParameters::AnnotationsType::All)(
"false", engine::api::RouteParameters::AnnotationsType::None)(
"duration", engine::api::RouteParameters::AnnotationsType::Duration)(
"nodes", engine::api::RouteParameters::AnnotationsType::Nodes)(
"distance", engine::api::RouteParameters::AnnotationsType::Distance)(
"weight", engine::api::RouteParameters::AnnotationsType::Weight)(
"datasources", engine::api::RouteParameters::AnnotationsType::Datasources);
annotations_type.add("duration", AnnotationsType::Duration)("nodes",
AnnotationsType::Nodes)(
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
base_rule =
BaseGrammar::base_rule(qi::_r1) |
@ -75,7 +74,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
(qi::lit("overview=") >
overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1]) |
(qi::lit("annotations=") >
annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',');
(qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] |
qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] |
(annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',')));
query_rule = BaseGrammar::query_rule(qi::_r1);
}

View File

@ -2,7 +2,7 @@
"name": "osrm-backend-test-suite",
"version": "0.0.0",
"private": true,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.",
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {
"chalk": "^1.1.3",
"cucumber": "^1.2.1",

View File

@ -327,7 +327,7 @@ function Handlers.handle_penalties(way,result,data,profile)
local sideroad_penalty = 1.0
data.sideroad = way:get_value_by_key("side_road")
if "yes" == data.sideroad or "rotary" == data.sideroad then
sideroad_penalty = side_road_multiplier;
sideroad_penalty = profile.side_road_multiplier
end
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, forward_hov_penalty)

View File

@ -268,7 +268,7 @@ template <typename Key, typename Value> struct CSVFilesParser
qi::rule<Iterator, std::pair<Key, Value>()> csv_line =
(key_rule >> ',' >> value_source) >> -(',' >> *(qi::char_ - qi::eol));
std::vector<std::pair<Key, Value>> result;
const auto ok = qi::parse(first, last, (csv_line % qi::eol) >> *qi::eol, result);
const auto ok = qi::parse(first, last, -(csv_line % qi::eol) >> *qi::eol, result);
if (!ok || first != last)
{

View File

@ -40,7 +40,6 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
LaneDataVector lane_data,
const Intersection &intersection)
{
// a none-turn is allowing multiple turns. we have to add a lane-data entry for
// every possible turn. This should, hopefully, only be the case for single lane
// entries?
@ -107,20 +106,64 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
util::Log(logWARNING) << "Failed lane assignment. Reached bad situation.";
return std::make_pair(std::size_t{0}, std::size_t{0});
}();
for (auto intersection_index = range.first; intersection_index < range.second;
++intersection_index)
const auto intersection_range_first = intersection.begin() + range.first;
const auto intersection_range_end = intersection.begin() + range.second;
const auto allowed_in_range =
std::count_if(intersection_range_first, intersection_range_end, [](const auto &road) {
return road.entry_allowed;
});
if (allowed_in_range > 1 && lane_data[none_index].to - lane_data[none_index].from >= 1)
{
if (intersection[intersection_index].entry_allowed)
// check if there is a straight turn
auto straight_itr =
std::find_if(intersection_range_first, intersection_range_end, [](const auto &road) {
return road.instruction.direction_modifier == DirectionModifier::Straight;
});
// we have a straight turn?
if (straight_itr != intersection_range_end)
{
// FIXME this probably can be only a subset of these turns here?
lane_data.push_back(
{tag_by_modifier[intersection[intersection_index].instruction.direction_modifier],
lane_data[none_index].from,
lane_data[none_index].to,
false});
for (auto itr = intersection_range_first; itr != straight_itr; ++itr)
{
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
lane_data[none_index].from,
lane_data[none_index].from,
false});
}
lane_data.push_back({tag_by_modifier[straight_itr->instruction.direction_modifier],
lane_data[none_index].from,
lane_data[none_index].to,
false});
for (auto itr = straight_itr + 1; itr != intersection_range_end; ++itr)
{
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
lane_data[none_index].to,
lane_data[none_index].to,
false});
}
lane_data.erase(lane_data.begin() + none_index);
}
return lane_data;
}
else
{
for (auto intersection_index = range.first; intersection_index < range.second;
++intersection_index)
{
if (intersection[intersection_index].entry_allowed)
{
lane_data.push_back({tag_by_modifier[intersection[intersection_index]
.instruction.direction_modifier],
lane_data[none_index].from,
lane_data[none_index].to,
false});
}
}
lane_data.erase(lane_data.begin() + none_index);
}
lane_data.erase(lane_data.begin() + none_index);
return lane_data;
}

View File

@ -1,11 +1,27 @@
#ifndef OSRM_UNIT_TEST_ARGS
#define OSRM_UNIT_TEST_ARGS
#include "util/log.hpp"
#include <boost/filesystem.hpp>
#include <iostream>
#include <iostream>
#include <string>
#include <vector>
inline std::vector<std::string> get_args()
{
osrm::util::LogPolicy::GetInstance().Unmute();
if ((boost::unit_test::framework::master_test_suite().argc != 2) ||
(!boost::filesystem::is_regular_file(
boost::unit_test::framework::master_test_suite().argv[1])))
{
osrm::util::Log(logERROR) << "Please provide valid input osrm file";
osrm::util::Log(logERROR) << "Usage: "
<< boost::unit_test::framework::master_test_suite().argv[0]
<< " /path/to/input_osrm_file" << std::endl;
std::exit(EXIT_FAILURE);
}
// Split off argv[0], store actual positional arguments in args
const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;

View File

@ -387,4 +387,72 @@ BOOST_AUTO_TEST_CASE(test_route_user_disables_generating_hints)
BOOST_CHECK_EQUAL(waypoint.get<json::Object>().values.count("hint"), 0);
}
BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
{
const auto args = get_args();
auto osrm = getOSRM(args.at(0));
using namespace osrm;
RouteParameters params;
params.annotations_type = RouteParameters::AnnotationsType::Duration |
RouteParameters::AnnotationsType::Distance |
RouteParameters::AnnotationsType::Speed;
params.coordinates.push_back(get_dummy_location());
params.coordinates.push_back(get_dummy_location());
json::Object result;
const auto rc = osrm.Route(params, result);
BOOST_CHECK(rc == Status::Ok);
const auto &routes = result.values["routes"].get<json::Array>().values;
const auto &legs = routes[0].get<json::Object>().values.at("legs").get<json::Array>().values;
const auto &annotation =
legs[0].get<json::Object>().values.at("annotation").get<json::Object>();
const auto &speeds = annotation.values.at("speed").get<json::Array>().values;
const auto &durations = annotation.values.at("duration").get<json::Array>().values;
const auto &distances = annotation.values.at("distance").get<json::Array>().values;
int length = speeds.size();
for (int i = 0; i < length; i++)
{
auto speed = speeds[i].get<json::Number>().value;
auto duration = durations[i].get<json::Number>().value;
auto distance = distances[i].get<json::Number>().value;
BOOST_CHECK_EQUAL(speed, std::round(distance / duration * 10.) / 10.);
}
}
BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property)
{
const auto args = get_args();
auto osrm = getOSRM(args.at(0));
using namespace osrm;
RouteParameters params{};
params.annotations = true;
params.coordinates.push_back(get_dummy_location());
params.coordinates.push_back(get_dummy_location());
json::Object result;
const auto rc = osrm.Route(params, result);
BOOST_CHECK(rc == Status::Ok);
const auto code = result.values.at("code").get<json::String>().value;
BOOST_CHECK_EQUAL(code, "Ok");
auto annotations = result.values["routes"]
.get<json::Array>()
.values[0]
.get<json::Object>()
.values["legs"]
.get<json::Array>()
.values[0]
.get<json::Object>()
.values["annotation"]
.get<json::Object>()
.values;
BOOST_CHECK_EQUAL(annotations.size(), 5);
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -67,6 +67,7 @@ BOOST_AUTO_TEST_CASE(invalid_route_urls)
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=distances"), 28UL);
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations="), 20UL);
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=true,false"), 24UL);
BOOST_CHECK_EQUAL(
testInvalidOptions<RouteParameters>("1,2;3,4?annotations=&overview=simplified"), 20UL);
@ -349,6 +350,22 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
true);
BOOST_CHECK_EQUAL(result_15->annotations, true);
RouteParameters reference_speed{};
reference_speed.annotations_type = RouteParameters::AnnotationsType::Duration;
reference_speed.coordinates = coords_1;
auto result_speed =
parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
"overview=simplified&annotations=duration,distance,speed");
BOOST_CHECK(result_speed);
BOOST_CHECK_EQUAL(reference_speed.geometries, result_speed->geometries);
BOOST_CHECK_EQUAL(reference_speed.overview, result_speed->overview);
BOOST_CHECK_EQUAL(result_speed->annotations_type ==
(RouteParameters::AnnotationsType::Duration |
RouteParameters::AnnotationsType::Distance |
RouteParameters::AnnotationsType::Speed),
true);
BOOST_CHECK_EQUAL(result_speed->annotations, true);
// parse multiple annotations correctly
RouteParameters reference_16{};
reference_16.annotations_type = RouteParameters::AnnotationsType::Duration |