diff --git a/msgs/CMakeLists.txt b/msgs/CMakeLists.txt
index cdfd1e8..3d01d55 100644
--- a/msgs/CMakeLists.txt
+++ b/msgs/CMakeLists.txt
@@ -48,6 +48,8 @@ set(SIMPLE_MSGS_SRCS
src/pose_stamped.cpp
src/rotation_matrix.cpp
src/rotation_matrix_stamped.cpp
+ src/transform.cpp
+ src/transform_stamped.cpp
)
# Generate the Flatbuffers headers.
diff --git a/msgs/fbs/transform.fbs b/msgs/fbs/transform.fbs
new file mode 100644
index 0000000..a121947
--- /dev/null
+++ b/msgs/fbs/transform.fbs
@@ -0,0 +1,11 @@
+// Schema for S.I.M.P.L.E. Homogeneous Transformation
+
+namespace simple_msgs;
+
+table TransformFbs {
+ point:[ubyte];
+ matrix:[ubyte];
+}
+
+root_type TransformFbs;
+file_identifier "TRAN";
\ No newline at end of file
diff --git a/msgs/fbs/transform_stamped.fbs b/msgs/fbs/transform_stamped.fbs
new file mode 100644
index 0000000..4aa966e
--- /dev/null
+++ b/msgs/fbs/transform_stamped.fbs
@@ -0,0 +1,11 @@
+// Schema for S.I.M.P.L.E. Stamped Homogeneous Transformation
+
+namespace simple_msgs;
+
+table TransformStampedFbs {
+ transform:[ubyte];
+ header:[ubyte];
+}
+
+root_type TransformStampedFbs;
+file_identifier "TRST";
diff --git a/msgs/include/simple_msgs/all_messages.h b/msgs/include/simple_msgs/all_messages.h
index e95b2cc..0371f95 100644
--- a/msgs/include/simple_msgs/all_messages.h
+++ b/msgs/include/simple_msgs/all_messages.h
@@ -28,5 +28,7 @@
#include "rotation_matrix.h"
#include "rotation_matrix_stamped.h"
#include "string.h"
+#include "transform.h"
+#include "transform_stamped.h"
#endif // SIMPLE_MSGS_ALL_H
diff --git a/msgs/include/simple_msgs/rotation_matrix.h b/msgs/include/simple_msgs/rotation_matrix.h
index 871f131..96c6da7 100644
--- a/msgs/include/simple_msgs/rotation_matrix.h
+++ b/msgs/include/simple_msgs/rotation_matrix.h
@@ -21,8 +21,8 @@
namespace simple_msgs {
/**
* @class RotationMatrix rotation_matrix.h.
- * @brief Thread-safe wrapper for a Flatbuffers RotationMatrix message.
- * It represents a 3x3 rotation matrix.
+ * @brief A thread-safe wrapper for a Flatbuffers RotationMatrix message.
+ * It represents a 3x3 rotation matrix stored in row-major order.
*/
class RotationMatrix : public GenericMessage {
public:
diff --git a/msgs/include/simple_msgs/transform.h b/msgs/include/simple_msgs/transform.h
new file mode 100644
index 0000000..0a9d6a4
--- /dev/null
+++ b/msgs/include/simple_msgs/transform.h
@@ -0,0 +1,164 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SIMPLE_MSGS_TRANSFORM_H
+#define SIMPLE_MSGS_TRANSFORM_H
+
+#include
+#include
+
+#include "generated/transform_generated.h"
+#include "point.h"
+#include "rotation_matrix.h"
+
+namespace simple_msgs {
+/**
+ * @class Transform transform.h.
+ * @brief Wrapper for a Flatbuffers Transform message.
+ * It represents a 4x4 homogeneous transformation, stored in row-major order.
+ */
+class Transform : public GenericMessage {
+public:
+ Transform() = default;
+
+ /**
+ * @brief Construct a Transform message give its translation and its rotation part.
+ */
+ Transform(const Point&, const RotationMatrix&);
+
+ /**
+ * @brief Construct a Transform message give its translation and its rotation part.
+ */
+ Transform(Point&&, RotationMatrix&&);
+
+ /**
+ * @brief Construct a Transform message give a vector of 16 elements.
+ * The vector is expected to be in row-major order.
+ */
+ Transform(const std::array&);
+
+ /**
+ * @brief Construct a Transform message give a vector of 16 elements.
+ * The vector is expected to be in row-major order.
+ */
+ Transform(std::array&&) noexcept;
+
+ /**
+ * @brief Construct a Transform message using a raw memory coming from network.
+ */
+ Transform(const void*);
+
+ /**
+ * @brief Copy constructor.
+ */
+ Transform(const Transform&);
+
+ /**
+ * @brief Move constructor.
+ */
+ Transform(Transform&&) noexcept;
+
+ /**
+ * @brief Copy assignment operator.
+ */
+ Transform& operator=(const Transform&);
+
+ /**
+ * @brief Move assignment operator.
+ */
+ Transform& operator=(Transform&&) noexcept;
+
+ /**
+ * @brief Copy assignment operator that uses raw memory coming from the network.
+ */
+ Transform& operator=(std::shared_ptr);
+
+ /**
+ * @brief Returns true if lhs is equal to rhs, false otherwise.
+ */
+ inline bool operator==(const Transform& rhs) const {
+ std::lock_guard lock{mutex_};
+ return (point_ == rhs.point_ && matrix_ == rhs.matrix_);
+ }
+
+ /**
+ * @brief Returns true if lhs is not equal to rhs, false otherwise.
+ */
+ inline bool operator!=(const Transform& rhs) const { return !(*this == rhs); }
+
+ /**
+ * @brief Stream extraction operator.
+ */
+ friend std::ostream& operator<<(std::ostream&, const Transform&);
+
+ /**
+ * @brief Builds and returns the buffer accordingly to the values currently stored.
+ */
+ std::shared_ptr getBufferData() const override;
+
+ /**
+ * @brief Returns the rotational part of the homogeneous transformation.
+ */
+ inline RotationMatrix& getRotation() {
+ std::lock_guard lock{mutex_};
+ return matrix_;
+ }
+
+ /**
+ * @brief Returns the rotational part of the homogeneous transformation.
+ */
+ inline const RotationMatrix& getRotation() const {
+ std::lock_guard lock{mutex_};
+ return matrix_;
+ }
+
+ /**
+ * @brief Returns the translational part of the homogeneous transformation.
+ */
+ inline Point& getTranslation() {
+ std::lock_guard lock{mutex_};
+ return point_;
+ }
+
+ /**
+ * @brief Returns the translational part of the homogeneous transformation.
+ */
+ inline const Point& getTranslation() const {
+ std::lock_guard lock{mutex_};
+ return point_;
+ }
+
+ /**
+ * @brief Modifies the translational part of the Pose.
+ */
+ void setTranslation(const Point&);
+
+ /**
+ * @brief Modifies the rotational part of the Pose.
+ */
+ void setRotation(const RotationMatrix&);
+
+ /**
+ * @brief Returns an identifier of the message type generated by the flatbuffers.
+ */
+ static inline std::string getTopic() { return TransformFbsIdentifier(); }
+
+private:
+ //! Thread safe copy and move constructors.
+ Transform(const Transform& other, const std::lock_guard&);
+ Transform(Transform&& other, const std::lock_guard&) noexcept;
+
+ mutable std::mutex mutex_{};
+ Point point_{}; //! The translational part of the homogeneous transformation.
+ RotationMatrix matrix_{}; //! The rotational part of the homogeneous transformation.
+};
+} // Namespace simple_msgs.
+
+#endif // SIMPLE_MSGS_TRANSFORM_H
diff --git a/msgs/include/simple_msgs/transform_stamped.h b/msgs/include/simple_msgs/transform_stamped.h
new file mode 100644
index 0000000..568ef9e
--- /dev/null
+++ b/msgs/include/simple_msgs/transform_stamped.h
@@ -0,0 +1,152 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SIMPLE_MSGS_TRANSFORM_STAMPED_H
+#define SIMPLE_MSGS_TRANSFORM_STAMPED_H
+
+#include
+#include
+
+#include "generated/transform_stamped_generated.h"
+#include "header.h"
+#include "transform.h"
+
+namespace simple_msgs {
+/**
+ * @class TransformStamped transform_stamped.h.
+ * @brief Thread-safe wrapper for a Flatbuffers TransformStamped message.
+ * It contains a Transform and a Header message.
+ */
+class TransformStamped : public GenericMessage {
+public:
+ TransformStamped() = default;
+
+ /**
+ * @brief Construct a TransformStamped message given its Header and Transform.
+ */
+ TransformStamped(const Header&, const Transform&);
+
+ /**
+ * @brief Construct a TransformStamped message given its Header and Transform.
+ */
+ TransformStamped(Header&&, Transform&&);
+
+ /**
+ * @brief Construct a TransformStamped message using a raw memory coming from network.
+ */
+ TransformStamped(const void*);
+
+ /**
+ * @brief Copy constructor.
+ */
+ TransformStamped(const TransformStamped&);
+
+ /**
+ * @brief Move constructor.
+ */
+ TransformStamped(TransformStamped&&) noexcept;
+
+ /**
+ * @brief Copy assignment operator.
+ */
+ TransformStamped& operator=(const TransformStamped&);
+
+ /**
+ * @brief Move assignment operator.
+ */
+ TransformStamped& operator=(TransformStamped&&) noexcept;
+
+ /**
+ * @brief Copy assignment operator that uses raw memory coming from the network.
+ */
+ TransformStamped& operator=(std::shared_ptr);
+
+ /**
+ * @brief Returns true if lhs is equal to rhs, false otherwise.
+ */
+ inline bool operator==(const TransformStamped& rhs) const {
+ std::lock_guard lock{mutex_};
+ return (transform_ == rhs.transform_ && header_ == rhs.header_);
+ }
+
+ /**
+ * @brief Returns true if lhs is not equal to rhs, false otherwise.
+ */
+ inline bool operator!=(const TransformStamped& rhs) const { return !(*this == rhs); }
+
+ /**
+ * @brief Stream extraction operator.
+ */
+ friend std::ostream& operator<<(std::ostream&, const TransformStamped&);
+
+ /**
+ * @brief Builds and returns the buffer accordingly to the values currently stored.
+ */
+ std::shared_ptr getBufferData() const override;
+
+ /**
+ * @brief Returns the message Header.
+ */
+ inline Header& getHeader() {
+ std::lock_guard lock{mutex_};
+ return header_;
+ }
+
+ /**
+ * @brief Returns the message Header.
+ */
+ inline const Header& getHeader() const {
+ std::lock_guard lock{mutex_};
+ return header_;
+ }
+
+ /**
+ * @brief Returns the message Transform.
+ */
+ inline Transform& getTransform() {
+ std::lock_guard lock{mutex_};
+ return transform_;
+ }
+
+ /**
+ * @brief Returns the message Transform.
+ */
+ inline const Transform& getTransform() const {
+ std::lock_guard lock{mutex_};
+ return transform_;
+ }
+
+ /**
+ * @brief Modifies the message header.
+ */
+ void setHeader(const Header&);
+
+ /**
+ * @brief Modifies the message Transform.
+ */
+ void setTransform(const Transform&);
+
+ /**
+ * @brief Returns an identifier of the message type generated by the flatbuffers.
+ */
+ static inline std::string getTopic() { return TransformStampedFbsIdentifier(); }
+
+private:
+ //! Thread safe copy and move constructors.
+ TransformStamped(const TransformStamped& other, const std::lock_guard&);
+ TransformStamped(TransformStamped&& other, const std::lock_guard&) noexcept;
+
+ mutable std::mutex mutex_{};
+ Header header_{};
+ Transform transform_{};
+};
+} // Namespace simple_msgs.
+
+#endif // SIMPLE_MSGS_TRANSFORM_STAMPED_H
diff --git a/msgs/src/point_stamped.cpp b/msgs/src/point_stamped.cpp
index 262824e..16bc6a5 100644
--- a/msgs/src/point_stamped.cpp
+++ b/msgs/src/point_stamped.cpp
@@ -77,14 +77,14 @@ std::shared_ptr PointStamped::getBufferData() const
return std::make_shared(builder.Release());
}
-void PointStamped::setHeader(const Header& h) {
+void PointStamped::setHeader(const Header& header) {
std::lock_guard lock{mutex_};
- header_ = h;
+ header_ = header;
}
-void PointStamped::setPoint(const Point& p) {
+void PointStamped::setPoint(const Point& point) {
std::lock_guard lock{mutex_};
- point_ = p;
+ point_ = point;
}
/**
diff --git a/msgs/src/pose_stamped.cpp b/msgs/src/pose_stamped.cpp
index 65f5633..9754d96 100644
--- a/msgs/src/pose_stamped.cpp
+++ b/msgs/src/pose_stamped.cpp
@@ -16,8 +16,7 @@ PoseStamped::PoseStamped(const Header& header, const Pose& pose) : header_{heade
PoseStamped::PoseStamped(Header&& header, Pose&& pose) : header_{std::move(header)}, pose_{std::move(pose)} {}
PoseStamped::PoseStamped(const void* data)
- : header_{GetPoseStampedFbs(data)->header()->data()} // namespace simple_msgs
- , pose_{GetPoseStampedFbs(data)->pose()->data()} {}
+ : header_{GetPoseStampedFbs(data)->header()->data()}, pose_{GetPoseStampedFbs(data)->pose()->data()} {}
PoseStamped::PoseStamped(const PoseStamped& other, const std::lock_guard&)
: PoseStamped{other.header_, other.pose_} {}
diff --git a/msgs/src/transform.cpp b/msgs/src/transform.cpp
new file mode 100644
index 0000000..ac94b16
--- /dev/null
+++ b/msgs/src/transform.cpp
@@ -0,0 +1,112 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "simple_msgs/transform.h"
+
+namespace simple_msgs {
+Transform::Transform(const Point& point, const RotationMatrix& matrix) : point_{point}, matrix_{matrix} {}
+
+Transform::Transform(Point&& point, RotationMatrix&& matrix) : point_{std::move(point)}, matrix_{std::move(matrix)} {}
+
+Transform::Transform(const std::array& data)
+ : point_{data[3], data[7], data[11]}
+ , matrix_{data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]} {}
+
+Transform::Transform(std::array&& data) noexcept
+ : point_{data[3], data[7], data[11]}
+ , matrix_{data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]} {}
+
+Transform::Transform(const void* data)
+ : point_{GetTransformFbs(data)->point()->data()}, matrix_{GetTransformFbs(data)->matrix()->data()} {}
+
+Transform::Transform(const Transform& other, const std::lock_guard&)
+ : Transform{other.point_, other.matrix_} {}
+
+Transform::Transform(Transform&& other, const std::lock_guard&) noexcept
+ : point_{std::move(other.point_)}, matrix_{std::move(other.matrix_)} {}
+
+Transform::Transform(const Transform& other) : Transform{other, std::lock_guard(other.mutex_)} {}
+
+Transform::Transform(Transform&& other) noexcept
+ : Transform{std::forward(other), std::lock_guard(other.mutex_)} {}
+
+Transform& Transform::operator=(const Transform& other) {
+ if (this != std::addressof(other)) {
+ std::lock(mutex_, other.mutex_);
+ std::lock_guard lock{mutex_, std::adopt_lock};
+ std::lock_guard other_lock{other.mutex_, std::adopt_lock};
+ point_ = other.point_;
+ matrix_ = other.matrix_;
+ }
+ return *this;
+}
+
+Transform& Transform::operator=(Transform&& other) noexcept {
+ if (this != std::addressof(other)) {
+ std::lock(mutex_, other.mutex_);
+ std::lock_guard lock{mutex_, std::adopt_lock};
+ std::lock_guard other_lock{other.mutex_, std::adopt_lock};
+ point_ = std::move(other.point_);
+ matrix_ = std::move(other.matrix_);
+ }
+ return *this;
+}
+
+Transform& Transform::operator=(std::shared_ptr data) {
+ std::lock_guard lock{mutex_};
+ auto p = GetTransformFbs(*data);
+ point_ = p->point()->data();
+ matrix_ = p->matrix()->data();
+ return *this;
+}
+
+std::shared_ptr Transform::getBufferData() const {
+ std::lock_guard lock{mutex_};
+ flatbuffers::FlatBufferBuilder builder{1024};
+
+ auto point_data = point_.getBufferData();
+ auto point_vector = builder.CreateVector(point_data->data(), point_data->size());
+
+ auto matrix_data = matrix_.getBufferData();
+ auto matrix_vector = builder.CreateVector(matrix_data->data(), matrix_data->size());
+
+ TransformFbsBuilder tmp_builder{builder};
+ tmp_builder.add_point(point_vector);
+ tmp_builder.add_matrix(matrix_vector);
+ FinishTransformFbsBuffer(builder, tmp_builder.Finish());
+ return std::make_shared(builder.Release());
+}
+
+void Transform::setRotation(const RotationMatrix& matrix) {
+ std::lock_guard lock{mutex_};
+ matrix_ = matrix;
+}
+
+void Transform::setTranslation(const Point& point) {
+ std::lock_guard lock{mutex_};
+ point_ = point;
+}
+
+/**
+ * @brief Stream extraction operator.
+ */
+std::ostream& operator<<(std::ostream& out, const Transform& t) {
+ std::lock_guard lock{t.mutex_};
+ auto vectorized_matrix = t.matrix_.toVector();
+ out << "Transform \n \t" << std::to_string(vectorized_matrix[0]) << " " << std::to_string(vectorized_matrix[1]) << " "
+ << std::to_string(vectorized_matrix[2]) << " " << std::to_string(t.point_.getX()) << "\n \t"
+ << std::to_string(vectorized_matrix[3]) << " " << std::to_string(vectorized_matrix[4]) << " "
+ << std::to_string(vectorized_matrix[5]) << " " << std::to_string(t.point_.getY()) << "\n \t"
+ << std::to_string(vectorized_matrix[6]) << " " << std::to_string(vectorized_matrix[7]) << " "
+ << std::to_string(vectorized_matrix[8]) << " " << std::to_string(t.point_.getZ()) << "\n"
+ << "0 0 0 1 \n";
+ return out;
+}
+} // namespace simple_msgs
diff --git a/msgs/src/transform_stamped.cpp b/msgs/src/transform_stamped.cpp
new file mode 100644
index 0000000..19bdbbc
--- /dev/null
+++ b/msgs/src/transform_stamped.cpp
@@ -0,0 +1,101 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "simple_msgs/transform_stamped.h"
+
+namespace simple_msgs {
+TransformStamped::TransformStamped(const Header& header, const Transform& matrix)
+ : header_{header}, transform_{matrix} {}
+
+TransformStamped::TransformStamped(Header&& header, Transform&& matrix)
+ : header_{std::move(header)}, transform_{std::move(matrix)} {}
+
+TransformStamped::TransformStamped(const void* data)
+ : header_{GetTransformStampedFbs(data)->header()->data()}
+ , transform_{GetTransformStampedFbs(data)->transform()->data()} {}
+
+TransformStamped::TransformStamped(const TransformStamped& other, const std::lock_guard&)
+ : TransformStamped{other.header_, other.transform_} {}
+
+TransformStamped::TransformStamped(TransformStamped&& other, const std::lock_guard&) noexcept
+ : TransformStamped{std::move(other.header_), std::move(other.transform_)} {}
+
+TransformStamped::TransformStamped(const TransformStamped& other)
+ : TransformStamped{other, std::lock_guard(other.mutex_)} {}
+
+TransformStamped::TransformStamped(TransformStamped&& other) noexcept
+ : TransformStamped{std::forward(other), std::lock_guard(other.mutex_)} {}
+
+TransformStamped& TransformStamped::operator=(const TransformStamped& other) {
+ if (this != std::addressof(other)) {
+ std::lock(mutex_, other.mutex_);
+ std::lock_guard lock{mutex_, std::adopt_lock};
+ std::lock_guard other_lock{other.mutex_, std::adopt_lock};
+ header_ = other.header_;
+ transform_ = other.transform_;
+ }
+ return *this;
+}
+
+TransformStamped& TransformStamped::operator=(TransformStamped&& other) noexcept {
+ if (this != std::addressof(other)) {
+ std::lock(mutex_, other.mutex_);
+ std::lock_guard lock{mutex_, std::adopt_lock};
+ std::lock_guard other_lock{other.mutex_, std::adopt_lock};
+ header_ = std::move(other.header_);
+ transform_ = std::move(other.transform_);
+ }
+ return *this;
+}
+
+TransformStamped& TransformStamped::operator=(std::shared_ptr data) {
+ std::lock_guard lock{mutex_};
+ auto p = GetTransformStampedFbs(*data);
+ header_ = p->header()->data();
+ transform_ = p->transform()->data();
+ return *this;
+}
+
+std::shared_ptr TransformStamped::getBufferData() const {
+ std::lock_guard lock{mutex_};
+ flatbuffers::FlatBufferBuilder builder{1024};
+
+ auto header_data = header_.getBufferData();
+ auto header_vector = builder.CreateVector(header_data->data(), header_data->size());
+
+ auto transform_data = transform_.getBufferData();
+ auto transform_vector = builder.CreateVector(transform_data->data(), transform_data->size());
+
+ TransformStampedFbsBuilder tmp_builder{builder};
+ tmp_builder.add_header(header_vector);
+ tmp_builder.add_transform(transform_vector);
+ FinishTransformStampedFbsBuffer(builder, tmp_builder.Finish());
+ return std::make_shared(builder.Release());
+}
+
+void TransformStamped::setHeader(const Header& header) {
+ std::lock_guard lock{mutex_};
+ header_ = header;
+}
+
+void TransformStamped::setTransform(const Transform& transform) {
+ std::lock_guard lock{mutex_};
+ transform_ = transform;
+}
+
+/**
+ * @brief Stream extraction operator.
+ */
+std::ostream& operator<<(std::ostream& out, const TransformStamped& t) {
+ std::lock_guard lock{t.mutex_};
+ out << t.header_ << t.transform_;
+ return out;
+}
+} // namespace simple_msgs
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 57643ee..1295d5c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -40,6 +40,10 @@ add_executable(test_rotation_matrix test_rotation_matrix.cpp)
target_link_libraries(test_rotation_matrix simple-static ${coverage_lib})
add_test(NAME simple_tests.rotation_matrix COMMAND $)
+add_executable(test_transform test_transform.cpp)
+target_link_libraries(test_transform simple-static ${coverage_lib})
+add_test(NAME simple_tests.transform COMMAND $)
+
add_executable(test_pose test_pose.cpp)
target_link_libraries(test_pose simple-static ${coverage_lib})
add_test(NAME simple_tests.pose COMMAND $)
@@ -72,6 +76,10 @@ add_executable(test_rotation_matrix_stamped test_rotation_matrix_stamped.cpp)
target_link_libraries(test_rotation_matrix_stamped simple-static ${coverage_lib})
add_test(NAME simple_tests.rotation_matrix_stamped COMMAND $)
+add_executable(test_transform_stamped test_transform_stamped.cpp)
+target_link_libraries(test_transform_stamped simple-static ${coverage_lib})
+add_test(NAME simple_tests.transform_stamped COMMAND $)
+
# PUBLISHER / SUBSCRIBER TESTS
add_executable(test_publisher test_publisher.cpp)
target_link_libraries(test_publisher simple-static ${coverage_lib})
@@ -94,7 +102,7 @@ add_test(NAME simple_tests.pub_sub COMMAND $)
#target_link_libraries(test_server simple-static ${coverage_lib})
#add_test(NAME simple_tests.server COMMAND $)
-add_executable(test_req_rep test_single_req_rep.cpp)
+add_executable(test_req_rep test_req_rep.cpp)
target_link_libraries(test_req_rep simple-static ${coverage_lib})
add_test(NAME simple_tests.req_rep COMMAND $)
diff --git a/tests/include/random_generators.hpp b/tests/include/random_generators.hpp
new file mode 100644
index 0000000..91ead24
--- /dev/null
+++ b/tests/include/random_generators.hpp
@@ -0,0 +1,27 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SIMPLE_TESTS_RANDOM_GENERATORS_HPP
+#define SIMPLE_TESTS_RANDOM_GENERATORS_HPP
+
+#include
+#include
+
+namespace simple_tests {
+
+static std::random_device rd;
+static std::minstd_rand generator(rd());
+static std::uniform_int_distribution int_dist(1, 1000);
+static std::uniform_real_distribution double_dist(1, std::nextafter(1000, DBL_MAX));
+static std::bernoulli_distribution bool_dist;
+
+} // Namespace simple_tests.
+
+#endif // SIMPLE_TESTS_RANDOM_GENERATORS_HPP.
diff --git a/tests/include/test_utilities.hpp b/tests/include/test_utilities.hpp
new file mode 100644
index 0000000..d090e7e
--- /dev/null
+++ b/tests/include/test_utilities.hpp
@@ -0,0 +1,357 @@
+/**
+ * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
+ * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
+ * Langsch - fernanda.langsch@tum.de
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SIMPLE_TESTS_UTILITIES_HPP
+#define SIMPLE_TESTS_UTILITIES_HPP
+
+#include
+
+#include "random_generators.hpp"
+#include "simple_msgs/all_messages.h"
+
+namespace simple_tests {
+
+//! The total number of messages defined in the simple_msgs namespace.
+static constexpr size_t TOTAL_NUM_MESSAGES = 16;
+
+//! Minimum port number to use for the random generation.
+static constexpr size_t MIN_PORT_NUMBER = 5555;
+
+//! Maximum port number to use for the random generation.
+static constexpr size_t MAX_PORT_NUMBER = 5700;
+
+//! Random port generation.
+//! The following objects are used to ranomly assign a port number to pub/sub and client/server tests scenarios.
+//! We also keep track of the used ports, so that a non used one is assigned to new test cases. This is to avoid that
+//! ZMQ complains about a port being already taken.
+
+//! A random generator of port numbers, this is used to randomly assign a port during pub/sub or client/server tests and
+//! avoid that the same number was already assigned to another test scenario within the same test.
+static std::uniform_int_distribution port_dist(MIN_PORT_NUMBER, MAX_PORT_NUMBER);
+
+//! Keeps track of which port number was already used in a test executable.
+static std::vector port_pool{};
+
+//! To avoid that multiple test scenario race to generate/check ports.
+static std::mutex port_mutex{};
+
+/**
+ * @brief Generate a random port number to use and check if it wasn't used yet. If so it adds the new generated number
+ * to the pool of used ports and gives it back to the user.
+ */
+size_t generatePort() {
+ std::lock_guard lock(port_mutex);
+ bool success{false};
+ while (!success) {
+ size_t port = port_dist(generator);
+ if (std::find(port_pool.begin(), port_pool.end(), port) == port_pool.end()) {
+ port_pool.push_back(port);
+ success = true;
+ return port;
+ }
+ }
+ return 0;
+}
+
+//! END - Random port generation.
+
+//! Following are convininet objects for the pub/sub and client/server tests.
+//! Since those tests are performed for each message type, we need the same structures for each message.
+//! We keep them in the arrays down here and track which message type uses which elements of the array with the enum.
+
+static std::array active_callback{};
+static std::array received_messages{};
+
+enum MessageType {
+ Bool = 0,
+ Int = 1,
+ Double = 2,
+ Float = 3,
+ String = 4,
+ Header = 5,
+ Point = 6,
+ Quaternion = 7,
+ Pose = 8,
+ RotationMatrix = 9,
+ Transform = 10,
+ PointStamped = 11,
+ QuaternionStamped = 12,
+ PoseStamped = 13,
+ RotationMatrixStamped = 14,
+ TransformStamped = 15
+};
+
+//! Variables to use in callback functions to receive messages.
+static simple_msgs::Bool received_bool{};
+static simple_msgs::Int received_int{};
+static simple_msgs::Double received_double{};
+static simple_msgs::Float received_float{};
+static simple_msgs::String received_string{};
+static simple_msgs::Header received_header{};
+static simple_msgs::Point received_point{};
+static simple_msgs::Quaternion received_quaternion{};
+static simple_msgs::Pose received_pose{};
+static simple_msgs::RotationMatrix received_rotation_matrix{};
+static simple_msgs::Transform received_transform{};
+static simple_msgs::PointStamped received_point_stamped{};
+static simple_msgs::QuaternionStamped received_quaternion_stamped{};
+static simple_msgs::PoseStamped received_pose_stamped{};
+static simple_msgs::RotationMatrixStamped received_rotation_matrix_stamped{};
+static simple_msgs::TransformStamped received_transform_stamped{};
+
+//! Functions to randomly generate simple_msgs.
+
+simple_msgs::Bool createRandomBool() { return simple_msgs::Bool(bool_dist(generator)); }
+
+simple_msgs::Int createRandomInt() { return simple_msgs::Int(int_dist(generator)); }
+
+simple_msgs::Double createRandomDouble() { return simple_msgs::Double(double_dist(generator)); }
+
+simple_msgs::Float createRandomFloat() { return simple_msgs::Float(static_cast(double_dist(generator))); }
+
+simple_msgs::String createRandomString() {
+ return simple_msgs::String("Random string: " + std::to_string(int_dist(generator)));
+}
+
+simple_msgs::Header createRandomHeader() {
+ int x = int_dist(generator);
+ std::string y("Header string:");
+ y.append(std::to_string(int_dist(generator) % 100));
+ long long z = static_cast(double_dist(generator));
+ return simple_msgs::Header(x, y, z);
+}
+
+simple_msgs::Point createRandomPoint() {
+ return simple_msgs::Point(double_dist(generator), double_dist(generator), double_dist(generator));
+}
+
+simple_msgs::Quaternion createRandomQuaternion() {
+ return simple_msgs::Quaternion(double_dist(generator), double_dist(generator), double_dist(generator),
+ double_dist(generator));
+}
+
+simple_msgs::Pose createRandomPose() { return simple_msgs::Pose(createRandomPoint(), createRandomQuaternion()); }
+
+simple_msgs::RotationMatrix createRandomRotationMatrix() {
+ return simple_msgs::RotationMatrix(double_dist(generator), double_dist(generator), double_dist(generator),
+ double_dist(generator), double_dist(generator), double_dist(generator),
+ double_dist(generator), double_dist(generator), double_dist(generator));
+}
+
+simple_msgs::Transform createRandomTransform() {
+ return simple_msgs::Transform(createRandomPoint(), createRandomRotationMatrix());
+}
+
+simple_msgs::PointStamped createRandomPointStamped() {
+ return simple_msgs::PointStamped(createRandomHeader(), createRandomPoint());
+}
+
+simple_msgs::PoseStamped createRandomPoseStamped() {
+ return simple_msgs::PoseStamped(createRandomHeader(), createRandomPose());
+}
+
+simple_msgs::QuaternionStamped createRandomQuaternionStamped() {
+ return simple_msgs::QuaternionStamped(createRandomHeader(), createRandomQuaternion());
+}
+
+simple_msgs::RotationMatrixStamped createRandomRotationMatrixStamped() {
+ return simple_msgs::RotationMatrixStamped(createRandomHeader(), createRandomRotationMatrix());
+}
+
+simple_msgs::TransformStamped createRandomTransformStamped() {
+ return simple_msgs::TransformStamped(createRandomHeader(), createRandomTransform());
+}
+
+//! Set of callback functions for all the simple_msgs.
+//! They modify the received point. They are used for client/server tests.
+
+void callbackFunctionBool(simple_msgs::Bool& b) {
+ b = !b; //! Invert the value of the Bool message.
+}
+
+void callbackFunctionInt(simple_msgs::Int& i) {
+ i.set(i.get() + 1); //! Add 1.
+}
+
+void callbackFunctionDouble(simple_msgs::Double& d) {
+ d.set(d.get() + 1); //! Add 1.
+}
+
+void callbackFunctionFloat(simple_msgs::Float& f) {
+ f.set(f.get() + 1); //! Add 1.
+}
+
+void callbackFunctionString(simple_msgs::String& s) {
+ s.set("REPLY"); //! Replace the string by a standard reply.
+}
+
+void callbackFunctionHeader(simple_msgs::Header& h) {
+ h.setFrameID("ID");
+ h.setSequenceNumber(1);
+ h.setTimestamp(10);
+}
+
+void callbackFunctionPoint(simple_msgs::Point& p) { ++p; }
+
+void callbackFunctionQuaternion(simple_msgs::Quaternion& q) {
+ q.setW(q.getW() + 1);
+ q.setX(q.getX() + 1);
+ q.setY(q.getY() + 1);
+ q.setZ(q.getZ() + 1);
+}
+
+void callbackFunctionPose(simple_msgs::Pose& p) {
+ p.getPosition() += 1.0;
+ p.getQuaternion().setW(p.getQuaternion().getW() + 1);
+ p.getQuaternion().setX(p.getQuaternion().getX() + 1);
+ p.getQuaternion().setY(p.getQuaternion().getY() + 1);
+ p.getQuaternion().setZ(p.getQuaternion().getZ() + 1);
+}
+
+void callbackFunctionRotationMatrix(simple_msgs::RotationMatrix& r) {
+ r.setColumn(0, {{0, 0, 0}});
+ r.setColumn(1, {{0, 0, 0}});
+ r.setColumn(2, {{0, 0, 0}});
+}
+
+void callbackFunctionTransform(simple_msgs::Transform& t) {
+ t.setTranslation({1, 1, 1});
+ t.setRotation({1, 1, 1, 1, 1, 1, 1, 1, 1});
+}
+
+void callbackFunctionPointStamped(simple_msgs::PointStamped& p) {
+ callbackFunctionPoint(p.getPoint());
+ callbackFunctionHeader(p.getHeader());
+}
+
+void callbackFunctionQuaternionStamped(simple_msgs::QuaternionStamped& q) {
+ callbackFunctionQuaternion(q.getQuaternion());
+ callbackFunctionHeader(q.getHeader());
+}
+
+void callbackFunctionPoseStamped(simple_msgs::PoseStamped& p) {
+ callbackFunctionPose(p.getPose());
+ callbackFunctionHeader(p.getHeader());
+}
+
+void callbackFunctionRotationMatrixStamped(simple_msgs::RotationMatrixStamped& r) {
+ callbackFunctionRotationMatrix(r.getRotationMatrix());
+ callbackFunctionHeader(r.getHeader());
+}
+
+void callbackFunctionTransformStamped(simple_msgs::TransformStamped& t) {
+ callbackFunctionTransform(t.getTransform());
+ callbackFunctionHeader(t.getHeader());
+}
+
+//! Set of const callbacks for all the simple_msgs
+//! They receive a message and just save it. They are used for pub/sub tests.
+
+void callbackFunctionConstBool(const simple_msgs::Bool& b) {
+ received_bool = b;
+ received_messages[MessageType::Bool]++;
+ if (!active_callback[MessageType::Bool]) { active_callback[MessageType::Bool] = true; }
+}
+
+void callbackFunctionConstInt(const simple_msgs::Int& i) {
+ received_int = i;
+ received_messages[MessageType::Int]++;
+ if (!active_callback[MessageType::Int]) { active_callback[MessageType::Int] = true; }
+}
+
+void callbackFunctionConstFloat(const simple_msgs::Float& f) {
+ received_float = f;
+ received_messages[MessageType::Float]++;
+ if (!active_callback[MessageType::Float]) { active_callback[MessageType::Float] = true; }
+}
+
+void callbackFunctionConstDouble(const simple_msgs::Double& d) {
+ received_double = d;
+ received_messages[MessageType::Double]++;
+ if (!active_callback[MessageType::Double]) { active_callback[MessageType::Double] = true; }
+}
+
+void callbackFunctionConstString(const simple_msgs::String& s) {
+ received_string = s;
+ received_messages[MessageType::String]++;
+ if (!active_callback[MessageType::String]) { active_callback[MessageType::String] = true; }
+}
+
+void callbackFunctionConstHeader(const simple_msgs::Header& h) {
+ received_header = h;
+ received_messages[MessageType::Header]++;
+ if (!active_callback[MessageType::Header]) { active_callback[MessageType::Header] = true; }
+}
+
+void callbackFunctionConstPoint(const simple_msgs::Point& p) {
+ received_point = p;
+ received_messages[MessageType::Point]++;
+ if (!active_callback[MessageType::Point]) { active_callback[MessageType::Point] = true; }
+}
+
+void callbackFunctionConstQuaternion(const simple_msgs::Quaternion& q) {
+ received_quaternion = q;
+ received_messages[MessageType::Quaternion]++;
+ if (!active_callback[MessageType::Quaternion]) { active_callback[MessageType::Quaternion] = true; }
+}
+
+void callbackFunctionConstPose(const simple_msgs::Pose& p) {
+ received_pose = p;
+ received_messages[MessageType::Pose]++;
+ if (!active_callback[MessageType::Pose]) { active_callback[MessageType::Pose] = true; }
+}
+
+void callbackFunctionConstRotationMatrix(const simple_msgs::RotationMatrix& r) {
+ received_rotation_matrix = r;
+ received_messages[MessageType::RotationMatrix]++;
+ if (!active_callback[MessageType::RotationMatrix]) { active_callback[MessageType::RotationMatrix] = true; }
+}
+
+void callbackFunctionConstTransform(const simple_msgs::Transform& t) {
+ received_transform = t;
+ received_messages[MessageType::Transform]++;
+ if (!active_callback[MessageType::Transform]) { active_callback[MessageType::Transform] = true; }
+}
+
+void callbackFunctionConstPointStamped(const simple_msgs::PointStamped& ps) {
+ received_point_stamped = ps;
+ received_messages[MessageType::PointStamped]++;
+ if (!active_callback[MessageType::PointStamped]) { active_callback[MessageType::PointStamped] = true; }
+}
+
+void callbackFunctionConstQuaternionStamped(const simple_msgs::QuaternionStamped& qs) {
+ received_quaternion_stamped = qs;
+ received_messages[MessageType::QuaternionStamped]++;
+ if (!active_callback[MessageType::QuaternionStamped]) { active_callback[MessageType::QuaternionStamped] = true; }
+}
+
+void callbackFunctionConstPoseStamped(const simple_msgs::PoseStamped& ps) {
+ received_pose_stamped = ps;
+ received_messages[MessageType::PoseStamped]++;
+ if (!active_callback[MessageType::PoseStamped]) { active_callback[MessageType::PoseStamped] = true; }
+}
+
+void callbackFunctionConstRotationMatrixStamped(const simple_msgs::RotationMatrixStamped& rs) {
+ received_rotation_matrix_stamped = rs;
+ received_messages[MessageType::RotationMatrixStamped]++;
+ if (!active_callback[MessageType::RotationMatrixStamped]) {
+ active_callback[MessageType::RotationMatrixStamped] = true;
+ }
+}
+
+void callbackFunctionConstTransformStamped(const simple_msgs::TransformStamped& ts) {
+ received_transform_stamped = ts;
+ received_messages[MessageType::TransformStamped]++;
+ if (!active_callback[MessageType::TransformStamped]) { active_callback[MessageType::TransformStamped] = true; }
+}
+
+} // Namespace simple_tests.
+
+#endif // SIMPLE_TESTS_UTILITIES_HPP.
diff --git a/tests/include/test_utils.hpp b/tests/include/test_utils.hpp
deleted file mode 100644
index 771038b..0000000
--- a/tests/include/test_utils.hpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort
- * Copyright (C) 2018 Salvatore Virga - salvo.virga@tum.de, Fernanda Levy
- * Langsch - fernanda.langsch@tum.de
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef TEST_UTILS_HPP
-#define TEST_UTILS_HPP
-
-#include
-#include
-
-#include "simple_msgs/all_messages.h"
-
-// Function for random message generation.
-simple_msgs::Header createRandomHeader() {
- int x = rand() % 100;
- std::string y("Header string:");
- y.append(std::to_string(rand() % 100));
- long long z = rand();
- return simple_msgs::Header(x, y, z);
-}
-
-simple_msgs::Point createRandomPoint() {
- double x = static_cast(rand()) / RAND_MAX;
- double y = static_cast(rand()) / RAND_MAX;
- double z = static_cast(rand()) / RAND_MAX;
- return simple_msgs::Point(x, y, z);
-}
-
-simple_msgs::Quaternion createRandomQuaternion() {
- double x = static_cast(rand()) / RAND_MAX;
- double y = static_cast(rand()) / RAND_MAX;
- double z = static_cast(rand()) / RAND_MAX;
- double w = static_cast(rand()) / RAND_MAX;
- return simple_msgs::Quaternion(x, y, z, w);
-}
-
-simple_msgs::RotationMatrix createRandomRotationMatrix() {
- double m_11 = static_cast(rand()) / RAND_MAX;
- double m_12 = static_cast(rand()) / RAND_MAX;
- double m_13 = static_cast(rand()) / RAND_MAX;
- double m_21 = static_cast(rand()) / RAND_MAX;
- double m_22 = static_cast(rand()) / RAND_MAX;
- double m_23 = static_cast(rand()) / RAND_MAX;
- double m_31 = static_cast(rand()) / RAND_MAX;
- double m_32 = static_cast(rand()) / RAND_MAX;
- double m_33 = static_cast(rand()) / RAND_MAX;
- return simple_msgs::RotationMatrix(m_11, m_12, m_13, m_21, m_22, m_23, m_31, m_32, m_33);
-}
-
-simple_msgs::Pose createRandomPose() { return simple_msgs::Pose(createRandomPoint(), createRandomQuaternion()); }
-
-simple_msgs::Int createRandomInt() {
- int x = rand() % 100;
- return simple_msgs::Int(x);
-}
-
-simple_msgs::Double createRandomDouble() {
- double x = static_cast(rand()) / RAND_MAX;
- return simple_msgs::Double(x);
-}
-
-simple_msgs::Float createRandomFloat() {
- float x = static_cast(rand()) / RAND_MAX;
- return simple_msgs::Float(x);
-}
-
-simple_msgs::Bool createRandomBool() {
- bool x((rand() % 1) != 0);
- return simple_msgs::Bool(x);
-}
-
-simple_msgs::String createRandomString() {
- std::string s("Random string: " + std::to_string(rand() % 100));
- return simple_msgs::String(s);
-}
-
-simple_msgs::PointStamped createRandomPointStamped() {
- return simple_msgs::PointStamped(createRandomHeader(), createRandomPoint());
-}
-
-simple_msgs::PoseStamped createRandomPoseStamped() {
- return simple_msgs::PoseStamped(createRandomHeader(), createRandomPose());
-}
-
-simple_msgs::QuaternionStamped createRandomQuaternionStamped() {
- return simple_msgs::QuaternionStamped(createRandomHeader(), createRandomQuaternion());
-}
-
-simple_msgs::RotationMatrixStamped createRandomRotationMatrixStamped() {
- return simple_msgs::RotationMatrixStamped(createRandomHeader(), createRandomRotationMatrix());
-}
-
-// Set of callback functions for all the simple_msgs.
-// They modify the received point.
-
-void callbackFunctionPoint(simple_msgs::Point& p) {
- simple_msgs::Point point(1, 1, 1);
- p += point;
-}
-
-void callbackFunctionHeader(simple_msgs::Header& h) {
- h.setFrameID("ID");
- h.setSequenceNumber(1);
- h.setTimestamp(10);
-}
-
-void callbackFunctionPose(simple_msgs::Pose& p) {
- p.getPosition() += 1.0;
- p.getQuaternion().setW(p.getQuaternion().getW() + 1);
- p.getQuaternion().setX(p.getQuaternion().getX() + 1);
- p.getQuaternion().setY(p.getQuaternion().getY() + 1);
- p.getQuaternion().setZ(p.getQuaternion().getZ() + 1);
-}
-
-void callbackFunctionQuaternion(simple_msgs::Quaternion& q) {
- q.setW(q.getW() + 1);
- q.setX(q.getX() + 1);
- q.setY(q.getY() + 1);
- q.setZ(q.getZ() + 1);
-}
-
-void callbackFunctionString(simple_msgs::String& s) {
- // Replace the string by a standard reply.
- s.set("REPLY");
-}
-
-void callbackFunctionRotationMatrix(simple_msgs::RotationMatrix& r) {
- r.setColumn(0, {{0, 0, 0}});
- r.setColumn(1, {{0, 0, 0}});
- r.setColumn(2, {{0, 0, 0}});
-}
-
-void callbackFunctionBool(simple_msgs::Bool& b) {
- b = !b; //! Invert the value of the Bool message.
-}
-
-void callbackFunctionInt(simple_msgs::Int& i) {
- i.set(i.get() + 1); //! Add 1.
-}
-
-// define callback function
-void callbackFunctionDouble(simple_msgs::Double& d) {
- d.set(d.get() + 1); //! Add 1.
-}
-
-// define callback function
-void callbackFunctionFloat(simple_msgs::Float& f) {
- f.set(f.get() + 1); //! Add 1.
-}
-
-void callbackFunctionPointStamped(simple_msgs::PointStamped& p) {
- // Add one to the point and set a default header.
- callbackFunctionPoint(p.getPoint());
- callbackFunctionHeader(p.getHeader());
-}
-
-void callbackFunctionPoseStamped(simple_msgs::PoseStamped& p) {
- // Add one to the point and set a default header.
- callbackFunctionPose(p.getPose());
- callbackFunctionHeader(p.getHeader());
-}
-
-void callbackFunctionPoseStampedLazy(simple_msgs::PoseStamped& p) {
- // Add one to the point and set a default header.
- callbackFunctionPoseStamped(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
-}
-
-void callbackFunctionQuaternionStamped(simple_msgs::QuaternionStamped& q) {
- // Add one to the point and set a default header.
- callbackFunctionQuaternion(q.getQuaternion());
- callbackFunctionHeader(q.getHeader());
-}
-
-void callbackFunctionRotationMatrixStamped(simple_msgs::RotationMatrixStamped& r) {
- // Add one to the point and set a default header.
- callbackFunctionRotationMatrix(r.getRotationMatrix());
- callbackFunctionHeader(r.getHeader());
-}
-
-// Set of const callbacks for all the simple_msgs
-// They receive a message and just save it.
-
-bool running_bool{false}, running_int{false}, running_float{false}, running_double{false}, running_string{false},
- running_header{false}, running_point{false}, running_quaternion{false}, running_pose{false},
- running_rotation_matrix{false}, running_point_stamped{false}, running_quaternion_stamped{false},
- running_pose_stamped{false}, running_rotation_matrix_stamped{false};
-
-int num_received_bool = 0, num_received_int = 0, num_received_float = 0, num_received_double = 0,
- num_received_string = 0, num_received_header = 0, num_received_point = 0, num_received_quaternion = 0,
- num_received_pose = 0, num_received_rotation_matrix = 0, num_received_point_stamped = 0,
- num_received_quaternion_stamped = 0, num_received_pose_stamped = 0, num_received_rotation_matrix_stamped = 0;
-
-simple_msgs::Bool received_bool{};
-simple_msgs::Int received_int{};
-simple_msgs::Double received_double{};
-simple_msgs::Float received_float{};
-simple_msgs::String received_string{};
-simple_msgs::Header received_header{};
-simple_msgs::Point received_point{};
-simple_msgs::PointStamped received_point_stamped{};
-simple_msgs::Quaternion received_quaternion{};
-simple_msgs::QuaternionStamped received_quaternion_stamped{};
-simple_msgs::Pose received_pose{};
-simple_msgs::PoseStamped received_pose_stamped{};
-simple_msgs::RotationMatrix received_rotation_matrix{};
-simple_msgs::RotationMatrixStamped received_rotation_matrix_stamped{};
-
-void callbackFunctionConstBool(const simple_msgs::Bool& b) {
- received_bool = b;
- num_received_bool++;
- if (!running_bool) { running_bool = true; }
-}
-
-void callbackFunctionConstInt(const simple_msgs::Int& i) {
- received_int = i;
- num_received_int++;
- if (!running_int) { running_int = true; }
-}
-
-void callbackFunctionConstFloat(const simple_msgs::Float& f) {
- received_float = f;
- num_received_float++;
- if (!running_float) { running_float = true; }
-}
-
-void callbackFunctionConstDouble(const simple_msgs::Double& d) {
- received_double = d;
- num_received_double++;
- if (!running_double) { running_double = true; }
-}
-
-void callbackFunctionConstString(const simple_msgs::String& s) {
- received_string = s;
- num_received_string++;
- if (!running_string) { running_string = true; }
-}
-
-void callbackFunctionConstHeader(const simple_msgs::Header& h) {
- received_header = h;
- num_received_header++;
- if (!running_header) { running_header = true; }
-}
-
-void callbackFunctionConstPoint(const simple_msgs::Point& p) {
- received_point = p;
- num_received_point++;
- if (!running_point) { running_point = true; }
-}
-
-void callbackFunctionConstPointStamped(const simple_msgs::PointStamped& ps) {
- received_point_stamped = ps;
- num_received_point_stamped++;
- if (!running_point_stamped) { running_point_stamped = true; }
-}
-
-void callbackFunctionConstQuaternion(const simple_msgs::Quaternion& q) {
- received_quaternion = q;
- num_received_quaternion++;
- if (!running_quaternion) { running_quaternion = true; }
-}
-
-void callbackFunctionConstQuaternionStamped(const simple_msgs::QuaternionStamped& qs) {
- received_quaternion_stamped = qs;
- num_received_quaternion_stamped++;
- if (!running_quaternion_stamped) { running_quaternion_stamped = true; }
-}
-
-void callbackFunctionConstPose(const simple_msgs::Pose& p) {
- received_pose = p;
- num_received_pose++;
- if (!running_pose) { running_pose = true; }
-}
-
-void callbackFunctionConstPoseStamped(const simple_msgs::PoseStamped& ps) {
- received_pose_stamped = ps;
- num_received_pose_stamped++;
- if (!running_pose_stamped) { running_pose_stamped = true; }
-}
-
-void callbackFunctionConstRotationMatrix(const simple_msgs::RotationMatrix& r) {
- received_rotation_matrix = r;
- num_received_rotation_matrix++;
- if (!running_rotation_matrix) { running_rotation_matrix = true; }
-}
-
-void callbackFunctionConstRotationMatrixStamped(const simple_msgs::RotationMatrixStamped& rs) {
- received_rotation_matrix_stamped = rs;
- num_received_rotation_matrix_stamped++;
- if (!running_rotation_matrix_stamped) { running_rotation_matrix_stamped = true; }
-}
-
-#endif
diff --git a/tests/test_bool.cpp b/tests/test_bool.cpp
index 1580dc5..1868d8b 100644
--- a/tests/test_bool.cpp
+++ b/tests/test_bool.cpp
@@ -11,33 +11,30 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
#include "simple_msgs/bool.h"
// TEST FOR USING THE BOOL MESSAGE WRAPPER
SCENARIO("Using a Bool Message") {
- bool true_boolean{true}, false_boolean{false};
// Testing constructors.
GIVEN("A Bool created from an empty constructor") {
simple_msgs::Bool empty_bool{};
WHEN("We check its value") {
- THEN("It has to be false") { REQUIRE(empty_bool.get() == false_boolean); }
+ THEN("It has to be false") { REQUIRE(empty_bool.get() == false); }
}
}
GIVEN("A Bool created from a bool") {
- simple_msgs::Bool single_bool(true_boolean);
+ simple_msgs::Bool single_bool(true);
WHEN("We check its value") {
- THEN("It has to be equal to the given parameter") { REQUIRE(single_bool.get() == true_boolean); }
+ THEN("It has to be equal to the given parameter") { REQUIRE(single_bool.get() == true); }
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A Bool") {
- simple_msgs::Bool single_bool(true_boolean);
+ simple_msgs::Bool single_bool(true);
WHEN("I construct a new Bool from the serialized data of the existing "
"Bool") {
simple_msgs::Bool copy_buffer_bool(single_bool.getBufferData()->data());
@@ -50,14 +47,14 @@ SCENARIO("Using a Bool Message") {
WHEN("I move-construct a new Bool") {
simple_msgs::Bool moved_bool(std::move(single_bool));
THEN("The new Bool contains the value that was contained in the original one") {
- REQUIRE(moved_bool.get() == true_boolean);
+ REQUIRE(moved_bool.get() == true);
}
}
}
- // Testing copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Bool") {
- simple_msgs::Bool single_bool(false_boolean);
+ simple_msgs::Bool single_bool(false);
WHEN("I copy-assign using the Bool's buffer data") {
simple_msgs::Bool copy_assigned_buffer_bool{};
auto data_ptr = std::make_shared(single_bool.getBufferData()->data());
@@ -73,46 +70,46 @@ SCENARIO("Using a Bool Message") {
simple_msgs::Bool move_assigned_bool{};
move_assigned_bool = std::move(single_bool);
THEN("The new Bool contains the value that was contained in the original one") {
- REQUIRE(move_assigned_bool.get() == false_boolean);
+ REQUIRE(move_assigned_bool.get() == false);
}
}
}
// Testing getter-setter
GIVEN("A Bool") {
- // start a Bool
simple_msgs::Bool bool_msg{};
WHEN("I set its value") {
- bool_msg.set(true_boolean);
- THEN("The Bool contains the correct value") { REQUIRE(bool_msg.get() == true_boolean); }
+ bool_msg.set(true);
+ THEN("The Bool contains the correct value") { REQUIRE(bool_msg.get() == true); }
}
}
// Testing operations.
GIVEN("Two identical Bools") {
- simple_msgs::Bool single_true_boolean{true_boolean};
- simple_msgs::Bool single_false_boolean{true_boolean};
+ simple_msgs::Bool boolean_1{true};
+ simple_msgs::Bool boolean_2{true};
WHEN("I compare them") {
- THEN("They are equal") { REQUIRE(single_true_boolean == single_false_boolean); }
+ THEN("They are equal") { REQUIRE(boolean_1 == boolean_2); }
}
WHEN("I change the value of one of them") {
- single_true_boolean.set(false_boolean);
- THEN("They are different") { REQUIRE(single_true_boolean != single_false_boolean); }
+ boolean_1.set(false);
+ THEN("They are different") { REQUIRE(boolean_1 != boolean_2); }
}
WHEN("I compare one to the negative value of the other") {
- THEN("They are different") { REQUIRE((!single_true_boolean) != single_false_boolean); }
+ THEN("They are different") { REQUIRE((!boolean_1) != boolean_2); }
}
}
+ // Testing message topic and stream operator.
GIVEN("A Bool") {
- simple_msgs::Bool single_bool{true_boolean};
+ simple_msgs::Bool boolean{true};
WHEN("I get the message topic") {
- std::string topic_name = single_bool.getTopic();
+ std::string topic_name = boolean.getTopic();
THEN("I get the correct one") { REQUIRE(topic_name == "BOOL"); }
}
WHEN("I print the Bool") {
std::ostringstream out;
- out << single_bool;
+ out << boolean;
THEN("The ostream is correct") { REQUIRE(out.str() == "1"); }
}
}
diff --git a/tests/test_double.cpp b/tests/test_double.cpp
index 1561f56..3fda26c 100644
--- a/tests/test_double.cpp
+++ b/tests/test_double.cpp
@@ -11,32 +11,35 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
+#include "random_generators.hpp"
#include "simple_msgs/double.hpp"
+using namespace simple_tests;
+
// TEST FOR USING THE DOUBLE MESSAGE WRAPPER
SCENARIO("Using a Double Message") {
- double double_1 = static_cast(rand()) / RAND_MAX;
- double double_2 = static_cast(rand()) / RAND_MAX;
+ double double_1 = double_dist(generator);
+ double double_2 = double_dist(generator);
+
// Testing constructors.
GIVEN("A Double created from an empty constructor") {
simple_msgs::Double empty_double{};
WHEN("We check its value") {
- THEN("It has to be zero") { REQUIRE(empty_double.get() == 0); }
+ THEN("It has to be zero") { REQUIRE(empty_double.get() == Approx(0)); }
}
}
GIVEN("A Double created from a double") {
simple_msgs::Double single_double{double_1};
WHEN("We check the its value") {
- THEN("It has to be equal to the given parameter") { REQUIRE(single_double.get() == double_1); }
+ THEN("It has to be equal to the given parameter") { REQUIRE(single_double.get() == Approx(double_1)); }
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A Double") {
simple_msgs::Double single_double{double_1};
WHEN("I construct a new Double from the serialized data of the existing Double") {
@@ -50,12 +53,12 @@ SCENARIO("Using a Double Message") {
WHEN("I move-construct a new Double") {
simple_msgs::Double moved_double{std::move(single_double)};
THEN("The new Double contains the value that was contained in the orignal one") {
- REQUIRE(moved_double.get() == double_1);
+ REQUIRE(moved_double.get() == Approx(double_1));
}
}
}
- // Testing copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Double") {
simple_msgs::Double single_double{double_1};
WHEN("I copy-assign from that Double's buffer") {
@@ -72,7 +75,7 @@ SCENARIO("Using a Double Message") {
WHEN("I move-assign from that Double") {
simple_msgs::Double move_assigned_double{};
move_assigned_double = std::move(single_double);
- THEN("The new Double is equal to the original") { REQUIRE(move_assigned_double.get() == double_1); }
+ THEN("The new Double is equal to the original") { REQUIRE(move_assigned_double.get() == Approx(double_1)); }
}
}
@@ -81,9 +84,9 @@ SCENARIO("Using a Double Message") {
// start a Double
simple_msgs::Double d{};
WHEN("I set the value of the Double") {
- double x = static_cast(rand()) / RAND_MAX;
+ double x = double_dist(generator);
d.set(x);
- THEN("Its value is correct") { REQUIRE(d.get() == x); }
+ THEN("Its value is correct") { REQUIRE(d.get() == Approx(x)); }
}
}
@@ -100,6 +103,7 @@ SCENARIO("Using a Double Message") {
}
}
+ // Testing message topic and stream operator.
GIVEN("A Double") {
simple_msgs::Double single_double(double_1);
WHEN("I get the message topic") {
diff --git a/tests/test_float.cpp b/tests/test_float.cpp
index 772afc0..56018dd 100644
--- a/tests/test_float.cpp
+++ b/tests/test_float.cpp
@@ -11,32 +11,35 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
+#include "random_generators.hpp"
#include "simple_msgs/float.hpp"
+using namespace simple_tests;
+
// TEST FOR USING THE Float MESSAGE WRAPPER
SCENARIO("Using a Float Message") {
- float float_1 = static_cast(rand()) / RAND_MAX;
- float float_2 = static_cast(rand()) / RAND_MAX;
+ float float_1 = static_cast(double_dist(generator));
+ float float_2 = static_cast(double_dist(generator));
+
// Testing constructors.
GIVEN("A Float created from an empty constructor") {
simple_msgs::Float empty_Float{};
WHEN("We check its value") {
- THEN("It has to be zero") { REQUIRE(empty_Float.get() == 0); }
+ THEN("It has to be zero") { REQUIRE(empty_Float.get() == Approx(0)); }
}
}
GIVEN("A Float created from a Float") {
simple_msgs::Float single_Float{float_1};
WHEN("We check the its value") {
- THEN("It has to be equal to the given parameter") { REQUIRE(single_Float.get() == float_1); }
+ THEN("It has to be equal to the given parameter") { REQUIRE(single_Float.get() == Approx(float_1)); }
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A Float") {
simple_msgs::Float single_Float{float_1};
WHEN("I construct a new Float from the serialized data of the existing Float") {
@@ -50,12 +53,12 @@ SCENARIO("Using a Float Message") {
WHEN("I move-construct a new Float") {
simple_msgs::Float moved_Float{std::move(single_Float)};
THEN("The new Float contains the value that was contained in the orignal one") {
- REQUIRE(moved_Float.get() == float_1);
+ REQUIRE(moved_Float.get() == Approx(float_1));
}
}
}
- // Testing copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Float") {
simple_msgs::Float single_float{float_1};
WHEN("I copy-assign from that Float's buffer") {
@@ -72,7 +75,7 @@ SCENARIO("Using a Float Message") {
WHEN("I move-assign from that Float") {
simple_msgs::Float move_assigned_float{};
move_assigned_float = std::move(single_float);
- THEN("The new Float is equal to the original") { REQUIRE(move_assigned_float.get() == float_1); }
+ THEN("The new Float is equal to the original") { REQUIRE(move_assigned_float.get() == Approx(float_1)); }
}
}
@@ -83,7 +86,7 @@ SCENARIO("Using a Float Message") {
WHEN("I set the value of the Float") {
float x = static_cast(rand()) / RAND_MAX;
d.set(x);
- THEN("Its value is correct") { REQUIRE(d.get() == x); }
+ THEN("Its value is correct") { REQUIRE(d.get() == Approx(x)); }
}
}
@@ -100,6 +103,7 @@ SCENARIO("Using a Float Message") {
}
}
+ // Testing message topic and stream operator.
GIVEN("A Float") {
simple_msgs::Float single_Float(float_1);
WHEN("I get the message topic") {
diff --git a/tests/test_header.cpp b/tests/test_header.cpp
index bd9a021..8a0485f 100644
--- a/tests/test_header.cpp
+++ b/tests/test_header.cpp
@@ -11,18 +11,21 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
+#include "random_generators.hpp"
#include "simple_msgs/header.h"
+using namespace simple_tests;
+
// TEST FOR USING THE HEADER MESSAGE WRAPPER
SCENARIO("Using a Header Message") {
- int int_1 = static_cast(rand());
- long long long_1 = rand();
- long long long_2 = rand();
+ int int_1 = int_dist(generator);
+ long long long_1 = static_cast(double_dist(generator));
+ long long long_2 = static_cast(double_dist(generator));
std::string string_1 = std::to_string(long_1);
+
// Testing constructors.
GIVEN("A Header created from an empty constructor") {
simple_msgs::Header empty_header{};
@@ -46,7 +49,7 @@ SCENARIO("Using a Header Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A header") {
simple_msgs::Header original_header{int_1, string_1, long_1};
WHEN("I construct a new Header from the serialized data of the existing Header") {
@@ -67,7 +70,7 @@ SCENARIO("Using a Header Message") {
}
}
- // Testing copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Header") {
simple_msgs::Header original_header(int_1, string_1, long_1);
WHEN("I copy-assign from that Header's buffer") {
@@ -120,9 +123,24 @@ SCENARIO("Using a Header Message") {
header1.setTimestamp(long_2);
THEN("They have to be different") { REQUIRE(header1 != header2); }
}
+ }
+
+ // Testing message topic and stream operator.
+ GIVEN("A Header") {
+ simple_msgs::Header header{int_1, string_1, long_1};
WHEN("I get the message topic") {
- std::string topic_name = header1.getTopic();
+ std::string topic_name = header.getTopic();
THEN("I get the correct one") { REQUIRE(topic_name == "HEAD"); }
}
+ WHEN("I print the Float") {
+ std::ostringstream out_msg, out_check;
+ out_msg << header;
+ out_check << "Header\n \t"
+ << "seq_n: " << std::to_string(int_1) << "\n \t"
+ << "frame_id: " << string_1 << "\n \t"
+ << "timestamp: " << std::to_string(long_1) << "\n";
+ ;
+ THEN("The output is correct") { REQUIRE(out_msg.str() == out_check.str()); }
+ }
}
}
diff --git a/tests/test_image.cpp b/tests/test_image.cpp
index 109ff1b..d04f59f 100644
--- a/tests/test_image.cpp
+++ b/tests/test_image.cpp
@@ -11,29 +11,31 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
#include "simple_msgs/image.hpp"
-#include "test_utils.hpp"
+#include "test_utilities.hpp"
+
+using namespace simple_tests;
// TEST FOR USING THE IMAGE MESSAGE WRAPPER
SCENARIO("Using an uint8 Image Message") {
simple_msgs::Pose empty_pose{};
simple_msgs::Header empty_header{};
- double random_double_1 = static_cast(rand()) / RAND_MAX;
- double random_double_2 = static_cast(rand()) / RAND_MAX;
- double random_double_3 = static_cast(rand()) / RAND_MAX;
- uint32_t random_int_1 = rand() / 100;
- uint32_t random_int_2 = rand() / 100;
- uint32_t random_int_3 = rand() / 100;
+ double random_double_1 = double_dist(generator);
+ double random_double_2 = double_dist(generator);
+ double random_double_3 = double_dist(generator);
+ uint32_t random_int_1 = static_cast(int_dist(generator));
+ uint32_t random_int_2 = static_cast(int_dist(generator));
+ uint32_t random_int_3 = static_cast(int_dist(generator));
std::string random_string = std::to_string(random_double_1);
simple_msgs::Header random_header = createRandomHeader();
simple_msgs::Pose random_pose = createRandomPose();
- // uint8_t data
- int image_size{1};
- auto image_data = std::make_shared(static_cast(rand() % 256));
+
+ // Uint8_t data.
+ uint64_t image_size{1};
+ auto image_data = std::make_shared(static_cast(int_dist(generator)));
// Testing constructor.
GIVEN("A uint8_t Image created from an empty constructor") {
@@ -56,7 +58,7 @@ SCENARIO("Using an uint8 Image Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -72,9 +74,9 @@ SCENARIO("Using an uint8 Image Message") {
WHEN("I move-construct a new Image") {
simple_msgs::Image move_image{std::move(random_image)};
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_image.getNumChannels() == 1);
REQUIRE(move_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_image.getImageDimensions()[1] == random_int_2);
@@ -88,7 +90,7 @@ SCENARIO("Using an uint8 Image Message") {
}
}
- // Testing copy-assignment.
+ // Testing copy/move assignment.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -112,9 +114,9 @@ SCENARIO("Using an uint8 Image Message") {
simple_msgs::Image move_assigned_image{};
move_assigned_image = std::move(random_image);
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_assigned_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_assigned_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_assigned_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_assigned_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_assigned_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_assigned_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_assigned_image.getNumChannels() == 1);
REQUIRE(move_assigned_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_assigned_image.getImageDimensions()[1] == random_int_2);
@@ -157,9 +159,9 @@ SCENARIO("Using an uint8 Image Message") {
WHEN("I set the Image resolution") {
empty_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
THEN("The resolution is correct") {
- REQUIRE(empty_image.getSpacing()[0] == random_double_1);
- REQUIRE(empty_image.getSpacing()[1] == random_double_2);
- REQUIRE(empty_image.getSpacing()[2] == random_double_3);
+ REQUIRE(empty_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(empty_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(empty_image.getSpacing()[2] == Approx(random_double_3));
}
}
WHEN("I set the Image encoding") {
@@ -192,18 +194,19 @@ SCENARIO("Using an uint8 Image Message") {
SCENARIO("Using an int16_t Image Message") {
simple_msgs::Pose empty_pose{};
simple_msgs::Header empty_header{};
- double random_double_1 = static_cast(rand()) / RAND_MAX;
- double random_double_2 = static_cast(rand()) / RAND_MAX;
- double random_double_3 = static_cast(rand()) / RAND_MAX;
- uint32_t random_int_1 = rand() / 100;
- uint32_t random_int_2 = rand() / 100;
- uint32_t random_int_3 = rand() / 100;
+ double random_double_1 = double_dist(generator);
+ double random_double_2 = double_dist(generator);
+ double random_double_3 = double_dist(generator);
+ uint32_t random_int_1 = static_cast(int_dist(generator));
+ uint32_t random_int_2 = static_cast(int_dist(generator));
+ uint32_t random_int_3 = static_cast(int_dist(generator));
std::string random_string = std::to_string(random_double_1);
simple_msgs::Header random_header = createRandomHeader();
simple_msgs::Pose random_pose = createRandomPose();
- // int16_t data
- int image_size{1};
- auto image_data = std::make_shared(static_cast(rand() % 256));
+
+ // Int16_t data.
+ uint64_t image_size{1};
+ auto image_data = std::make_shared(static_cast(rand() % 256)); // TODO
// Testing constructor.
GIVEN("A int16_t Image created from an empty constructor") {
@@ -226,7 +229,7 @@ SCENARIO("Using an int16_t Image Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -242,9 +245,9 @@ SCENARIO("Using an int16_t Image Message") {
WHEN("I move-construct a new Image") {
simple_msgs::Image move_image{std::move(random_image)};
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_image.getNumChannels() == 1);
REQUIRE(move_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_image.getImageDimensions()[1] == random_int_2);
@@ -258,7 +261,7 @@ SCENARIO("Using an int16_t Image Message") {
}
}
- // Testing copy-assignment.
+ // Testing copy/move assignment.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -282,9 +285,9 @@ SCENARIO("Using an int16_t Image Message") {
simple_msgs::Image move_assigned_image{};
move_assigned_image = std::move(random_image);
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_assigned_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_assigned_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_assigned_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_assigned_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_assigned_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_assigned_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_assigned_image.getNumChannels() == 1);
REQUIRE(move_assigned_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_assigned_image.getImageDimensions()[1] == random_int_2);
@@ -327,9 +330,9 @@ SCENARIO("Using an int16_t Image Message") {
WHEN("I set the Image resolution") {
empty_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
THEN("The resolution is correct") {
- REQUIRE(empty_image.getSpacing()[0] == random_double_1);
- REQUIRE(empty_image.getSpacing()[1] == random_double_2);
- REQUIRE(empty_image.getSpacing()[2] == random_double_3);
+ REQUIRE(empty_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(empty_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(empty_image.getSpacing()[2] == Approx(random_double_3));
}
}
WHEN("I set the Image encoding") {
@@ -362,17 +365,18 @@ SCENARIO("Using an int16_t Image Message") {
SCENARIO("Using a float Image Message") {
simple_msgs::Pose empty_pose{};
simple_msgs::Header empty_header{};
- double random_double_1 = static_cast(rand()) / RAND_MAX;
- double random_double_2 = static_cast(rand()) / RAND_MAX;
- double random_double_3 = static_cast(rand()) / RAND_MAX;
- uint32_t random_int_1 = rand() / 100;
- uint32_t random_int_2 = rand() / 100;
- uint32_t random_int_3 = rand() / 100;
+ double random_double_1 = double_dist(generator);
+ double random_double_2 = double_dist(generator);
+ double random_double_3 = double_dist(generator);
+ uint32_t random_int_1 = static_cast(int_dist(generator));
+ uint32_t random_int_2 = static_cast(int_dist(generator));
+ uint32_t random_int_3 = static_cast(int_dist(generator));
std::string random_string = std::to_string(random_double_1);
simple_msgs::Header random_header = createRandomHeader();
simple_msgs::Pose random_pose = createRandomPose();
- // float data
- int image_size{1};
+
+ // Float data.
+ uint64_t image_size{1};
auto image_data = std::make_shared(static_cast(rand() % 256));
// Testing constructor.
@@ -396,7 +400,7 @@ SCENARIO("Using a float Image Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -412,9 +416,9 @@ SCENARIO("Using a float Image Message") {
WHEN("I move-construct a new Image") {
simple_msgs::Image move_image{std::move(random_image)};
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_image.getNumChannels() == 1);
REQUIRE(move_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_image.getImageDimensions()[1] == random_int_2);
@@ -428,7 +432,7 @@ SCENARIO("Using a float Image Message") {
}
}
- // Testing copy-assignment.
+ // Testing copy/move assignment.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -452,9 +456,9 @@ SCENARIO("Using a float Image Message") {
simple_msgs::Image move_assigned_image{};
move_assigned_image = std::move(random_image);
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_assigned_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_assigned_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_assigned_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_assigned_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_assigned_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_assigned_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_assigned_image.getNumChannels() == 1);
REQUIRE(move_assigned_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_assigned_image.getImageDimensions()[1] == random_int_2);
@@ -497,9 +501,9 @@ SCENARIO("Using a float Image Message") {
WHEN("I set the Image resolution") {
empty_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
THEN("The resolution is correct") {
- REQUIRE(empty_image.getSpacing()[0] == random_double_1);
- REQUIRE(empty_image.getSpacing()[1] == random_double_2);
- REQUIRE(empty_image.getSpacing()[2] == random_double_3);
+ REQUIRE(empty_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(empty_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(empty_image.getSpacing()[2] == Approx(random_double_3));
}
}
WHEN("I set the Image encoding") {
@@ -532,17 +536,18 @@ SCENARIO("Using a float Image Message") {
SCENARIO("Using an double Image Message") {
simple_msgs::Pose empty_pose{};
simple_msgs::Header empty_header{};
- double random_double_1 = static_cast(rand()) / RAND_MAX;
- double random_double_2 = static_cast(rand()) / RAND_MAX;
- double random_double_3 = static_cast(rand()) / RAND_MAX;
- uint32_t random_int_1 = rand() / 100;
- uint32_t random_int_2 = rand() / 100;
- uint32_t random_int_3 = rand() / 100;
+ double random_double_1 = double_dist(generator);
+ double random_double_2 = double_dist(generator);
+ double random_double_3 = double_dist(generator);
+ uint32_t random_int_1 = static_cast(int_dist(generator));
+ uint32_t random_int_2 = static_cast(int_dist(generator));
+ uint32_t random_int_3 = static_cast(int_dist(generator));
std::string random_string = std::to_string(random_double_1);
simple_msgs::Header random_header = createRandomHeader();
simple_msgs::Pose random_pose = createRandomPose();
- // double data
- int image_size{1};
+
+ // Double data.
+ uint64_t image_size{1};
auto image_data = std::make_shared(static_cast(rand() % 256));
// Testing constructor.
@@ -566,7 +571,7 @@ SCENARIO("Using an double Image Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -582,9 +587,9 @@ SCENARIO("Using an double Image Message") {
WHEN("I move-construct a new Image") {
simple_msgs::Image move_image{std::move(random_image)};
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_image.getNumChannels() == 1);
REQUIRE(move_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_image.getImageDimensions()[1] == random_int_2);
@@ -598,7 +603,7 @@ SCENARIO("Using an double Image Message") {
}
}
- // Testing copy-assignment.
+ // Testing copy/move assignment.
GIVEN("An Image") {
simple_msgs::Image random_image{};
random_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
@@ -622,9 +627,9 @@ SCENARIO("Using an double Image Message") {
simple_msgs::Image move_assigned_image{};
move_assigned_image = std::move(random_image);
THEN("The new Image fields are the same as the original") {
- REQUIRE(move_assigned_image.getSpacing()[0] == random_double_1);
- REQUIRE(move_assigned_image.getSpacing()[1] == random_double_2);
- REQUIRE(move_assigned_image.getSpacing()[2] == random_double_3);
+ REQUIRE(move_assigned_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(move_assigned_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(move_assigned_image.getSpacing()[2] == Approx(random_double_3));
REQUIRE(move_assigned_image.getNumChannels() == 1);
REQUIRE(move_assigned_image.getImageDimensions()[0] == random_int_1);
REQUIRE(move_assigned_image.getImageDimensions()[1] == random_int_2);
@@ -667,9 +672,9 @@ SCENARIO("Using an double Image Message") {
WHEN("I set the Image resolution") {
empty_image.setImageSpacing(random_double_1, random_double_2, random_double_3);
THEN("The resolution is correct") {
- REQUIRE(empty_image.getSpacing()[0] == random_double_1);
- REQUIRE(empty_image.getSpacing()[1] == random_double_2);
- REQUIRE(empty_image.getSpacing()[2] == random_double_3);
+ REQUIRE(empty_image.getSpacing()[0] == Approx(random_double_1));
+ REQUIRE(empty_image.getSpacing()[1] == Approx(random_double_2));
+ REQUIRE(empty_image.getSpacing()[2] == Approx(random_double_3));
}
}
WHEN("I set the Image encoding") {
diff --git a/tests/test_int.cpp b/tests/test_int.cpp
index 9eb20e1..ce5cb23 100644
--- a/tests/test_int.cpp
+++ b/tests/test_int.cpp
@@ -11,16 +11,19 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
+#include "random_generators.hpp"
#include "simple_msgs/int.hpp"
+using namespace simple_tests;
+
// TEST FOR USING THE Int MESSAGE WRAPPER
SCENARIO("Using a Int Message") {
- int int_1 = rand() / 100;
- int int_2 = rand() / 100;
+ int int_1 = int_dist(generator);
+ int int_2 = int_dist(generator);
+
// Testing constructors.
GIVEN("A Int created from an empty constructor") {
simple_msgs::Int empty_Int{};
@@ -36,7 +39,7 @@ SCENARIO("Using a Int Message") {
}
}
- // Testing copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A Int") {
simple_msgs::Int single_Int{int_1};
WHEN("I construct a new Int from the serialized data of the existing Int") {
@@ -55,7 +58,7 @@ SCENARIO("Using a Int Message") {
}
}
- // Testing copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Int") {
simple_msgs::Int single_Int{int_1};
WHEN("I copy-assign from that Int's buffer") {
@@ -100,6 +103,7 @@ SCENARIO("Using a Int Message") {
}
}
+ // Testing message topic and stream operator.
GIVEN("A Int") {
simple_msgs::Int single_Int(int_1);
WHEN("I get the message topic") {
diff --git a/tests/test_point.cpp b/tests/test_point.cpp
index c2aa79c..e1f9378 100644
--- a/tests/test_point.cpp
+++ b/tests/test_point.cpp
@@ -11,27 +11,29 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
+
+#include "random_generators.hpp"
#include "simple_msgs/point.h"
+using namespace simple_tests;
+
// Tests for Point Message.
SCENARIO("Using a Point Message") {
- double double_1 = static_cast(rand()) / RAND_MAX;
- double double_2 = static_cast(rand()) / RAND_MAX;
- double double_3 = static_cast(rand()) / RAND_MAX;
+ double double_1 = double_dist(generator);
+ double double_2 = double_dist(generator);
+ double double_3 = double_dist(generator);
std::array double_array{{double_1, double_2, double_3}};
- std::array twisted_double_array{{double_3, double_1, double_2}};
+ std::array flipped_double_array{{double_3, double_1, double_2}};
// Testing Constructors.
GIVEN("An empty Point") {
simple_msgs::Point empty_point{};
WHEN("It is constructed") {
THEN("The Point coordinates have to be zero") {
- REQUIRE(empty_point.getX() == 0);
- REQUIRE(empty_point.getY() == 0);
- REQUIRE(empty_point.getZ() == 0);
+ REQUIRE(empty_point.getX() == Approx(0));
+ REQUIRE(empty_point.getY() == Approx(0));
+ REQUIRE(empty_point.getZ() == Approx(0));
}
}
}
@@ -40,9 +42,9 @@ SCENARIO("Using a Point Message") {
simple_msgs::Point single_double_point{double_1};
WHEN("We check the Point coordinates") {
THEN("They all have to be equal to the given value") {
- REQUIRE(single_double_point.getX() == double_1);
- REQUIRE(single_double_point.getY() == double_1);
- REQUIRE(single_double_point.getZ() == double_1);
+ REQUIRE(single_double_point.getX() == Approx(double_1));
+ REQUIRE(single_double_point.getY() == Approx(double_1));
+ REQUIRE(single_double_point.getZ() == Approx(double_1));
}
}
}
@@ -51,9 +53,9 @@ SCENARIO("Using a Point Message") {
simple_msgs::Point three_double_point{double_1, double_2, double_3};
WHEN("We check the Point coordinates") {
THEN("They have to be equal to the given values") {
- REQUIRE(three_double_point.getX() == double_1);
- REQUIRE(three_double_point.getY() == double_2);
- REQUIRE(three_double_point.getZ() == double_3);
+ REQUIRE(three_double_point.getX() == Approx(double_1));
+ REQUIRE(three_double_point.getY() == Approx(double_2));
+ REQUIRE(three_double_point.getZ() == Approx(double_3));
}
}
}
@@ -62,9 +64,9 @@ SCENARIO("Using a Point Message") {
simple_msgs::Point double_array_point{double_array};
WHEN("We check the Point coordinates") {
THEN("They all have to be equal to the array content") {
- REQUIRE(double_array_point.getX() == double_1);
- REQUIRE(double_array_point.getY() == double_2);
- REQUIRE(double_array_point.getZ() == double_3);
+ REQUIRE(double_array_point.getX() == Approx(double_1));
+ REQUIRE(double_array_point.getY() == Approx(double_2));
+ REQUIRE(double_array_point.getZ() == Approx(double_3));
}
}
}
@@ -73,14 +75,14 @@ SCENARIO("Using a Point Message") {
simple_msgs::Point moved_array_point{std::move(double_array)};
WHEN("We check the Point coordinates") {
THEN("They all have to be equal to the array content") {
- REQUIRE(moved_array_point.getX() == double_1);
- REQUIRE(moved_array_point.getY() == double_2);
- REQUIRE(moved_array_point.getZ() == double_3);
+ REQUIRE(moved_array_point.getX() == Approx(double_1));
+ REQUIRE(moved_array_point.getY() == Approx(double_2));
+ REQUIRE(moved_array_point.getZ() == Approx(double_3));
}
}
}
- // Testing Copy-constructors.
+ // Testing copy/move constructors.
GIVEN("A Point") {
simple_msgs::Point single_point{double_array};
simple_msgs::Point reference_point{single_point};
@@ -95,14 +97,14 @@ SCENARIO("Using a Point Message") {
WHEN("I move-construct a new Point") {
simple_msgs::Point moved_point{std::move(single_point)};
THEN("The new Point coordinates are equal to the previous' ones") {
- REQUIRE(moved_point.getX() == reference_point.getX());
- REQUIRE(moved_point.getY() == reference_point.getY());
- REQUIRE(moved_point.getZ() == reference_point.getZ());
+ REQUIRE(moved_point.getX() == Approx(reference_point.getX()));
+ REQUIRE(moved_point.getY() == Approx(reference_point.getY()));
+ REQUIRE(moved_point.getZ() == Approx(reference_point.getZ()));
}
}
}
- // Testing Copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A Point") {
simple_msgs::Point single_point{double_1};
simple_msgs::Point reference_point{double_1};
@@ -123,19 +125,19 @@ SCENARIO("Using a Point Message") {
THEN("The new Point has to be same as the original") { REQUIRE(copy_buffer_point == reference_point); }
}
WHEN("I copy-assign a double array to that point") {
- single_point = twisted_double_array;
+ single_point = flipped_double_array;
THEN("The Point coordinates are equal to the array") {
- REQUIRE(single_point.getX() == twisted_double_array[0]);
- REQUIRE(single_point.getY() == twisted_double_array[1]);
- REQUIRE(single_point.getZ() == twisted_double_array[2]);
+ REQUIRE(single_point.getX() == Approx(flipped_double_array[0]));
+ REQUIRE(single_point.getY() == Approx(flipped_double_array[1]));
+ REQUIRE(single_point.getZ() == Approx(flipped_double_array[2]));
}
}
WHEN("I move-assign from an array to that Point") {
- single_point = std::move(twisted_double_array);
+ single_point = std::move(flipped_double_array);
THEN("The Point coordinates are equal to the array") {
- REQUIRE(single_point.getX() == twisted_double_array[0]);
- REQUIRE(single_point.getY() == twisted_double_array[1]);
- REQUIRE(single_point.getZ() == twisted_double_array[2]);
+ REQUIRE(single_point.getX() == Approx(flipped_double_array[0]));
+ REQUIRE(single_point.getY() == Approx(flipped_double_array[1]));
+ REQUIRE(single_point.getZ() == Approx(flipped_double_array[2]));
}
}
}
@@ -176,65 +178,65 @@ SCENARIO("Using a Point Message") {
WHEN("I add them") {
simple_msgs::Point sum_point = first_point + second_point;
THEN("The sum should be correct") {
- REQUIRE(sum_point.getX() == (first_point.getX() + second_point.getX()));
- REQUIRE(sum_point.getY() == (first_point.getY() + second_point.getY()));
- REQUIRE(sum_point.getZ() == (first_point.getZ() + second_point.getZ()));
+ REQUIRE(sum_point.getX() == Approx(first_point.getX() + second_point.getX()));
+ REQUIRE(sum_point.getY() == Approx(first_point.getY() + second_point.getY()));
+ REQUIRE(sum_point.getZ() == Approx(first_point.getZ() + second_point.getZ()));
}
}
WHEN("I add the second to the first one") {
first_point += second_point;
THEN("The first Point should have increased by the second Point") {
- REQUIRE(first_point.getX() == (double_1 + second_point.getX()));
- REQUIRE(first_point.getY() == (double_2 + second_point.getX()));
- REQUIRE(first_point.getZ() == (double_3 + second_point.getX()));
+ REQUIRE(first_point.getX() == Approx(double_1 + second_point.getX()));
+ REQUIRE(first_point.getY() == Approx(double_2 + second_point.getX()));
+ REQUIRE(first_point.getZ() == Approx(double_3 + second_point.getX()));
}
}
WHEN("I subtract them") {
simple_msgs::Point difference_point = first_point - second_point;
THEN("The difference should be correct") {
- REQUIRE(difference_point.getX() == (first_point.getX() - second_point.getX()));
- REQUIRE(difference_point.getY() == (first_point.getY() - second_point.getY()));
- REQUIRE(difference_point.getZ() == (first_point.getZ() - second_point.getZ()));
+ REQUIRE(difference_point.getX() == Approx(first_point.getX() - second_point.getX()));
+ REQUIRE(difference_point.getY() == Approx(first_point.getY() - second_point.getY()));
+ REQUIRE(difference_point.getZ() == Approx(first_point.getZ() - second_point.getZ()));
}
}
WHEN("I subtract the second to the first one") {
first_point -= second_point;
THEN("The first Point should have decreased by the second Point") {
- REQUIRE(first_point.getX() == double_1 - second_point.getX());
- REQUIRE(first_point.getY() == double_2 - second_point.getY());
- REQUIRE(first_point.getZ() == double_3 - second_point.getZ());
+ REQUIRE(first_point.getX() == Approx(double_1 - second_point.getX()));
+ REQUIRE(first_point.getY() == Approx(double_2 - second_point.getY()));
+ REQUIRE(first_point.getZ() == Approx(double_3 - second_point.getZ()));
}
}
WHEN("I multiply them") {
simple_msgs::Point multiplied_point = first_point * second_point;
THEN("The result is correct") {
- REQUIRE(multiplied_point.getX() == first_point.getX() * second_point.getX());
- REQUIRE(multiplied_point.getY() == first_point.getY() * second_point.getY());
- REQUIRE(multiplied_point.getZ() == first_point.getZ() * second_point.getZ());
+ REQUIRE(multiplied_point.getX() == Approx(first_point.getX() * second_point.getX()));
+ REQUIRE(multiplied_point.getY() == Approx(first_point.getY() * second_point.getY()));
+ REQUIRE(multiplied_point.getZ() == Approx(first_point.getZ() * second_point.getZ()));
}
}
WHEN("I multiply the first times the second") {
first_point *= second_point;
THEN("The result is correct") {
- REQUIRE(first_point.getX() == double_1 * second_point.getX());
- REQUIRE(first_point.getY() == double_2 * second_point.getY());
- REQUIRE(first_point.getZ() == double_3 * second_point.getZ());
+ REQUIRE(first_point.getX() == Approx(double_1 * second_point.getX()));
+ REQUIRE(first_point.getY() == Approx(double_2 * second_point.getY()));
+ REQUIRE(first_point.getZ() == Approx(double_3 * second_point.getZ()));
}
}
WHEN("I divide them") {
simple_msgs::Point divided_point = first_point / second_point;
THEN("The result is correct") {
- REQUIRE(divided_point.getX() == first_point.getX() / second_point.getX());
- REQUIRE(divided_point.getY() == first_point.getY() / second_point.getY());
- REQUIRE(divided_point.getZ() == first_point.getZ() / second_point.getZ());
+ REQUIRE(divided_point.getX() == Approx(first_point.getX() / second_point.getX()));
+ REQUIRE(divided_point.getY() == Approx(first_point.getY() / second_point.getY()));
+ REQUIRE(divided_point.getZ() == Approx(first_point.getZ() / second_point.getZ()));
}
}
WHEN("I divide the first by the second") {
first_point /= second_point;
THEN("The result is correct") {
- REQUIRE(first_point.getX() == double_1 / second_point.getX());
- REQUIRE(first_point.getY() == double_2 / second_point.getY());
- REQUIRE(first_point.getZ() == double_3 / second_point.getZ());
+ REQUIRE(first_point.getX() == Approx(double_1 / second_point.getX()));
+ REQUIRE(first_point.getY() == Approx(double_2 / second_point.getY()));
+ REQUIRE(first_point.getZ() == Approx(double_3 / second_point.getZ()));
}
}
}
@@ -244,26 +246,27 @@ SCENARIO("Using a Point Message") {
simple_msgs::Point single_point{};
WHEN("I set the X coordinate of the Point") {
single_point.setX(double_3);
- THEN("The data point has the correct coordinate") { REQUIRE(single_point.getX() == double_3); }
+ THEN("The data point has the correct coordinate") { REQUIRE(single_point.getX() == Approx(double_3)); }
}
WHEN("I set the Y coordinate of the Point") {
single_point.setY(double_1);
- THEN("The data point has the correct coordinate") { REQUIRE(single_point.getY() == double_1); }
+ THEN("The data point has the correct coordinate") { REQUIRE(single_point.getY() == Approx(double_1)); }
}
WHEN("I set the Z coordinate of the Point") {
single_point.setZ(double_2);
- THEN("The data Point has the correct coordinate") { REQUIRE(single_point.getZ() == double_2); }
+ THEN("The data Point has the correct coordinate") { REQUIRE(single_point.getZ() == Approx(double_2)); }
}
}
+ // Testing vectorization, message topic and stream operator.
GIVEN("A Point") {
simple_msgs::Point single_point{double_array};
WHEN("I get the double array from the Point") {
auto array = single_point.toVector();
THEN("The array elements are correct") {
- REQUIRE(array[0] == single_point.getX());
- REQUIRE(array[1] == single_point.getY());
- REQUIRE(array[2] == single_point.getZ());
+ REQUIRE(array[0] == Approx(single_point.getX()));
+ REQUIRE(array[1] == Approx(single_point.getY()));
+ REQUIRE(array[2] == Approx(single_point.getZ()));
}
}
WHEN("I get the message topic") {
diff --git a/tests/test_point_stamped.cpp b/tests/test_point_stamped.cpp
index 7c95723..269a78e 100644
--- a/tests/test_point_stamped.cpp
+++ b/tests/test_point_stamped.cpp
@@ -11,26 +11,27 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
-#include "simple_msgs/header.h"
-#include "simple_msgs/point.h"
+
+#include "random_generators.hpp"
#include "simple_msgs/point_stamped.h"
+using namespace simple_tests;
+
// TEST FOR USING THE STAMPED POINT MESSAGE WRAPPER
SCENARIO("Using a PointStamped Message") {
- double double_1 = static_cast(rand()) / RAND_MAX;
- double double_2 = static_cast(rand()) / RAND_MAX;
- double double_3 = static_cast(rand()) / RAND_MAX;
- long long time = rand();
- int random_int = rand() / 100;
+ double double_1 = double_dist(generator);
+ double double_2 = double_dist(generator);
+ double double_3 = double_dist(generator);
+ long long time = static_cast(double_dist(generator));
+ int random_int = int_dist(generator);
std::string random_string = std::to_string(double_1);
simple_msgs::Point random_point(double_1, double_2, double_3);
simple_msgs::Point empty_point;
simple_msgs::Header empty_header;
simple_msgs::Header random_header(random_int, random_string, time);
+
// Test the constructors.
GIVEN("A PointStamped created from an empty constructor") {
simple_msgs::PointStamped empty_point_stamped{};
@@ -52,7 +53,7 @@ SCENARIO("Using a PointStamped Message") {
}
}
- // Testing copy constructors.
+ // Testing copy/move constructors.
GIVEN("A PointStamped") {
simple_msgs::PointStamped point_stamped{random_header, random_point};
WHEN("I copy-construct a PointStamped from its serialized data") {
@@ -72,7 +73,7 @@ SCENARIO("Using a PointStamped Message") {
}
}
- // Testing Copy-assignments.
+ // Testing copy/move assignments.
GIVEN("A PointStamped") {
simple_msgs::PointStamped point_stamped{random_header, random_point};
WHEN("I copy-assign from that PointStamped's buffer") {
@@ -126,7 +127,7 @@ SCENARIO("Using a PointStamped Message") {
}
}
- // Testing Topic and ostream
+ // Testing message topic and stream operator.
GIVEN("A point") {
simple_msgs::PointStamped point_stamped{};
WHEN("I get the message topic") {
diff --git a/tests/test_pose.cpp b/tests/test_pose.cpp
index a7da981..2974b6f 100644
--- a/tests/test_pose.cpp
+++ b/tests/test_pose.cpp
@@ -11,25 +11,26 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
-#include "simple_msgs/point.h"
+
+#include "random_generators.hpp"
#include "simple_msgs/pose.h"
-#include "simple_msgs/quaternion.h"
+
+using namespace simple_tests;
// TEST FOR USING THE POSE MESSAGE WRAPPER
SCENARIO("Using a Pose Message") {
- double double_1 = static_cast(rand()) / RAND_MAX;
- double double_2 = static_cast(rand()) / RAND_MAX;
- double double_3 = static_cast(rand()) / RAND_MAX;
- double double_4 = static_cast(rand()) / RAND_MAX;
- double double_5 = static_cast(rand()) / RAND_MAX;
- double double_6 = static_cast(rand()) / RAND_MAX;
- double double_7 = static_cast(rand()) / RAND_MAX;
+ double double_1 = double_dist(generator);
+ double double_2 = double_dist(generator);
+ double double_3 = double_dist(generator);
+ double double_4 = double_dist(generator);
+ double double_5 = double_dist(generator);
+ double double_6 = double_dist(generator);
+ double double_7 = double_dist(generator);
simple_msgs::Point point{double_1, double_2, double_3};
simple_msgs::Quaternion quaternion{double_4, double_5, double_6, double_7};
+
// Test the constructors.
GIVEN("A Pose created from an empty constructor") {
simple_msgs::Pose empty_pose{};
@@ -105,38 +106,44 @@ SCENARIO("Using a Pose Message") {
simple_msgs::Pose pose{point, quaternion};
WHEN("I set the X coordinate of the Pose's position") {
pose.getPosition().setX(double_7);
- THEN("The data Pose's position has the correct coordinate") { REQUIRE(pose.getPosition().getX() == double_7); }
+ THEN("The data Pose's position has the correct coordinate") {
+ REQUIRE(pose.getPosition().getX() == Approx(double_7));
+ }
}
WHEN("I set the Y coordinate of the Pose's position") {
pose.getPosition().setY(double_6);
- THEN("The data Pose's position has the correct coordinate") { REQUIRE(pose.getPosition().getY() == double_6); }
+ THEN("The data Pose's position has the correct coordinate") {
+ REQUIRE(pose.getPosition().getY() == Approx(double_6));
+ }
}
WHEN("I set the Z coordinate of the Pose's position") {
pose.getPosition().setZ(double_5);
- THEN("The data Pose's position has the correct coordinate") { REQUIRE(pose.getPosition().getZ() == double_5); }
+ THEN("The data Pose's position has the correct coordinate") {
+ REQUIRE(pose.getPosition().getZ() == Approx(double_5));
+ }
}
WHEN("I set the X coordinate of the Pose's quaternion") {
pose.getQuaternion().setX(double_1);
THEN("The data Pose's quaternion has the correct coordinate") {
- REQUIRE(pose.getQuaternion().getX() == double_1);
+ REQUIRE(pose.getQuaternion().getX() == Approx(double_1));
}
}
WHEN("I set the Y coordinate of the Pose's quaternion") {
pose.getQuaternion().setY(double_2);
THEN("The data Pose's quaternion has the correct coordinate") {
- REQUIRE(pose.getQuaternion().getY() == double_2);
+ REQUIRE(pose.getQuaternion().getY() == Approx(double_2));
}
}
WHEN("I set the Z coordinate of the Pose's quaternion") {
pose.getQuaternion().setZ(double_3);
THEN("The data Pose's quaternion has the correct coordinate") {
- REQUIRE(pose.getQuaternion().getZ() == double_3);
+ REQUIRE(pose.getQuaternion().getZ() == Approx(double_3));
}
}
WHEN("I set the W coordinate of the Pose's quaternion") {
pose.getQuaternion().setW(double_4);
THEN("The data Pose's quaternion has the correct coordinate") {
- REQUIRE(pose.getQuaternion().getW() == double_4);
+ REQUIRE(pose.getQuaternion().getW() == Approx(double_4));
}
}
}
@@ -166,7 +173,7 @@ SCENARIO("Using a Pose Message") {
}
}
- // Testing Topic
+ // Testing message topic and stream operator.
GIVEN("A point") {
simple_msgs::Pose pose{};
WHEN("I get the message topic") {
diff --git a/tests/test_pose_stamped.cpp b/tests/test_pose_stamped.cpp
index 1fe7a6f..fe10660 100644
--- a/tests/test_pose_stamped.cpp
+++ b/tests/test_pose_stamped.cpp
@@ -11,24 +11,23 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
-#include
#include
-#include "simple_msgs/header.h"
-#include "simple_msgs/pose.h"
+#include "random_generators.hpp"
#include "simple_msgs/pose_stamped.h"
+using namespace simple_tests;
+
// TEST FOR USING THE STAMPED POSE MESSAGE WRAPPER
SCENARIO("Using a PoseStamped Message") {
- double double_1 = static_cast(rand()) / RAND_MAX;
- double double_2 = static_cast(rand()) / RAND_MAX;
- double double_3 = static_cast(rand()) / RAND_MAX;
- double double_4 = static_cast(rand()) / RAND_MAX;
- double double_5 = static_cast(rand()) / RAND_MAX;
- double double_6 = static_cast(rand()) / RAND_MAX;
- double double_7 = static_cast(rand()) / RAND_MAX;
+ double double_1 = double_dist(generator);
+ double double_2 = double_dist(generator);
+ double double_3 = double_dist(generator);
+ double double_4 = double_dist(generator);
+ double double_5 = double_dist(generator);
+ double double_6 = double_dist(generator);
+ double double_7 = double_dist(generator);
long long time = rand();
int random_int = rand() / 100;
std::string random_string = std::to_string(double_1);
@@ -38,6 +37,7 @@ SCENARIO("Using a PoseStamped Message") {
simple_msgs::Pose empty_pose{};
simple_msgs::Header empty_header{};
simple_msgs::Header random_header{random_int, random_string, time};
+
// Test the constructors.
GIVEN("A PoseStamped created from an empty constructor") {
simple_msgs::PoseStamped empty_pose_stamped{};
@@ -133,7 +133,7 @@ SCENARIO("Using a PoseStamped Message") {
}
}
- // Testing Topic
+ // Testing message topic and stream operators.
GIVEN("A point") {
simple_msgs::PoseStamped pose_stamped{};
WHEN("I get the message topic") {
diff --git a/tests/test_pub_sub.cpp b/tests/test_pub_sub.cpp
index 8023d10..0491be8 100644
--- a/tests/test_pub_sub.cpp
+++ b/tests/test_pub_sub.cpp
@@ -11,311 +11,408 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
-#include
+#include
#include "simple/publisher.hpp"
#include "simple/subscriber.hpp"
-#include "test_utils.hpp"
+#include "test_utilities.hpp"
+
+using namespace simple_tests;
// Test: Publish and Subscribe to all data types.
+static constexpr size_t TEST_MESSAGES_TO_SEND = 10;
+static constexpr size_t WAIT_TIME_FOR_SUBSCRIBER = 2; //! In seconds.
+static constexpr size_t TIME_BETWEEN_MESSAGES = 10; //! In milliseconds.
+
SCENARIO("Publish and subscribe to a Bool message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5555");
- simple::Subscriber sub("tcp://localhost:5555", callbackFunctionConstBool);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstBool};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomBool();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
-
- if (running_bool) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_bool); }
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomBool();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
+ if (active_callback[MessageType::Bool]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_bool); }
}
}
}
- REQUIRE(num_received_bool == 10);
+ REQUIRE(received_messages[MessageType::Bool] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Int message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5556");
- simple::Subscriber sub("tcp://localhost:5556", callbackFunctionConstInt);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstInt};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomInt();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomInt();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_int) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_int); }
+ if (active_callback[MessageType::Int]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_int); }
}
}
}
- REQUIRE(num_received_int == 10);
+ REQUIRE(received_messages[MessageType::Int] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Float message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5557");
- simple::Subscriber sub("tcp://localhost:5557", callbackFunctionConstFloat);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstFloat};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomFloat();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomFloat();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_float) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_float); }
+ if (active_callback[MessageType::Float]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_float); }
}
}
}
- REQUIRE(num_received_float == 10);
+ REQUIRE(received_messages[MessageType::Float] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Double message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5558");
- simple::Subscriber sub("tcp://localhost:5558", callbackFunctionConstDouble);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstDouble};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomDouble();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomDouble();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_double) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_double); }
+ if (active_callback[MessageType::Double]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_double); }
}
}
}
- REQUIRE(num_received_double == 10);
+ REQUIRE(received_messages[MessageType::Double] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a String message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5559");
- simple::Subscriber sub("tcp://localhost:5559", callbackFunctionConstString);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstString};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomString();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomString();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_string) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_string); }
+ if (active_callback[MessageType::String]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_string); }
}
}
}
- REQUIRE(num_received_string == 10);
+ REQUIRE(received_messages[MessageType::String] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Header message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5560");
- simple::Subscriber sub("tcp://localhost:5560", callbackFunctionConstHeader);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstHeader};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomHeader();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomHeader();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_header) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_header); }
+ if (active_callback[MessageType::Header]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_header); }
}
}
}
- REQUIRE(num_received_header == 10);
+ REQUIRE(received_messages[MessageType::Header] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Point message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5561");
- simple::Subscriber sub("tcp://localhost:5561", callbackFunctionConstPoint);
- std::this_thread::sleep_for(std::chrono::seconds(5));
+ simple::Publisher pub{publisher_address};
+ simple::Subscriber sub{subscriber_address, callbackFunctionConstPoint};
+ std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME_FOR_SUBSCRIBER));
WHEN("A publisher publishes data") {
- for (int i = 0; i < 10; ++i) {
- auto p = createRandomPoint();
- pub.publish(p);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ for (size_t i = 0; i < TEST_MESSAGES_TO_SEND; ++i) {
+ auto message = createRandomPoint();
+ pub.publish(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_MESSAGES));
- if (running_point) {
- THEN("The data received is the same as the one sent") { REQUIRE(p == received_point); }
+ if (active_callback[MessageType::Point]) {
+ THEN("The data received is the same as the one sent") { REQUIRE(message == received_point); }
}
}
}
- REQUIRE(num_received_point == 10);
+ REQUIRE(received_messages[MessageType::Point] == TEST_MESSAGES_TO_SEND);
}
}
SCENARIO("Publish and subscribe to a Quaternion message.") {
+ const auto port = generatePort();
+ const auto publisher_address = "tcp://*:" + std::to_string(port);
+ const auto subscriber_address = "tcp://localhost:" + std::to_string(port);
GIVEN("An instance of a subscriber.") {
- simple::Publisher pub("tcp://*:5562");
- simple::Subscriber