diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp index 4a14aa7fce29f5262f3d4eeb7080f2d6986c27f2..d7b5429947d56515f9c21fa32deb1c0fa59a81c4 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp @@ -20,7 +20,9 @@ * GNU General Public License */ +#include "ArmarXCore/core/exceptions/LocalException.h" #include <RobotAPI/interface/armem/query.h> +#include <boost/test/tools/old/interface.hpp> #define BOOST_TEST_MODULE RobotAPI::ArmarXLibraries::armem #define ARMARX_BOOST_TEST @@ -337,6 +339,11 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeTime_2) /* TimeApprox */ +/** + * @brief Lookup between elements. No range specified. + * + * Desired behavior: Return elements before and after timestamp. + */ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_no_limit) { BOOST_REQUIRE_EQUAL(entity.size(), 5); @@ -358,7 +365,11 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_no_limit) } - +/** + * @brief Lookup between elements. Range is OK. + * + * Desired behavior: Return elements before and after timestamp. + */ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_600) { BOOST_REQUIRE_EQUAL(entity.size(), 5); @@ -380,7 +391,11 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_600) } - +/** + * @brief Lookup between elements. Range is too small. + * + * Desired behavior: Return empty list. + */ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_too_small) { BOOST_REQUIRE_EQUAL(entity.size(), 5); @@ -395,7 +410,11 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_too_small) } - +/** + * @brief Lookup between elements. Only next element is in range. + * + * Desired behavior: Return only element after query timestamp. + */ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_next) { BOOST_REQUIRE_EQUAL(entity.size(), 5); @@ -414,9 +433,13 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_next) BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end()); } - } +/** + * @brief Lookup between elements. Only previous element is in range. + * + * Desired behavior: Return only element before query timestamp. + */ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_previous) { BOOST_REQUIRE_EQUAL(entity.size(), 5); @@ -435,7 +458,97 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_previous) BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end()); } +} + +/** + * @brief Lookup with perfect match. + * + * Desired behavior: Return only element matching timestamp exactly. + */ +BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_perfect_match) +{ + BOOST_REQUIRE_EQUAL(entity.size(), 5); + addResults(query::entity::TimeApprox{ 3000, -1}); + BOOST_REQUIRE_EQUAL(results.size(), 2); + + for (const auto& result : results) + { + std::vector<armem::Time> times = simox::alg::get_keys(result.history()); + BOOST_REQUIRE_EQUAL(times.size(), 1); + + std::vector<armem::Time> expected + { + armem::Time::microSeconds(3000) + }; + + BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end()); + } +} +/** + * @brief Invalid lookup into the past. + * + * Desired behavior: Return empty list. + */ +BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_past) +{ + BOOST_REQUIRE_EQUAL(entity.size(), 5); + addResults(query::entity::TimeApprox{ 1, 1}); + BOOST_REQUIRE_EQUAL(results.size(), 2); + + for (const auto& result : results) + { + std::vector<armem::Time> times = simox::alg::get_keys(result.history()); + BOOST_REQUIRE(times.empty()); + } +} + +/** + * @brief Invalid lookup into the future. + * + * Desired behavior: Return empty list. + */ +BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future) +{ + BOOST_REQUIRE_EQUAL(entity.size(), 5); + addResults(query::entity::TimeApprox{ 10'000, 1}); + BOOST_REQUIRE_EQUAL(results.size(), 2); + + for (const auto& result : results) + { + std::vector<armem::Time> times = simox::alg::get_keys(result.history()); + BOOST_REQUIRE(times.empty()); + } +} + +/** + * @brief Lookup into the future, but still considered valid as time range is not set. + * + * Desired behavior: Return most recent element in history. + */ +BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future_valid) +{ + BOOST_REQUIRE_EQUAL(entity.size(), 5); + addResults(query::entity::TimeApprox{ 10'000, -1}); + BOOST_REQUIRE_EQUAL(results.size(), 2); + + for (const auto& result : results) + { + std::vector<armem::Time> times = simox::alg::get_keys(result.history()); + BOOST_REQUIRE_EQUAL(times.size(), 1); + + std::vector<armem::Time> expected + { + armem::Time::microSeconds(5'000) + }; + + BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end()); + } +} + +BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_invalid_timestamp) +{ + BOOST_REQUIRE_THROW(addResults(query::entity::TimeApprox{ -1, 1}), ::armarx::LocalException); }