gucoordinates
GUCoordinatesTests.hpp
Go to the documentation of this file.
1/*
2 * GUCoordinatesTests.hpp
3 * tests
4 *
5 * Created by Callum McColl on 20/06/2020.
6 * Copyright © 2020 Callum McColl. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials
18 * provided with the distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgement:
22 *
23 * This product includes software developed by Callum McColl.
24 *
25 * 4. Neither the name of the author nor the names of contributors
26 * may be used to endorse or promote products derived from this
27 * software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
33 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * -----------------------------------------------------------------------
42 * This program is free software; you can redistribute it and/or
43 * modify it under the above terms or under the terms of the GNU
44 * General Public License as published by the Free Software Foundation;
45 * either version 2 of the License, or (at your option) any later version.
46 *
47 * This program is distributed in the hope that it will be useful,
48 * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50 * GNU General Public License for more details.
51 *
52 * You should have received a copy of the GNU General Public License
53 * along with this program; if not, see http://www.gnu.org/licenses/
54 * or write to the Free Software Foundation, Inc., 51 Franklin Street,
55 * Fifth Floor, Boston, MA 02110-1301, USA.
56 *
57 */
58
59#ifndef GUCOORDINATESTESTS_HPP
60#define GUCOORDINATESTESTS_HPP
61
62#pragma clang diagnostic push
63#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
64#pragma clang diagnostic ignored "-Wfloat-equal"
65#pragma clang diagnostic ignored "-Wsign-compare"
66#pragma clang diagnostic ignored "-Wmissing-noreturn"
67#pragma clang diagnostic ignored "-Wshift-sign-overflow"
68#pragma clang diagnostic ignored "-Wused-but-marked-unused"
69#pragma clang diagnostic ignored "-Wundef"
70#pragma clang diagnostic ignored "-Wc++98-compat"
71#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
72#pragma clang diagnostic ignored "-Wc++11-long-long"
73#pragma clang diagnostic ignored "-Wc++11-extensions"
74#pragma clang diagnostic ignored "-Wdeprecated"
75#pragma clan diagnostic ignored "-Wsuggest-override"
76#pragma clan diagnostic ignored "-Wsuggest-destructor-override"
77#include <gtest/gtest.h>
78#pragma clang diagnostic pop
79
80#pragma clang diagnostic push
81#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
82#include "fff.h"
83#pragma clang diagnostic pop
84
85#include "../gucoordinates.h"
86#include "fakes.h"
87#include "custom_fakes.h"
88
89#include <typeinfo>
90
91#include <math.h>
92
93#define GU_NAO_V5_TOP_CAMERA gu_camera_make(6.364, 5.871, 1.2, 47.64, 60.97)
94#define GU_NAO_V5_BOTTOM_CAMERA gu_camera_make(1.774, 5.071, 39.7, 47.64, 60.97)
95
96#define GU_PEPPER_TOP_CAMERA gu_camera_make(115.3, 8.68, 0.0, 44.3, 55.2)
97#define GU_PEPPER_BOTTOM_CAMERA gu_camera_make(105.15, 9.36, 40.0, 44.3, 55.2)
98
99#define GU_NAO_V5_HEAD(p, y) (gu_camera_pivot) {.pitch = p, .yaw = y, .height = 41.7, .cameras = {GU_NAO_V5_TOP_CAMERA, GU_NAO_V5_BOTTOM_CAMERA}, .numCameras = 2}
100#define GU_NAO_V5_TOP_CAMERA_INDEX 0
101#define GU_NAO_V5_BOTTOM_CAMERA_INDEX 1
102
103#define GU_PEPPER_HEAD(p, y) {p, y, 0.0, {GU_PEPPER_TOP_CAMERA, GU_PEPPER_BOTTOM_CAMERA}, 2}
104
105#define GU_NAO_V5_ROBOT(hp, hy, x, y, t) (gu_robot) { .head = { hp, hy, 41.7, {GU_NAO_V5_TOP_CAMERA, GU_NAO_V5_BOTTOM_CAMERA}, 2 }, .position = { { x, y }, t } }
106
107#define GU_PEPPER_ROBOT(hp, hy, x, y, t) (gu_robot) { .head = { hp, hy, 0.0, {GU_PEPPER_TOP_CAMERA, GU_PEPPER_BOTTOM_CAMERA}, 2 }, .position = { { x, y }, t } }
108
109#pragma clang diagnostic push
110#pragma clang diagnostic ignored "-Wglobal-constructors"
111
112#define TEST2_F(testclassname, testname) \
113 TEST_F(testclassname, testname)
114
115#define RO3_TEST_F(className) \
116 TEST2_F(testclassname(className), RO3) { \
117 ro3_test(); \
118 }
119
120#if __cplusplus >= 201103L
121#define RO5_TEST_Fs(className) \
122 RO3_TEST_F(className) \
123 TEST2_F(testclassname(className), RO5) { \
124 ro5_test(); \
125 }
126#else
127#define RO5_TEST_Fs(className) RO3_TEST_F(className)
128#endif
129
130#define testclassname(className) className##CPPTests
131#define equals_reset(strctName) strctName##_equals_reset();
132#define equals_func(strctName) strctName##_equals
133#define equals_fake(strctName) strctName##_equals_fake
134
135#pragma clang diagnostic pop
136
137namespace CGTEST {
138
139 template <typename Class>
140 class GUCoordinatesTests: public ::testing::Test {
141 private:
142
143 protected:
144
148
149 virtual void SetUp() {
152 nao = GU_NAO_V5_HEAD(0.0, 0.0);
155 }
156
157 virtual void TearDown() {
160 }
161
162 virtual void preamble() {}
163
164 virtual Class initial() = 0;
165
166 virtual void change(Class &) {}
167
168 virtual Class empty() = 0;
169
170 void ro3_test() {
171 preamble();
172 Class obj = initial();
173#pragma clang diangostic push
174#pragma clang diagnostic ignored "-Wself-assign"
175 obj = obj;
176#pragma clang diagnostic pop
177 SCOPED_TRACE("Equality operator");
178 equals(obj, obj);
179 SCOPED_TRACE("Copy constructor");
180 Class obj2 = Class(obj);
181 equals(obj, obj2);
182 SCOPED_TRACE("Assignment operator");
183 Class obj3 = obj2;
184 equals(obj, obj3);
185 change(obj);
186 nequals(obj, obj3);
187 equals(obj2, obj3);
188 SCOPED_TRACE("Assignment operator2");
189 Class obj4;
190 obj4 = obj3;
191 equals(obj4, obj3);
192 Class * obj5 = &obj4;
193 equals(obj4, *obj5);
194 }
195
196#if __cplusplus >= 201103L
197 void ro5_test() {
198 Class obj = initial();
199 Class obj2 = initial();
200 SCOPED_TRACE("Move Constructor");
201 Class obj3 = std::move(obj);
202 obj = empty();
203 nequals(obj3, obj);
204 equals(obj3, obj2);
205 equals(obj, empty());
206 SCOPED_TRACE("Move assignment operator");
207 Class obj4;
208 obj4 = std::move(obj3);
209 obj3 = empty();
210 nequals(obj4, obj3);
211 equals(obj4, obj2);
212 equals(obj3, empty());
213 SCOPED_TRACE("Move assignment operator2");
214 Class * obj5 = &obj4;
215 obj4 = std::move(*obj5);
216 nequals(obj4, obj3);
217 equals(obj4, obj2);
218 nequals(*obj5, obj3);
219 equals(*obj5, obj2);
220 equals(*obj5, obj4);
221 }
222#endif
223
224 bool near(const double lhs, const double rhs) const
225 {
226 const double tolerance = 0.001;
227 return fabs(lhs - rhs) < tolerance;
228 }
229
230 void assert_near(const double lhs, const double rhs, const double tolerance) const
231 {
232 ASSERT_LE(fabs(lhs - rhs), tolerance);
233 }
234
236 {
237 ASSERT_EQ(lhs.x(), rhs.x());
238 ASSERT_EQ(lhs.y(), rhs.y());
239 ASSERT_EQ(lhs.resWidth(), rhs.resWidth());
240 ASSERT_EQ(lhs.resHeight(), rhs.resHeight());
241 }
242
244 {
245 ASSERT_FALSE(lhs.x() == rhs.x()
246 && lhs.y() == rhs.y()
247 && lhs.resWidth() == rhs.resWidth()
248 && lhs.resHeight() == rhs.resHeight()
249 );
250 }
251
252 void equals(const GU::Camera lhs, const GU::Camera rhs)
253 {
254 ASSERT_TRUE(near(lhs.height(), rhs.height()));
255 ASSERT_TRUE(near(lhs.centerOffset(), rhs.centerOffset()));
256 ASSERT_TRUE(near(lhs.vDirection(), rhs.vDirection()));
257 ASSERT_TRUE(near(lhs.vFov(), rhs.vFov()));
258 ASSERT_TRUE(near(lhs.hFov(), rhs.hFov()));
259 }
260
261 void nequals(const GU::Camera lhs, const GU::Camera rhs)
262 {
263 ASSERT_FALSE(
264 near(lhs.height(), rhs.height())
265 && near(lhs.centerOffset(), rhs.centerOffset())
266 && near(lhs.vDirection(), rhs.vDirection())
267 && near(lhs.vFov(), rhs.vFov())
268 && near(lhs.hFov(), rhs.hFov())
269 );
270 }
271
273 {
274 ASSERT_EQ(lhs.x(), rhs.x());
275 ASSERT_EQ(lhs.y(), rhs.y());
276 ASSERT_EQ(lhs.resWidth(), rhs.resWidth());
277 ASSERT_EQ(lhs.resHeight(), rhs.resHeight());
278 }
279
281 {
282 ASSERT_FALSE(
283 lhs.x() == rhs.x()
284 && lhs.y() == rhs.y()
285 && lhs.resWidth() == rhs.resWidth()
286 && lhs.resHeight() == rhs.resHeight()
287 );
288 }
289
291 {
292 ASSERT_TRUE(near(lhs.x(), rhs.x()));
293 ASSERT_TRUE(near(lhs.y(), rhs.y()));
294 }
295
297 {
298 ASSERT_FALSE(
299 near(lhs.x(), rhs.x())
300 && near(lhs.y(), rhs.y())
301 );
302 }
303
305 {
306 ASSERT_EQ(lhs.direction(), rhs.direction());
307 ASSERT_EQ(lhs.distance(), rhs.distance());
308 }
309
311 {
312 ASSERT_FALSE(
313 near(lhs.direction(), rhs.direction())
314 && lhs.distance() == rhs.distance()
315 );
316 }
317
319 {
320 ASSERT_EQ(lhs.x(), rhs.x());
321 ASSERT_EQ(lhs.y(), rhs.y());
322 }
323
325 {
326 ASSERT_FALSE(lhs.x() == rhs.x() && lhs.y() == rhs.y());
327 }
328
330 {
331 equals(lhs.position(), rhs.position());
332 ASSERT_EQ(lhs.heading(), rhs.heading());
333 }
334
336 {
337 ASSERT_FALSE(
338 lhs.position().x() == rhs.position().x()
339 && lhs.position().y() == rhs.position().y()
340 && lhs.heading() == rhs.heading()
341 );
342 }
343
344 void equals(const GU::CameraPivot lhs, const GU::CameraPivot rhs)
345 {
346 ASSERT_TRUE(near(lhs.pitch(), rhs.pitch())) << lhs.pitch() << ", " << rhs.pitch();
347 ASSERT_TRUE(near(lhs.yaw(), rhs.yaw()));
348 ASSERT_TRUE(near(lhs.height(), rhs.height()));
349 ASSERT_EQ(lhs.numCameras(), rhs.numCameras());
350 for (int i = 0; i < lhs.numCameras(); i++)
351 {
352 const GU::Camera lcamera = lhs.camera(i);
353 const GU::Camera rcamera = rhs.camera(i);
354 ASSERT_TRUE(near(lcamera.height(), rcamera.height()));
355 ASSERT_TRUE(near(lcamera.centerOffset(), rcamera.centerOffset()));
356 ASSERT_TRUE(near(lcamera.vDirection(), rcamera.vDirection()));
357 ASSERT_TRUE(near(lcamera.vFov(), rcamera.vFov()));
358 ASSERT_TRUE(near(lcamera.hFov(), rcamera.hFov()));
359 }
360 }
361
362 void nequals(const GU::CameraPivot lhs, const GU::CameraPivot rhs)
363 {
364 if (!(near(lhs.pitch(), rhs.pitch())
365 && near(lhs.yaw(), rhs.yaw())
366 && near(lhs.numCameras(), rhs.numCameras())
367 && near(lhs.height(), rhs.height())
368 ))
369 {
370 ASSERT_FALSE(near(lhs.pitch(), rhs.pitch())
371 && near(lhs.yaw(), rhs.yaw())
372 && near(lhs.numCameras(), rhs.numCameras())
373 && near(lhs.height(), rhs.height())
374 );
375 return;
376 }
377 for (int i = 0; i < lhs.numCameras(); i++)
378 {
379 const GU::Camera lcamera = lhs.camera(i);
380 const GU::Camera rcamera = rhs.camera(i);
381 ASSERT_FALSE(
382 near(lcamera.height(), rcamera.height())
383 && near(lcamera.centerOffset(),rcamera.centerOffset())
384 && near(lcamera.vDirection(), rcamera.vDirection())
385 && near(lcamera.vFov(), rcamera.vFov())
386 && near(lcamera.hFov(), rcamera.hFov())
387 );
388 }
389 }
390
392 {
393 ASSERT_EQ(lhs.has_value(), rhs.has_value());
394 equals(lhs.value(), rhs.value());
395 }
396
398 {
399 if (lhs.has_value() != rhs.has_value())
400 {
401 ASSERT_NE(lhs.has_value(), rhs.has_value());
402 return;
403 }
404 nequals(lhs.value(), rhs.value());
405 }
406
408 {
409 ASSERT_EQ(lhs.has_value(), rhs.has_value());
410 equals(lhs.value(), rhs.value());
411 }
412
414 {
415 if (lhs.has_value() != rhs.has_value())
416 {
417 ASSERT_NE(lhs.has_value(), rhs.has_value());
418 return;
419 }
420 nequals(lhs.value(), rhs.value());
421 }
422
424 {
425 ASSERT_EQ(lhs.has_value(), rhs.has_value());
426 equals(lhs.value(), rhs.value());
427 }
428
430 {
431 if (lhs.has_value() != rhs.has_value())
432 {
433 ASSERT_NE(lhs.has_value(), rhs.has_value());
434 return;
435 }
436 nequals(lhs.value(), rhs.value());
437 }
438
440 {
441 ASSERT_EQ(lhs.has_value(), rhs.has_value());
442 equals(lhs.value(), rhs.value());
443 }
444
446 {
447 if (lhs.has_value() != rhs.has_value())
448 {
449 ASSERT_NE(lhs.has_value(), rhs.has_value());
450 return;
451 }
452 nequals(lhs.value(), rhs.value());
453 }
454
456 {
457 ASSERT_EQ(lhs.has_value(), rhs.has_value());
458 equals(lhs.value(), rhs.value());
459 }
460
462 {
463 if (lhs.has_value() != rhs.has_value())
464 {
465 ASSERT_NE(lhs.has_value(), rhs.has_value());
466 return;
467 }
468 nequals(lhs.value(), rhs.value());
469 }
470
472 {
473 ASSERT_EQ(lhs.has_value(), rhs.has_value());
474 equals(lhs.value(), rhs.value());
475 }
476
478 {
479 if (lhs.has_value() != rhs.has_value())
480 {
481 ASSERT_NE(lhs.has_value(), rhs.has_value());
482 return;
483 }
484 nequals(lhs.value(), rhs.value());
485 }
486
487 };
488
489}
490
491#endif /* GUCOORDINATESTESTS_HPP */
#define GU_NAO_V5_BOTTOM_CAMERA
#define GU_NAO_V5_TOP_CAMERA
#define GU_NAO_V5_HEAD(p, y)
void equals(const GU::PercentCoordinate lhs, const GU::PercentCoordinate rhs)
void nequals(const GU::FieldCoordinate lhs, const GU::FieldCoordinate rhs)
void equals(const GU::OptionalCameraCoordinate lhs, const GU::OptionalCameraCoordinate rhs)
void nequals(const GU::OptionalFieldCoordinate lhs, const GU::OptionalFieldCoordinate rhs)
void equals(const GU::Camera lhs, const GU::Camera rhs)
void equals(const GU::RelativeCoordinate lhs, const GU::RelativeCoordinate rhs)
void nequals(const GU::RelativeCoordinate lhs, const GU::RelativeCoordinate rhs)
virtual Class initial()=0
void nequals(const GU::OptionalRelativeCoordinate lhs, const GU::OptionalRelativeCoordinate rhs)
void nequals(const GU::OptionalCartesianCoordinate lhs, const GU::OptionalCartesianCoordinate rhs)
void nequals(const GU::OptionalPercentCoordinate lhs, const GU::OptionalPercentCoordinate rhs)
void nequals(const GU::CameraPivot lhs, const GU::CameraPivot rhs)
void nequals(const GU::PercentCoordinate lhs, const GU::PercentCoordinate rhs)
void equals(const GU::OptionalPixelCoordinate lhs, const GU::OptionalPixelCoordinate rhs)
void equals(const GU::OptionalPercentCoordinate lhs, const GU::OptionalPercentCoordinate rhs)
void nequals(const GU::CartesianCoordinate lhs, const GU::CartesianCoordinate rhs)
void equals(const GU::OptionalRelativeCoordinate lhs, const GU::OptionalRelativeCoordinate rhs)
bool near(const double lhs, const double rhs) const
void nequals(const GU::OptionalCameraCoordinate lhs, const GU::OptionalCameraCoordinate rhs)
virtual Class empty()=0
void equals(const GU::PixelCoordinate lhs, const GU::PixelCoordinate rhs)
void nequals(const GU::Camera lhs, const GU::Camera rhs)
void equals(const GU::CartesianCoordinate lhs, const GU::CartesianCoordinate rhs)
void assert_near(const double lhs, const double rhs, const double tolerance) const
void equals(const GU::CameraCoordinate lhs, const GU::CameraCoordinate rhs)
void equals(const GU::CameraPivot lhs, const GU::CameraPivot rhs)
void nequals(const GU::OptionalPixelCoordinate lhs, const GU::OptionalPixelCoordinate rhs)
virtual void change(Class &)
void nequals(const GU::PixelCoordinate lhs, const GU::PixelCoordinate rhs)
void equals(const GU::OptionalFieldCoordinate lhs, const GU::OptionalFieldCoordinate rhs)
void equals(const GU::OptionalCartesianCoordinate lhs, const GU::OptionalCartesianCoordinate rhs)
void equals(const GU::FieldCoordinate lhs, const GU::FieldCoordinate rhs)
void nequals(const GU::CameraCoordinate lhs, const GU::CameraCoordinate rhs)
#define ALL_FAKES(FAKE)
Definition: fakes.h:77
#define FFF_RESET_HISTORY()
Definition: fff.h:139
#define RESET_FAKE(FUNCNAME)
Definition: fff.h:51
pixels_u y() const NOEXCEPT
pixels_u resWidth() const NOEXCEPT
pixels_u resHeight() const NOEXCEPT
pixels_u x() const NOEXCEPT
degrees_d vDirection() const NOEXCEPT
Definition: CameraCPP.cc:188
centimetres_d height() const NOEXCEPT
Definition: CameraCPP.cc:168
centimetres_d centerOffset() const NOEXCEPT
Definition: CameraCPP.cc:178
degrees_d hFov() const NOEXCEPT
Definition: CameraCPP.cc:208
degrees_d vFov() const NOEXCEPT
Definition: CameraCPP.cc:198
int numCameras() const NOEXCEPT
Definition: CameraPivot.cc:222
degrees_d yaw() const NOEXCEPT
Definition: CameraPivot.cc:181
degrees_d pitch() const NOEXCEPT
Definition: CameraPivot.cc:171
Camera camera(const int) const NOEXCEPT
Definition: CameraPivot.cc:212
centimetres_d height() const NOEXCEPT
Definition: CameraPivot.cc:192
centimetres_t x() const NOEXCEPT
centimetres_t y() const NOEXCEPT
degrees_t heading() const NOEXCEPT
CartesianCoordinate position() const NOEXCEPT
bool has_value() const NOEXCEPT
Wrapped value() const NOEXCEPT
percent_d y() const NOEXCEPT
percent_d x() const NOEXCEPT
pixels_t y() const NOEXCEPT
pixels_t x() const NOEXCEPT
pixels_u resWidth() const NOEXCEPT
pixels_u resHeight() const NOEXCEPT
millimetres_u distance() const NOEXCEPT
degrees_d direction() const NOEXCEPT