android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / test / src / TestWaypoints.cpp
blob4f82340bc4c0e5d2823110e170151b564810f50e
1 /* Copyright_License {
3 XCSoar Glide Computer - http://www.xcsoar.org/
4 Copyright (C) 2000-2013 The XCSoar Project
5 A detailed list of copyright holders can be found in the file "AUTHORS".
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "test_debug.hpp"
25 #include "Waypoint/WaypointVisitor.hpp"
26 #include "Waypoint/Waypoints.hpp"
27 #include "Geo/GeoVector.hpp"
29 #include <stdio.h>
30 #include <tchar.h>
32 class WaypointPredicateCounter: public WaypointVisitor
34 public:
35 typedef std::function<bool(const Waypoint &wp)> Predicate;
37 private:
38 Predicate predicate;
39 unsigned count;
41 public:
42 WaypointPredicateCounter(const Predicate &_predicate)
43 :predicate(_predicate), count(0) {}
45 virtual void Visit(const Waypoint &wp) {
46 if (predicate(wp))
47 count++;
50 unsigned GetCounter() const {
51 return count;
55 static void
56 AddSpiralWaypoints(Waypoints &waypoints,
57 const GeoPoint &center = GeoPoint(Angle::Degrees(51.4),
58 Angle::Degrees(7.85)),
59 Angle angle_start = Angle::Degrees(0),
60 Angle angle_step = Angle::Degrees(15),
61 fixed distance_start = fixed(0),
62 fixed distance_step = fixed(1000),
63 fixed distance_max = fixed(150000))
65 assert(positive(distance_step));
67 for (unsigned i = 0;; ++i) {
68 GeoVector vector;
69 vector.distance = distance_start + distance_step * i;
70 if (vector.distance > distance_max)
71 break;
73 vector.bearing = angle_start + angle_step * i;
75 Waypoint waypoint;
76 waypoint.location = vector.EndPoint(center);
77 waypoint.original_id = i;
78 waypoint.elevation = fixed(i * 10 - 500);
80 StaticString<256> buffer;
82 if (i % 7 == 0) {
83 buffer = _T("Airfield");
84 waypoint.type = Waypoint::Type::AIRFIELD;
85 } else if (i % 3 == 0) {
86 buffer = _T("Field");
87 waypoint.type = Waypoint::Type::OUTLANDING;
88 } else
89 buffer = _T("Waypoint");
91 buffer.AppendFormat(_T(" #%d"), i + 1);
92 waypoint.name = buffer;
94 waypoints.Append(std::move(waypoint));
97 waypoints.Optimise();
100 static void
101 TestLookups(const Waypoints &waypoints, const GeoPoint &center)
103 const Waypoint *waypoint;
105 ok1((waypoint = waypoints.LookupId(0)) == NULL);
106 ok1((waypoint = waypoints.LookupId(1)) != NULL);
107 ok1(waypoint->original_id == 0);
108 ok1((waypoint = waypoints.LookupId(151)) != NULL);
109 ok1(waypoint->original_id == 150);
110 ok1((waypoint = waypoints.LookupId(152)) == NULL);
111 ok1((waypoint = waypoints.LookupId(160)) == NULL);
113 ok1((waypoint = waypoints.LookupLocation(center, fixed(0))) != NULL);
114 ok1(waypoint->original_id == 0);
116 ok1((waypoint = waypoints.LookupName(_T("Waypoint #5"))) != NULL);
117 ok1(waypoint->original_id == 4);
119 ok1((waypoint = waypoints.LookupLocation(waypoint->location, fixed(10000))) != NULL);
120 ok1(waypoint->original_id == 4);
123 class BeginsWith
125 const TCHAR *prefix;
127 public:
128 BeginsWith(const TCHAR *_prefix):prefix(_prefix) {}
130 bool operator()(const Waypoint &waypoint) {
131 return StringStartsWith(waypoint.name.c_str(), prefix);
135 static void
136 TestNamePrefixVisitor(const Waypoints &waypoints, const TCHAR *prefix,
137 unsigned expected_results)
139 WaypointPredicateCounter::Predicate predicate = BeginsWith(prefix);
140 WaypointPredicateCounter prefix_counter(predicate);
141 waypoints.VisitNamePrefix(prefix, prefix_counter);
142 ok1(prefix_counter.GetCounter() == expected_results);
145 static void
146 TestNamePrefixVisitor(const Waypoints &waypoints)
148 TestNamePrefixVisitor(waypoints, _T(""), 151);
149 TestNamePrefixVisitor(waypoints, _T("Foo"), 0);
150 TestNamePrefixVisitor(waypoints, _T("a"), 0);
151 TestNamePrefixVisitor(waypoints, _T("A"), 22);
152 TestNamePrefixVisitor(waypoints, _T("Air"), 22);
153 TestNamePrefixVisitor(waypoints, _T("Field"), 51 - 8);
156 class CloserThan
158 fixed distance;
159 GeoPoint location;
161 public:
162 CloserThan(fixed _distance, const GeoPoint &_location)
163 :distance(_distance), location(_location) {}
165 bool operator()(const Waypoint &waypoint) {
166 return location.Distance(waypoint.location) < distance;
170 static void
171 TestRangeVisitor(const Waypoints &waypoints, const GeoPoint &location,
172 fixed distance, unsigned expected_results)
174 WaypointPredicateCounter::Predicate predicate = CloserThan(distance, location);
175 WaypointPredicateCounter distance_counter(predicate);
176 waypoints.VisitWithinRange(location, distance, distance_counter);
177 ok1(distance_counter.GetCounter() == expected_results);
180 static void
181 TestRangeVisitor(const Waypoints &waypoints, const GeoPoint &center)
183 TestRangeVisitor(waypoints, center, fixed(1), 1);
184 TestRangeVisitor(waypoints, center, fixed(999), 1);
185 TestRangeVisitor(waypoints, center, fixed(1300), 2);
186 TestRangeVisitor(waypoints, center, fixed(10500), 11);
187 TestRangeVisitor(waypoints, center, fixed(1000000), 151);
190 static bool
191 OriginalIDAbove5(const Waypoint &waypoint) {
192 return waypoint.original_id > 5;
195 static void
196 TestGetNearest(const Waypoints &waypoints, const GeoPoint &center)
198 const Waypoint *waypoint;
199 GeoPoint near = GeoVector(fixed(250), Angle::Degrees(15)).EndPoint(center);
200 GeoPoint far = GeoVector(fixed(750), Angle::Degrees(15)).EndPoint(center);
201 GeoPoint further = GeoVector(fixed(4200), Angle::Degrees(48)).EndPoint(center);
203 ok1((waypoint = waypoints.GetNearest(center, fixed(1))) != NULL);
204 ok1(waypoint->original_id == 0);
206 ok1((waypoint = waypoints.GetNearest(center, fixed(10000))) != NULL);
207 ok1(waypoint->original_id == 0);
209 ok1((waypoint = waypoints.GetNearest(near, fixed(1))) == NULL);
211 ok1((waypoint = waypoints.GetNearest(near, fixed(10000))) != NULL);
212 ok1(waypoint->original_id == 0);
214 ok1((waypoint = waypoints.GetNearest(far, fixed(1))) == NULL);
216 ok1((waypoint = waypoints.GetNearest(far, fixed(10000))) != NULL);
217 ok1(waypoint->original_id == 1);
219 ok1((waypoint = waypoints.GetNearestLandable(center, fixed(1))) != NULL);
220 ok1(waypoint->original_id == 0);
222 ok1((waypoint = waypoints.GetNearestLandable(center, fixed(10000))) != NULL);
223 ok1(waypoint->original_id == 0);
225 ok1((waypoint = waypoints.GetNearestLandable(further, fixed(1))) == NULL);
227 ok1((waypoint = waypoints.GetNearestLandable(further, fixed(10000))) != NULL);
228 ok1(waypoint->original_id == 3);
230 ok1((waypoint = waypoints.GetNearestIf(center, fixed(1), OriginalIDAbove5)) == NULL);
232 ok1((waypoint = waypoints.GetNearestIf(center, fixed(10000), OriginalIDAbove5)) != NULL);
233 ok1(waypoint->original_id == 6);
236 static void
237 TestIterator(const Waypoints &waypoints)
239 unsigned count = 0;
240 for (auto it = waypoints.begin(), end = waypoints.end(); it != end; ++it)
241 count++;
243 ok1(count == 151);
246 static unsigned
247 TestCopy(Waypoints& waypoints)
249 const Waypoint *wp = waypoints.LookupId(5);
250 if (!wp)
251 return false;
253 unsigned size_old = waypoints.size();
254 Waypoint wp_copy = *wp;
255 wp_copy.id = waypoints.size() + 1;
256 waypoints.Append(std::move(wp_copy));
257 waypoints.Optimise();
258 unsigned size_new = waypoints.size();
259 return (size_new == size_old + 1);
262 static bool
263 TestErase(Waypoints& waypoints, unsigned id)
265 waypoints.Optimise();
266 const Waypoint* wp;
267 wp = waypoints.LookupId(id);
268 if (wp == NULL)
269 return false;
271 waypoints.Erase(*wp);
272 waypoints.Optimise();
274 wp = waypoints.LookupId(id);
275 return wp == NULL;
278 static bool
279 TestReplace(Waypoints& waypoints, unsigned id)
281 const Waypoint* wp;
282 wp = waypoints.LookupId(id);
283 if (wp == NULL)
284 return false;
286 tstring oldName = wp->name;
288 Waypoint copy = *wp;
289 copy.name = _T("Fred");
290 waypoints.Replace(*wp, copy);
291 waypoints.Optimise();
293 wp = waypoints.LookupId(id);
294 return wp != NULL && wp->name != oldName && wp->name == _T("Fred");
298 main(int argc, char** argv)
300 if (!ParseArgs(argc, argv))
301 return 0;
303 plan_tests(52);
305 Waypoints waypoints;
306 GeoPoint center(Angle::Degrees(51.4), Angle::Degrees(7.85));
308 // AddSpiralWaypoints creates 151 waypoints from
309 // 0km to 150km distance in 1km steps
310 AddSpiralWaypoints(waypoints, center);
312 ok1(!waypoints.IsEmpty());
313 ok1(waypoints.size() == 151);
315 TestLookups(waypoints, center);
316 TestNamePrefixVisitor(waypoints);
317 TestRangeVisitor(waypoints, center);
318 TestGetNearest(waypoints, center);
319 TestIterator(waypoints);
321 ok(TestCopy(waypoints), "waypoint copy", 0);
322 ok(TestErase(waypoints, 3), "waypoint erase", 0);
323 ok(TestReplace(waypoints, 4), "waypoint replace", 0);
325 // test clear
326 waypoints.Clear();
327 ok1(waypoints.IsEmpty());
328 ok1(waypoints.size() == 0);
330 return exit_status();