1 #include "server/api/parameters_parser.hpp"
2
3 #include "parameters_io.hpp"
4
5 #include "engine/api/base_parameters.hpp"
6 #include "engine/api/match_parameters.hpp"
7 #include "engine/api/nearest_parameters.hpp"
8 #include "engine/api/route_parameters.hpp"
9 #include "engine/api/table_parameters.hpp"
10 #include "engine/api/tile_parameters.hpp"
11 #include "engine/api/trip_parameters.hpp"
12
13 #include "util/debug.hpp"
14
15 #include <boost/optional/optional_io.hpp>
16 #include <boost/test/test_tools.hpp>
17 #include <boost/test/unit_test.hpp>
18
19 #define CHECK_EQUAL_RANGE(R1, R2) \
20 BOOST_CHECK_EQUAL_COLLECTIONS(R1.begin(), R1.end(), R2.begin(), R2.end());
21
22 BOOST_AUTO_TEST_SUITE(api_parameters_parser)
23
24 using namespace osrm;
25 using namespace osrm::server;
26 using namespace osrm::server::api;
27 using namespace osrm::engine::api;
28
29 // returns distance to front
testInvalidOptions(std::string options)30 template <typename ParameterT> std::size_t testInvalidOptions(std::string options)
31 {
32 auto iter = options.begin();
33 auto result = parseParameters<ParameterT>(iter, options.end());
34 BOOST_CHECK(!result);
35 return std::distance(options.begin(), iter);
36 }
37
BOOST_AUTO_TEST_CASE(invalid_route_urls)38 BOOST_AUTO_TEST_CASE(invalid_route_urls)
39 {
40 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("a;3,4"), 0UL);
41 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("120;3,4"), 3UL);
42 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("90000000,2;3,4"), 0UL);
43 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&bla=foo"), 22UL);
44 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&bearings=foo"),
45 32UL);
46 BOOST_CHECK_EQUAL(
47 testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&continue_straight=foo"), 41UL);
48 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&radiuses=foo"),
49 32UL);
50 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&approaches=foo"),
51 34UL);
52 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&hints=foo"),
53 29UL);
54 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&hints=;;; ;"),
55 32UL);
56 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?generate_hints=notboolean"),
57 23UL);
58 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&geometries=foo"),
59 34UL);
60 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&overview=foo"),
61 32L);
62 BOOST_CHECK_EQUAL(
63 testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&alternatives=foo"), 36UL);
64 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&alternatives=-1"),
65 36UL);
66 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(""), 0);
67 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3.4.unsupported"), 7);
68 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.json?nooptions"), 13);
69 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4..json?nooptions"), 14);
70 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.0.json?nooptions"), 15);
71 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,4"} + '\0' + ".json"),
72 7);
73 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
74 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=distances"), 28UL);
75 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations="), 20UL);
76 BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=true,false"), 24UL);
77 BOOST_CHECK_EQUAL(
78 testInvalidOptions<RouteParameters>("1,2;3,4?annotations=&overview=simplified"), 20UL);
79 }
80
BOOST_AUTO_TEST_CASE(invalid_table_urls)81 BOOST_AUTO_TEST_CASE(invalid_table_urls)
82 {
83 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=1&bla=foo"), 17UL);
84 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
85 BOOST_CHECK_EQUAL(
86 testInvalidOptions<TableParameters>("1,2;3,4?sources=1&destinations=1&bla=foo"), 32UL);
87 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=foo"), 16UL);
88 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=foo"), 21UL);
89 BOOST_CHECK_EQUAL(
90 testInvalidOptions<TableParameters>("1,2;3,4?sources=all&destinations=all&annotations=bla"),
91 49UL);
92 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=asdf"),
93 28UL);
94 BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=10"), 28UL);
95 BOOST_CHECK_EQUAL(
96 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=-1"), 28UL);
97 BOOST_CHECK_EQUAL(
98 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=0"), 28UL);
99 BOOST_CHECK_EQUAL(
100 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
101 28UL);
102 BOOST_CHECK_EQUAL(
103 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
104 28UL);
105 BOOST_CHECK_EQUAL(
106 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
107 28UL);
108 BOOST_CHECK_EQUAL(
109 testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
110 28UL);
111 // TODO(danpat): this is only testing invalid grammar which isn't capable of checking
112 // for values that need to reference other things currently. These
113 // requests are gramatically correct, but semantically incorrect.
114 // The table service properly fails these, as it checks IsValid() after
115 // parsing, which fails when sources/destinations are too large
116 // BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=2"), 7UL);
117 // BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=2"), 7UL);
118 }
119
BOOST_AUTO_TEST_CASE(valid_route_hint)120 BOOST_AUTO_TEST_CASE(valid_route_hint)
121 {
122 engine::PhantomNode reference_node;
123 reference_node.input_location =
124 util::Coordinate(util::FloatLongitude{7.432251}, util::FloatLatitude{43.745995});
125 engine::Hint reference_hint{reference_node, 0x1337};
126 auto encoded_hint = reference_hint.ToBase64();
127 auto hint = engine::Hint::FromBase64(encoded_hint);
128 BOOST_CHECK_EQUAL(hint.phantom.input_location, reference_hint.phantom.input_location);
129 }
130
BOOST_AUTO_TEST_CASE(valid_route_urls)131 BOOST_AUTO_TEST_CASE(valid_route_urls)
132 {
133 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
134 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
135
136 RouteParameters reference_1{};
137 reference_1.coordinates = coords_1;
138 auto result_1 = parseParameters<RouteParameters>("1,2;3,4");
139 BOOST_CHECK(result_1);
140 BOOST_CHECK_EQUAL(reference_1.steps, result_1->steps);
141 BOOST_CHECK_EQUAL(reference_1.alternatives, result_1->alternatives);
142 BOOST_CHECK_EQUAL(reference_1.geometries, result_1->geometries);
143 BOOST_CHECK_EQUAL(reference_1.annotations, result_1->annotations);
144 BOOST_CHECK_EQUAL(reference_1.overview, result_1->overview);
145 BOOST_CHECK_EQUAL(reference_1.continue_straight, result_1->continue_straight);
146 CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
147 CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
148 CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
149 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
150 CHECK_EQUAL_RANGE(reference_1.hints, result_1->hints);
151
152 RouteParameters reference_2{};
153 reference_2.alternatives = true;
154 reference_2.number_of_alternatives = 1;
155 reference_2.steps = true;
156 reference_2.annotations = true;
157 reference_2.coordinates = coords_1;
158 auto result_2 =
159 parseParameters<RouteParameters>("1,2;3,4?steps=true&alternatives=true&geometries=polyline&"
160 "overview=simplified&annotations=true");
161 BOOST_CHECK(result_2);
162 BOOST_CHECK_EQUAL(reference_2.steps, result_2->steps);
163 BOOST_CHECK_EQUAL(reference_2.alternatives, result_2->alternatives);
164 BOOST_CHECK_EQUAL(reference_2.number_of_alternatives, result_2->number_of_alternatives);
165 BOOST_CHECK_EQUAL(reference_2.geometries, result_2->geometries);
166 BOOST_CHECK_EQUAL(reference_2.annotations, result_2->annotations);
167 BOOST_CHECK_EQUAL(reference_2.overview, result_2->overview);
168 BOOST_CHECK_EQUAL(reference_2.continue_straight, result_2->continue_straight);
169 CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
170 CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
171 CHECK_EQUAL_RANGE(reference_2.approaches, result_2->approaches);
172 CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
173 CHECK_EQUAL_RANGE(reference_2.hints, result_2->hints);
174 BOOST_CHECK_EQUAL(result_2->annotations_type == RouteParameters::AnnotationsType::All, true);
175
176 RouteParameters reference_3{false,
177 false,
178 false,
179 RouteParameters::GeometriesType::GeoJSON,
180 RouteParameters::OverviewType::False,
181 true};
182 reference_3.coordinates = coords_1;
183 auto result_3 = api::parseParameters<engine::api::RouteParameters>(
184 "1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&continue_"
185 "straight=true");
186 BOOST_CHECK(result_3);
187 BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
188 BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
189 BOOST_CHECK_EQUAL(reference_3.number_of_alternatives, result_3->number_of_alternatives);
190 BOOST_CHECK_EQUAL(reference_3.geometries, result_3->geometries);
191 BOOST_CHECK_EQUAL(reference_3.annotations, result_3->annotations);
192 BOOST_CHECK_EQUAL(reference_3.overview, result_3->overview);
193 BOOST_CHECK_EQUAL(reference_3.continue_straight, result_3->continue_straight);
194 CHECK_EQUAL_RANGE(reference_3.bearings, result_3->bearings);
195 CHECK_EQUAL_RANGE(reference_3.radiuses, result_3->radiuses);
196 CHECK_EQUAL_RANGE(reference_3.approaches, result_3->approaches);
197 CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates);
198 CHECK_EQUAL_RANGE(reference_3.hints, result_3->hints);
199
200 engine::PhantomNode phantom_1;
201 phantom_1.input_location = coords_1[0];
202 engine::PhantomNode phantom_2;
203 phantom_2.input_location = coords_1[1];
204 std::vector<boost::optional<engine::Hint>> hints_4 = {engine::Hint{phantom_1, 0x1337},
205 engine::Hint{phantom_2, 0x1337}};
206 RouteParameters reference_4{false,
207 false,
208 false,
209 RouteParameters::GeometriesType::Polyline,
210 RouteParameters::OverviewType::Simplified,
211 boost::optional<bool>{},
212 coords_1,
213 hints_4,
214 std::vector<boost::optional<double>>{},
215 std::vector<boost::optional<engine::Bearing>>{}};
216 auto result_4 = parseParameters<RouteParameters>(
217 "1,2;3,4?steps=false&hints=" + hints_4[0]->ToBase64() + ";" + hints_4[1]->ToBase64());
218 BOOST_CHECK(result_4);
219 BOOST_CHECK_EQUAL(reference_4.steps, result_4->steps);
220 BOOST_CHECK_EQUAL(reference_4.alternatives, result_4->alternatives);
221 BOOST_CHECK_EQUAL(reference_4.geometries, result_4->geometries);
222 BOOST_CHECK_EQUAL(reference_4.annotations, result_4->annotations);
223 BOOST_CHECK_EQUAL(reference_4.overview, result_4->overview);
224 BOOST_CHECK_EQUAL(reference_4.continue_straight, result_4->continue_straight);
225 CHECK_EQUAL_RANGE(reference_4.bearings, result_4->bearings);
226 CHECK_EQUAL_RANGE(reference_4.radiuses, result_4->radiuses);
227 CHECK_EQUAL_RANGE(reference_4.approaches, result_4->approaches);
228 CHECK_EQUAL_RANGE(reference_4.coordinates, result_4->coordinates);
229 CHECK_EQUAL_RANGE(reference_4.hints, result_4->hints);
230
231 std::vector<boost::optional<engine::Bearing>> bearings_4 = {
232 boost::none,
233 engine::Bearing{200, 10},
234 engine::Bearing{100, 5},
235 };
236 RouteParameters reference_5{false,
237 false,
238 false,
239 RouteParameters::GeometriesType::Polyline,
240 RouteParameters::OverviewType::Simplified,
241 boost::optional<bool>{},
242 coords_1,
243 std::vector<boost::optional<engine::Hint>>{},
244 std::vector<boost::optional<double>>{},
245 bearings_4};
246 auto result_5 = parseParameters<RouteParameters>("1,2;3,4?steps=false&bearings=;200,10;100,5");
247 BOOST_CHECK(result_5);
248 BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps);
249 BOOST_CHECK_EQUAL(reference_5.alternatives, result_5->alternatives);
250 BOOST_CHECK_EQUAL(reference_5.geometries, result_5->geometries);
251 BOOST_CHECK_EQUAL(reference_5.annotations, result_5->annotations);
252 BOOST_CHECK_EQUAL(reference_5.overview, result_5->overview);
253 BOOST_CHECK_EQUAL(reference_5.continue_straight, result_5->continue_straight);
254 CHECK_EQUAL_RANGE(reference_5.bearings, result_5->bearings);
255 CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses);
256 CHECK_EQUAL_RANGE(reference_5.approaches, result_5->approaches);
257 CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates);
258 CHECK_EQUAL_RANGE(reference_5.hints, result_5->hints);
259
260 std::vector<util::Coordinate> coords_2 = {{util::FloatLongitude{0}, util::FloatLatitude{1}},
261 {util::FloatLongitude{2}, util::FloatLatitude{3}},
262 {util::FloatLongitude{4}, util::FloatLatitude{5}}};
263
264 RouteParameters reference_6{};
265 reference_6.coordinates = coords_2;
266 auto result_6 = parseParameters<RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
267 BOOST_CHECK(result_6);
268 BOOST_CHECK_EQUAL(reference_6.steps, result_6->steps);
269 BOOST_CHECK_EQUAL(reference_6.alternatives, result_6->alternatives);
270 BOOST_CHECK_EQUAL(reference_6.geometries, result_6->geometries);
271 BOOST_CHECK_EQUAL(reference_6.annotations, result_6->annotations);
272 BOOST_CHECK_EQUAL(reference_6.overview, result_6->overview);
273 BOOST_CHECK_EQUAL(reference_6.continue_straight, result_6->continue_straight);
274 CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
275 CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
276 CHECK_EQUAL_RANGE(reference_6.approaches, result_6->approaches);
277 CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);
278 CHECK_EQUAL_RANGE(reference_6.hints, result_6->hints);
279
280 auto result_7 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;unlimited");
281 RouteParameters reference_7{};
282 reference_7.coordinates = coords_1;
283 reference_7.radiuses = {boost::none,
284 boost::make_optional(std::numeric_limits<double>::infinity())};
285 BOOST_CHECK(result_7);
286 BOOST_CHECK_EQUAL(reference_7.steps, result_7->steps);
287 BOOST_CHECK_EQUAL(reference_7.alternatives, result_7->alternatives);
288 BOOST_CHECK_EQUAL(reference_7.geometries, result_7->geometries);
289 BOOST_CHECK_EQUAL(reference_7.annotations, result_7->annotations);
290 BOOST_CHECK_EQUAL(reference_7.overview, result_7->overview);
291 BOOST_CHECK_EQUAL(reference_7.continue_straight, result_7->continue_straight);
292 CHECK_EQUAL_RANGE(reference_7.bearings, result_7->bearings);
293 CHECK_EQUAL_RANGE(reference_7.radiuses, result_7->radiuses);
294 CHECK_EQUAL_RANGE(reference_7.approaches, result_7->approaches);
295 CHECK_EQUAL_RANGE(reference_7.coordinates, result_7->coordinates);
296 CHECK_EQUAL_RANGE(reference_7.hints, result_7->hints);
297
298 auto result_8 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;");
299 RouteParameters reference_8{};
300 reference_8.coordinates = coords_1;
301 reference_8.radiuses = {boost::none, boost::none};
302 BOOST_CHECK(result_8);
303 CHECK_EQUAL_RANGE(reference_8.radiuses, result_8->radiuses);
304
305 auto result_9 = parseParameters<RouteParameters>("1,2?radiuses=");
306 RouteParameters reference_9{};
307 reference_9.coordinates = coords_1;
308 reference_9.radiuses = {boost::none};
309 BOOST_CHECK(result_9);
310 CHECK_EQUAL_RANGE(reference_9.radiuses, result_9->radiuses);
311
312 // Some Hint's are empty
313 std::vector<util::Coordinate> coords_3 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
314 {util::FloatLongitude{3}, util::FloatLatitude{4}},
315 {util::FloatLongitude{5}, util::FloatLatitude{6}},
316 {util::FloatLongitude{7}, util::FloatLatitude{8}}};
317
318 engine::PhantomNode phantom_3;
319 phantom_3.input_location = coords_3[0];
320 engine::PhantomNode phantom_4;
321 phantom_4.input_location = coords_3[2];
322 std::vector<boost::optional<engine::Hint>> hints_10 = {
323 engine::Hint{phantom_3, 0x1337}, boost::none, engine::Hint{phantom_4, 0x1337}, boost::none};
324
325 RouteParameters reference_10{false,
326 false,
327 false,
328 RouteParameters::GeometriesType::Polyline,
329 RouteParameters::OverviewType::Simplified,
330 boost::optional<bool>{},
331 coords_3,
332 hints_10,
333 std::vector<boost::optional<double>>{},
334 std::vector<boost::optional<engine::Bearing>>{}};
335 auto result_10 = parseParameters<RouteParameters>(
336 "1,2;3,4;5,6;7,8?steps=false&hints=" + hints_10[0]->ToBase64() + ";;" +
337 hints_10[2]->ToBase64() + ";");
338 BOOST_CHECK(result_10);
339 BOOST_CHECK_EQUAL(reference_10.steps, result_10->steps);
340 BOOST_CHECK_EQUAL(reference_10.alternatives, result_10->alternatives);
341 BOOST_CHECK_EQUAL(reference_10.geometries, result_10->geometries);
342 BOOST_CHECK_EQUAL(reference_10.annotations, result_10->annotations);
343 BOOST_CHECK_EQUAL(reference_10.overview, result_10->overview);
344 BOOST_CHECK_EQUAL(reference_10.continue_straight, result_10->continue_straight);
345 CHECK_EQUAL_RANGE(reference_10.bearings, result_10->bearings);
346 CHECK_EQUAL_RANGE(reference_10.radiuses, result_10->radiuses);
347 CHECK_EQUAL_RANGE(reference_10.approaches, result_10->approaches);
348 CHECK_EQUAL_RANGE(reference_10.coordinates, result_10->coordinates);
349 CHECK_EQUAL_RANGE(reference_10.hints, result_10->hints);
350
351 // Do not generate Hints when they are explicitly disabled
352 auto result_11 = parseParameters<RouteParameters>("1,2;3,4?generate_hints=false");
353 BOOST_CHECK(result_11);
354 BOOST_CHECK_EQUAL(result_11->generate_hints, false);
355
356 auto result_12 = parseParameters<RouteParameters>("1,2;3,4?generate_hints=true");
357 BOOST_CHECK(result_12);
358 BOOST_CHECK_EQUAL(result_12->generate_hints, true);
359
360 auto result_13 = parseParameters<RouteParameters>("1,2;3,4");
361 BOOST_CHECK(result_13);
362 BOOST_CHECK_EQUAL(result_13->generate_hints, true);
363
364 // parse none annotations value correctly
365 RouteParameters reference_14{};
366 reference_14.annotations_type = RouteParameters::AnnotationsType::None;
367 reference_14.coordinates = coords_1;
368 auto result_14 = parseParameters<RouteParameters>("1,2;3,4?geometries=polyline");
369 BOOST_CHECK(result_14);
370 BOOST_CHECK_EQUAL(reference_14.geometries, result_14->geometries);
371 BOOST_CHECK_EQUAL(result_14->annotations_type == RouteParameters::AnnotationsType::None, true);
372 BOOST_CHECK_EQUAL(result_14->annotations, false);
373
374 // parse single annotations value correctly
375 RouteParameters reference_15{};
376 reference_15.annotations_type = RouteParameters::AnnotationsType::Duration;
377 reference_15.coordinates = coords_1;
378 auto result_15 = parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
379 "overview=simplified&annotations=duration");
380 BOOST_CHECK(result_15);
381 BOOST_CHECK_EQUAL(reference_15.geometries, result_15->geometries);
382 BOOST_CHECK_EQUAL(result_15->annotations_type == RouteParameters::AnnotationsType::Duration,
383 true);
384 BOOST_CHECK_EQUAL(result_15->annotations, true);
385
386 RouteParameters reference_speed{};
387 reference_speed.annotations_type = RouteParameters::AnnotationsType::Duration;
388 reference_speed.coordinates = coords_1;
389 auto result_speed =
390 parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
391 "overview=simplified&annotations=duration,distance,speed");
392 BOOST_CHECK(result_speed);
393 BOOST_CHECK_EQUAL(reference_speed.geometries, result_speed->geometries);
394 BOOST_CHECK_EQUAL(reference_speed.overview, result_speed->overview);
395 BOOST_CHECK_EQUAL(result_speed->annotations_type ==
396 (RouteParameters::AnnotationsType::Duration |
397 RouteParameters::AnnotationsType::Distance |
398 RouteParameters::AnnotationsType::Speed),
399 true);
400 BOOST_CHECK_EQUAL(result_speed->annotations, true);
401
402 // parse multiple annotations correctly
403 RouteParameters reference_16{};
404 reference_16.annotations_type = RouteParameters::AnnotationsType::Duration |
405 RouteParameters::AnnotationsType::Weight |
406 RouteParameters::AnnotationsType::Nodes;
407 reference_16.coordinates = coords_1;
408 auto result_16 =
409 parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
410 "overview=simplified&annotations=duration,weight,nodes");
411 BOOST_CHECK(result_16);
412 BOOST_CHECK_EQUAL(reference_16.geometries, result_16->geometries);
413 BOOST_CHECK_EQUAL(static_cast<bool>(result_16->annotations_type &
414 (RouteParameters::AnnotationsType::Weight |
415 RouteParameters::AnnotationsType::Duration |
416 RouteParameters::AnnotationsType::Nodes)),
417 true);
418 BOOST_CHECK_EQUAL(result_16->annotations, true);
419
420 // parse all annotations correctly
421 RouteParameters reference_17{};
422 reference_17.annotations_type = RouteParameters::AnnotationsType::All;
423 reference_17.coordinates = coords_1;
424 auto result_17 = parseParameters<RouteParameters>(
425 "1,2;3,4?overview=simplified&annotations=duration,weight,nodes,datasources,distance");
426 BOOST_CHECK(result_17);
427 BOOST_CHECK_EQUAL(reference_17.geometries, result_17->geometries);
428 BOOST_CHECK_EQUAL(result_2->annotations_type == RouteParameters::AnnotationsType::All, true);
429 BOOST_CHECK_EQUAL(result_17->annotations, true);
430
431 std::vector<boost::optional<engine::Approach>> approaches_18 = {
432 boost::none,
433 engine::Approach::CURB,
434 engine::Approach::UNRESTRICTED,
435 engine::Approach::CURB,
436 };
437 RouteParameters reference_18{false,
438 false,
439 false,
440 RouteParameters::GeometriesType::Polyline,
441 RouteParameters::OverviewType::Simplified,
442 boost::optional<bool>{},
443 coords_3,
444 std::vector<boost::optional<engine::Hint>>{},
445 std::vector<boost::optional<double>>{},
446 std::vector<boost::optional<engine::Bearing>>{},
447 approaches_18};
448
449 auto result_18 = parseParameters<RouteParameters>(
450 "1,2;3,4;5,6;7,8?steps=false&approaches=;curb;unrestricted;curb");
451 BOOST_CHECK(result_18);
452 BOOST_CHECK_EQUAL(reference_18.steps, result_18->steps);
453 BOOST_CHECK_EQUAL(reference_18.alternatives, result_18->alternatives);
454 BOOST_CHECK_EQUAL(reference_18.geometries, result_18->geometries);
455 BOOST_CHECK_EQUAL(reference_18.annotations, result_18->annotations);
456 BOOST_CHECK_EQUAL(reference_18.overview, result_18->overview);
457 BOOST_CHECK_EQUAL(reference_18.continue_straight, result_18->continue_straight);
458 CHECK_EQUAL_RANGE(reference_18.bearings, result_18->bearings);
459 CHECK_EQUAL_RANGE(reference_18.radiuses, result_18->radiuses);
460 CHECK_EQUAL_RANGE(reference_18.approaches, result_18->approaches);
461 CHECK_EQUAL_RANGE(reference_18.coordinates, result_18->coordinates);
462 CHECK_EQUAL_RANGE(reference_18.hints, result_18->hints);
463
464 RouteParameters reference_19{};
465 reference_19.alternatives = true;
466 reference_19.number_of_alternatives = 3;
467 reference_19.coordinates = coords_1;
468 auto result_19 = parseParameters<RouteParameters>("1,2;3,4?alternatives=3");
469 BOOST_CHECK(result_19);
470 BOOST_CHECK_EQUAL(reference_19.steps, result_19->steps);
471 BOOST_CHECK_EQUAL(reference_19.alternatives, result_19->alternatives);
472 BOOST_CHECK_EQUAL(reference_19.number_of_alternatives, result_19->number_of_alternatives);
473 BOOST_CHECK_EQUAL(reference_19.geometries, result_19->geometries);
474 BOOST_CHECK_EQUAL(reference_19.annotations, result_19->annotations);
475 BOOST_CHECK_EQUAL(reference_19.overview, result_19->overview);
476 BOOST_CHECK_EQUAL(reference_19.continue_straight, result_19->continue_straight);
477 CHECK_EQUAL_RANGE(reference_19.bearings, result_19->bearings);
478 CHECK_EQUAL_RANGE(reference_19.radiuses, result_19->radiuses);
479 CHECK_EQUAL_RANGE(reference_19.approaches, result_19->approaches);
480 CHECK_EQUAL_RANGE(reference_19.coordinates, result_19->coordinates);
481 CHECK_EQUAL_RANGE(reference_19.hints, result_19->hints);
482
483 RouteParameters reference_20{};
484 reference_20.alternatives = false;
485 reference_20.number_of_alternatives = 0;
486 reference_20.coordinates = coords_1;
487 auto result_20 = parseParameters<RouteParameters>("1,2;3,4?alternatives=0");
488 BOOST_CHECK(result_20);
489 BOOST_CHECK_EQUAL(reference_20.steps, result_20->steps);
490 BOOST_CHECK_EQUAL(reference_20.alternatives, result_20->alternatives);
491 BOOST_CHECK_EQUAL(reference_20.number_of_alternatives, result_20->number_of_alternatives);
492 BOOST_CHECK_EQUAL(reference_20.geometries, result_20->geometries);
493 BOOST_CHECK_EQUAL(reference_20.annotations, result_20->annotations);
494 BOOST_CHECK_EQUAL(reference_20.overview, result_20->overview);
495 BOOST_CHECK_EQUAL(reference_20.continue_straight, result_20->continue_straight);
496 CHECK_EQUAL_RANGE(reference_20.bearings, result_20->bearings);
497 CHECK_EQUAL_RANGE(reference_20.radiuses, result_20->radiuses);
498 CHECK_EQUAL_RANGE(reference_20.approaches, result_20->approaches);
499 CHECK_EQUAL_RANGE(reference_20.coordinates, result_20->coordinates);
500 CHECK_EQUAL_RANGE(reference_20.hints, result_20->hints);
501
502 // exclude flags
503 RouteParameters reference_21{};
504 reference_21.exclude = {"ferry", "motorway"};
505 reference_21.coordinates = coords_1;
506 auto result_21 = parseParameters<RouteParameters>("1,2;3,4?exclude=ferry,motorway");
507 BOOST_CHECK(result_21);
508 BOOST_CHECK_EQUAL(reference_21.steps, result_21->steps);
509 BOOST_CHECK_EQUAL(reference_21.alternatives, result_21->alternatives);
510 BOOST_CHECK_EQUAL(reference_21.number_of_alternatives, result_21->number_of_alternatives);
511 BOOST_CHECK_EQUAL(reference_21.geometries, result_21->geometries);
512 BOOST_CHECK_EQUAL(reference_21.annotations, result_21->annotations);
513 BOOST_CHECK_EQUAL(reference_21.overview, result_21->overview);
514 BOOST_CHECK_EQUAL(reference_21.continue_straight, result_21->continue_straight);
515 CHECK_EQUAL_RANGE(reference_21.bearings, result_21->bearings);
516 CHECK_EQUAL_RANGE(reference_21.radiuses, result_21->radiuses);
517 CHECK_EQUAL_RANGE(reference_21.approaches, result_21->approaches);
518 CHECK_EQUAL_RANGE(reference_21.coordinates, result_21->coordinates);
519 CHECK_EQUAL_RANGE(reference_21.hints, result_21->hints);
520 CHECK_EQUAL_RANGE(reference_21.exclude, result_21->exclude);
521 }
522
BOOST_AUTO_TEST_CASE(valid_table_urls)523 BOOST_AUTO_TEST_CASE(valid_table_urls)
524 {
525 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
526 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
527
528 TableParameters reference_1{};
529 reference_1.coordinates = coords_1;
530 auto result_1 = parseParameters<TableParameters>("1,2;3,4");
531 BOOST_CHECK(result_1);
532 CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources);
533 CHECK_EQUAL_RANGE(reference_1.destinations, result_1->destinations);
534 CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
535 CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
536 CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
537 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
538
539 std::vector<std::size_t> sources_2 = {1, 2, 3};
540 std::vector<std::size_t> destinations_2 = {4, 5};
541 TableParameters reference_2{sources_2, destinations_2};
542 reference_2.coordinates = coords_1;
543 auto result_2 = parseParameters<TableParameters>("1,2;3,4?sources=1;2;3&destinations=4;5");
544 BOOST_CHECK(result_2);
545 CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources);
546 CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations);
547 CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
548 CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
549 CHECK_EQUAL_RANGE(reference_2.approaches, result_2->approaches);
550 CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
551
552 auto result_3 = parseParameters<TableParameters>("1,2;3,4?sources=all&destinations=all");
553 BOOST_CHECK(result_3);
554 CHECK_EQUAL_RANGE(reference_1.sources, result_3->sources);
555 CHECK_EQUAL_RANGE(reference_1.destinations, result_3->destinations);
556 CHECK_EQUAL_RANGE(reference_1.bearings, result_3->bearings);
557 CHECK_EQUAL_RANGE(reference_1.radiuses, result_3->radiuses);
558 CHECK_EQUAL_RANGE(reference_1.approaches, result_3->approaches);
559 CHECK_EQUAL_RANGE(reference_1.coordinates, result_3->coordinates);
560
561 TableParameters reference_4{};
562 reference_4.coordinates = coords_1;
563 auto result_4 = parseParameters<TableParameters>(
564 "1,2;3,4?sources=all&destinations=all&annotations=duration");
565 BOOST_CHECK(result_4);
566 BOOST_CHECK_EQUAL(result_4->annotations & (TableParameters::AnnotationsType::Distance |
567 TableParameters::AnnotationsType::Duration),
568 true);
569 CHECK_EQUAL_RANGE(reference_4.sources, result_4->sources);
570 CHECK_EQUAL_RANGE(reference_4.destinations, result_4->destinations);
571
572 TableParameters reference_5{};
573 reference_5.coordinates = coords_1;
574 auto result_5 = parseParameters<TableParameters>(
575 "1,2;3,4?sources=all&destinations=all&annotations=duration");
576 BOOST_CHECK(result_5);
577 BOOST_CHECK_EQUAL(result_5->annotations & TableParameters::AnnotationsType::Duration, true);
578 CHECK_EQUAL_RANGE(reference_5.sources, result_5->sources);
579 CHECK_EQUAL_RANGE(reference_5.destinations, result_5->destinations);
580
581 TableParameters reference_6{};
582 reference_6.coordinates = coords_1;
583 auto result_6 = parseParameters<TableParameters>(
584 "1,2;3,4?sources=all&destinations=all&annotations=distance");
585 BOOST_CHECK(result_6);
586 BOOST_CHECK_EQUAL(result_6->annotations & TableParameters::AnnotationsType::Distance, true);
587 CHECK_EQUAL_RANGE(reference_6.sources, result_6->sources);
588 CHECK_EQUAL_RANGE(reference_6.destinations, result_6->destinations);
589
590 TableParameters reference_7{};
591 reference_7.coordinates = coords_1;
592 auto result_7 = parseParameters<TableParameters>("1,2;3,4?annotations=distance");
593 BOOST_CHECK(result_7);
594 BOOST_CHECK_EQUAL(result_7->annotations & TableParameters::AnnotationsType::Distance, true);
595 CHECK_EQUAL_RANGE(reference_7.sources, result_7->sources);
596 CHECK_EQUAL_RANGE(reference_7.destinations, result_7->destinations);
597
598 TableParameters reference_8{};
599 reference_8.coordinates = coords_1;
600 auto result_8 =
601 parseParameters<TableParameters>("1,2;3,4?annotations=distance&fallback_speed=2.5");
602 BOOST_CHECK(result_8);
603 BOOST_CHECK_EQUAL(result_8->annotations & TableParameters::AnnotationsType::Distance, true);
604 CHECK_EQUAL_RANGE(reference_8.sources, result_8->sources);
605 CHECK_EQUAL_RANGE(reference_8.destinations, result_8->destinations);
606
607 TableParameters reference_9{};
608 reference_9.coordinates = coords_1;
609 auto result_9 = parseParameters<TableParameters>(
610 "1,2;3,4?annotations=distance&fallback_speed=2.5&fallback_coordinate=input");
611 BOOST_CHECK(result_9);
612 BOOST_CHECK_EQUAL(result_9->annotations & TableParameters::AnnotationsType::Distance, true);
613 CHECK_EQUAL_RANGE(reference_9.sources, result_9->sources);
614 CHECK_EQUAL_RANGE(reference_9.destinations, result_9->destinations);
615
616 TableParameters reference_10{};
617 reference_10.coordinates = coords_1;
618 auto result_10 = parseParameters<TableParameters>(
619 "1,2;3,4?annotations=distance&fallback_speed=20&fallback_coordinate=snapped");
620 BOOST_CHECK(result_10);
621 BOOST_CHECK_EQUAL(result_10->annotations & TableParameters::AnnotationsType::Distance, true);
622 CHECK_EQUAL_RANGE(reference_10.sources, result_10->sources);
623 CHECK_EQUAL_RANGE(reference_10.destinations, result_10->destinations);
624
625 auto result_11 = parseParameters<TableParameters>("1,2;3,4?sources=all&destinations=all&"
626 "annotations=duration&fallback_speed=1&"
627 "fallback_coordinate=snapped&scale_factor=2");
628 BOOST_CHECK(result_11);
629 CHECK_EQUAL_RANGE(reference_1.sources, result_11->sources);
630 CHECK_EQUAL_RANGE(reference_1.destinations, result_11->destinations);
631 CHECK_EQUAL_RANGE(reference_1.bearings, result_11->bearings);
632 CHECK_EQUAL_RANGE(reference_1.radiuses, result_11->radiuses);
633 CHECK_EQUAL_RANGE(reference_1.approaches, result_11->approaches);
634 CHECK_EQUAL_RANGE(reference_1.coordinates, result_11->coordinates);
635 }
636
BOOST_AUTO_TEST_CASE(valid_match_urls)637 BOOST_AUTO_TEST_CASE(valid_match_urls)
638 {
639 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
640 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
641
642 MatchParameters reference_1{};
643 reference_1.coordinates = coords_1;
644 auto result_1 = parseParameters<MatchParameters>("1,2;3,4");
645 BOOST_CHECK(result_1);
646 CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
647 CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
648 CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
649 CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
650 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
651
652 MatchParameters reference_2{};
653 reference_2.coordinates = coords_1;
654 reference_2.timestamps = {5, 6};
655 auto result_2 = parseParameters<MatchParameters>("1,2;3,4?timestamps=5;6");
656 BOOST_CHECK(result_2);
657 CHECK_EQUAL_RANGE(reference_2.timestamps, result_2->timestamps);
658 CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
659 CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
660 CHECK_EQUAL_RANGE(reference_2.approaches, result_2->approaches);
661 CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
662
663 std::vector<util::Coordinate> coords_2 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
664 {util::FloatLongitude{3}, util::FloatLatitude{4}},
665 {util::FloatLongitude{5}, util::FloatLatitude{6}}};
666
667 MatchParameters reference_3{};
668 reference_3.coordinates = coords_2;
669 reference_3.waypoints = {0, 2};
670 auto result_3 = parseParameters<MatchParameters>("1,2;3,4;5,6?waypoints=0;2");
671 BOOST_CHECK(result_3);
672 CHECK_EQUAL_RANGE(reference_3.waypoints, result_3->waypoints);
673 CHECK_EQUAL_RANGE(reference_3.timestamps, result_3->timestamps);
674 CHECK_EQUAL_RANGE(reference_3.bearings, result_3->bearings);
675 CHECK_EQUAL_RANGE(reference_3.radiuses, result_3->radiuses);
676 CHECK_EQUAL_RANGE(reference_3.approaches, result_3->approaches);
677 CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates);
678 }
679
BOOST_AUTO_TEST_CASE(invalid_match_urls)680 BOOST_AUTO_TEST_CASE(invalid_match_urls)
681 {
682 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
683 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
684
685 MatchParameters reference_1{};
686 reference_1.coordinates = coords_1;
687 auto result_1 = parseParameters<MatchParameters>("1,2;3,4?radiuses=unlimited;60");
688 BOOST_CHECK(result_1);
689 CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
690 CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
691 BOOST_CHECK(reference_1.radiuses != result_1->radiuses);
692 CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
693 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
694
695 std::vector<util::Coordinate> coords_2 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
696 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
697
698 MatchParameters reference_2{};
699 reference_2.coordinates = coords_2;
700 BOOST_CHECK_EQUAL(testInvalidOptions<MatchParameters>("1,2;3,4?waypoints=0,4"), 19UL);
701 BOOST_CHECK_EQUAL(testInvalidOptions<MatchParameters>("1,2;3,4?waypoints=x;4"), 18UL);
702 BOOST_CHECK_EQUAL(testInvalidOptions<MatchParameters>("1,2;3,4?waypoints=0;3.5"), 21UL);
703 }
704
BOOST_AUTO_TEST_CASE(valid_nearest_urls)705 BOOST_AUTO_TEST_CASE(valid_nearest_urls)
706 {
707 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}}};
708
709 NearestParameters reference_1{};
710 reference_1.coordinates = coords_1;
711 auto result_1 = parseParameters<NearestParameters>("1,2");
712 BOOST_CHECK(result_1);
713 BOOST_CHECK_EQUAL(reference_1.number_of_results, result_1->number_of_results);
714 CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
715 CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
716 CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
717 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
718
719 NearestParameters reference_2{};
720 reference_2.coordinates = coords_1;
721 reference_2.number_of_results = 42;
722 auto result_2 = parseParameters<NearestParameters>("1,2?number=42");
723 BOOST_CHECK(result_2);
724 BOOST_CHECK_EQUAL(reference_2.number_of_results, result_2->number_of_results);
725 CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
726 CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
727 CHECK_EQUAL_RANGE(reference_2.approaches, result_2->approaches);
728 CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
729 }
730
BOOST_AUTO_TEST_CASE(invalid_tile_urls)731 BOOST_AUTO_TEST_CASE(invalid_tile_urls)
732 {
733 TileParameters reference_1{1, 2, 3};
734 auto result_1 = parseParameters<TileParameters>("tile(1,2,3).mvt");
735 BOOST_CHECK(result_1);
736 BOOST_CHECK(!result_1->IsValid());
737 BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
738 BOOST_CHECK_EQUAL(reference_1.y, result_1->y);
739 BOOST_CHECK_EQUAL(reference_1.z, result_1->z);
740 }
741
BOOST_AUTO_TEST_CASE(valid_tile_urls)742 BOOST_AUTO_TEST_CASE(valid_tile_urls)
743 {
744 TileParameters reference_1{1, 2, 12};
745 auto result_1 = parseParameters<TileParameters>("tile(1,2,12).mvt");
746 BOOST_CHECK(result_1->IsValid());
747 BOOST_CHECK(result_1);
748 BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
749 BOOST_CHECK_EQUAL(reference_1.y, result_1->y);
750 BOOST_CHECK_EQUAL(reference_1.z, result_1->z);
751 }
752
BOOST_AUTO_TEST_CASE(valid_trip_urls)753 BOOST_AUTO_TEST_CASE(valid_trip_urls)
754 {
755 std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude{1}, util::FloatLatitude{2}},
756 {util::FloatLongitude{3}, util::FloatLatitude{4}}};
757
758 TripParameters reference_1{};
759 reference_1.coordinates = coords_1;
760 auto result_1 = parseParameters<TripParameters>("1,2;3,4");
761 BOOST_CHECK(result_1);
762 CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
763 CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
764
765 TripParameters reference_2{};
766 reference_2.coordinates = coords_1;
767 reference_2.source = TripParameters::SourceType::First;
768 reference_2.destination = TripParameters::DestinationType::Last;
769 auto result_2 = parseParameters<TripParameters>("1,2;3,4?source=first&destination=last");
770 BOOST_CHECK(result_2);
771 CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
772 CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
773
774 // check supported source/destination/rountrip combinations
775 auto param_fse_r =
776 parseParameters<TripParameters>("1,2;3,4?source=first&destination=last&roundtrip=true");
777 BOOST_CHECK(param_fse_r->IsValid());
778 auto param_fse_nr_ =
779 parseParameters<TripParameters>("1,2;3,4?source=first&destination=last&roundtrip=false");
780 BOOST_CHECK(param_fse_nr_->IsValid());
781 auto param_fs_r = parseParameters<TripParameters>("1,2;3,4?source=first&roundtrip=true");
782 BOOST_CHECK(param_fs_r->IsValid());
783 auto param_fs_nr = parseParameters<TripParameters>("1,2;3,4?source=first&roundtrip=false");
784 BOOST_CHECK(param_fs_nr->IsValid());
785 auto param_fe_r = parseParameters<TripParameters>("1,2;3,4?destination=last&roundtrip=true");
786 BOOST_CHECK(param_fe_r->IsValid());
787 auto param_fe_nr = parseParameters<TripParameters>("1,2;3,4?destination=last&roundtrip=false");
788 BOOST_CHECK(param_fe_nr->IsValid());
789 auto param_r = parseParameters<TripParameters>("1,2;3,4?roundtrip=true");
790 BOOST_CHECK(param_r->IsValid());
791 auto param_nr = parseParameters<TripParameters>("1,2;3,4?roundtrip=false");
792 BOOST_CHECK(param_nr->IsValid());
793
794 auto param_fail_1 =
795 testInvalidOptions<TripParameters>("1,2;3,4?source=blubb&destination=random");
796 BOOST_CHECK_EQUAL(param_fail_1, 15UL);
797 auto param_fail_2 = testInvalidOptions<TripParameters>("1,2;3,4?source=first&destination=nah");
798 BOOST_CHECK_EQUAL(param_fail_2, 33UL);
799 }
800
801 BOOST_AUTO_TEST_SUITE_END()
802