#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include <edgefirst/schemas.hpp>
namespace ef = edgefirst::schemas;
TEST_CASE("Header encode+view roundtrip", "[buffer_backed][header]") {
auto hdr = ef::Header::encode({1234, 5678}, "test_frame");
REQUIRE(hdr.has_value());
CHECK(hdr->stamp().sec == 1234);
CHECK(hdr->stamp().nanosec == 5678);
CHECK(hdr->frame_id() == "test_frame");
CHECK(!hdr->as_cdr().empty());
}
TEST_CASE("Header release transfers byte ownership", "[buffer_backed][header][release]") {
auto hdr = ef::Header::encode({1234, 5678}, "release_test");
REQUIRE(hdr.has_value());
auto cdr = hdr->as_cdr();
const std::uint8_t* expected_data = cdr.data();
const std::size_t expected_size = cdr.size();
auto released = std::move(*hdr).release();
CHECK(released.data == expected_data);
CHECK(released.size == expected_size);
ros_bytes_free(released.data, released.size);
}
TEST_CASE("Header double-release yields empty buffer on second call",
"[buffer_backed][header][release]") {
auto hdr = ef::Header::encode({1, 2}, "cam");
REQUIRE(hdr.has_value());
auto r1 = std::move(*hdr).release();
CHECK(r1.data != nullptr);
CHECK(r1.size > 0);
auto hdr2 = ef::Header::encode({3, 4}, "cam2");
REQUIRE(hdr2.has_value());
auto r2 = std::move(*hdr2).release();
CHECK(r2.data != nullptr);
ros_bytes_free(r1.data, r1.size);
ros_bytes_free(r2.data, r2.size);
}
TEST_CASE("Image release transfers large pixel buffer ownership",
"[buffer_backed][image][release]") {
std::vector<std::uint8_t> pixels(640 * 480 * 3, 0xA5);
auto img = ef::Image::encode(
ef::Time{1, 2}, "cam", 480, 640, "rgb8", false,
640 * 3, ef::span<const std::uint8_t>{pixels.data(), pixels.size()});
REQUIRE(img.has_value());
const auto cdr = img->as_cdr();
const std::uint8_t* expected_data = cdr.data();
const std::size_t expected_size = cdr.size();
auto released = std::move(*img).release();
CHECK(released.data == expected_data);
CHECK(released.size == expected_size);
CHECK(released.size > pixels.size());
ros_bytes_free(released.data, released.size);
}
TEST_CASE("Mask release works on OwnedBaseNoCdr derivatives",
"[buffer_backed][mask][release]") {
std::vector<std::uint8_t> mdata{1, 2, 3, 4, 5, 6, 7, 8};
auto mask = ef::Mask::encode(
2, 4, static_cast<std::uint32_t>(mdata.size()),
"mono8",
ef::span<const std::uint8_t>{mdata.data(), mdata.size()},
true);
REQUIRE(mask.has_value());
auto released = std::move(*mask).release();
CHECK(released.data != nullptr);
CHECK(released.size > 0);
ros_bytes_free(released.data, released.size);
}
TEST_CASE("Header encode empty frame_id", "[buffer_backed][header]") {
auto hdr = ef::Header::encode({0, 0}, "");
REQUIRE(hdr.has_value());
CHECK(hdr->frame_id() == "");
CHECK(hdr->stamp().sec == 0);
}
TEST_CASE("HeaderView from_cdr error on empty span", "[buffer_backed][header]") {
auto v = ef::HeaderView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("HeaderView from_cdr success + accessors", "[buffer_backed][header]") {
auto hdr = ef::Header::encode({10, 20}, "cam");
REQUIRE(hdr.has_value());
auto cdr = hdr->as_cdr();
auto v = ef::HeaderView::from_cdr(cdr);
REQUIRE(v.has_value());
CHECK(v->stamp().sec == 10);
CHECK(v->stamp().nanosec == 20);
CHECK(v->frame_id() == "cam");
CHECK(!v->as_cdr().empty());
}
TEST_CASE("HeaderView move semantics", "[buffer_backed][header]") {
auto hdr = ef::Header::encode({1, 2}, "cam");
REQUIRE(hdr.has_value());
auto cdr = hdr->as_cdr();
auto v1 = ef::HeaderView::from_cdr(cdr);
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "cam");
CHECK(v2.stamp().sec == 1);
}
TEST_CASE("Header move semantics", "[buffer_backed][header]") {
auto h1 = ef::Header::encode({99, 0}, "lidar");
REQUIRE(h1.has_value());
auto h2 = std::move(*h1);
CHECK(h2.frame_id() == "lidar");
CHECK(h2.stamp().sec == 99);
CHECK(!h2.as_cdr().empty());
}
TEST_CASE("CompressedImage encode+view roundtrip", "[buffer_backed][compressed_image]") {
const std::uint8_t pixels[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x42};
ef::span<const std::uint8_t> data_span{pixels, sizeof(pixels)};
auto img = ef::CompressedImage::encode({100, 200}, "camera", "jpeg", data_span);
REQUIRE(img.has_value());
CHECK(img->stamp().sec == 100);
CHECK(img->stamp().nanosec == 200);
CHECK(img->frame_id() == "camera");
CHECK(img->format() == "jpeg");
CHECK(img->data().size() == 5);
CHECK(!img->as_cdr().empty());
}
TEST_CASE("CompressedImageView from_cdr error on empty span", "[buffer_backed][compressed_image]") {
auto v = ef::CompressedImageView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("CompressedImageView from_cdr + move", "[buffer_backed][compressed_image]") {
const std::uint8_t px[] = {1, 2, 3};
auto img = ef::CompressedImage::encode({5, 6}, "front", "png",
ef::span<const std::uint8_t>{px, 3});
REQUIRE(img.has_value());
auto cdr = img->as_cdr();
auto v1 = ef::CompressedImageView::from_cdr(cdr);
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.format() == "png");
CHECK(v2.frame_id() == "front");
CHECK(v2.data().size() == 3);
}
TEST_CASE("CompressedImage move semantics", "[buffer_backed][compressed_image]") {
const std::uint8_t px[] = {0xAB};
auto i1 = ef::CompressedImage::encode({0, 0}, "back", "h264",
ef::span<const std::uint8_t>{px, 1});
REQUIRE(i1.has_value());
auto i2 = std::move(*i1);
CHECK(i2.format() == "h264");
CHECK(!i2.as_cdr().empty());
}
static constexpr std::uint8_t kGoldenImuBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7b,0x14,0xae,0x47,0xe1,0x7a,0x84,0x3f,0x7b,0x14,0xae,0x47,
0xe1,0x7a,0x94,0x3f,0xb8,0x1e,0x85,0xeb,0x51,0xb8,0x9e,0x3f,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1f,0x85,0xeb,0x51,0xb8,0x9e,0x23,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
};
static constexpr std::uint8_t kGoldenNavSatFixBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x9c,0x33,0xa2,0xb4,0x37,0xc0,0x46,0x40,0x55,0xc1,0xa8,0xa4,
0x4e,0x64,0x52,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x02,
};
static constexpr std::uint8_t kGoldenCameraInfoBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0xe0,0x01,0x00,0x00,
0x80,0x02,0x00,0x00,0x0a,0x00,0x00,0x00,0x70,0x6c,0x75,0x6d,0x62,0x5f,0x62,0x6f,
0x62,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0x99,0x99,0x99,
0x99,0x99,0xb9,0x3f,0x9a,0x99,0x99,0x99,0x99,0x99,0xc9,0xbf,0xfc,0xa9,0xf1,0xd2,
0x4d,0x62,0x50,0x3f,0xfc,0xa9,0xf1,0xd2,0x4d,0x62,0x60,0x3f,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x6e,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0x7f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x6e,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xe0,0x01,0x00,0x00,0x80,0x02,0x00,0x00,0x00,
};
static constexpr std::uint8_t kGoldenTransformStampedBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x0c,0x00,0x00,0x00,
0x63,0x68,0x69,0x6c,0x64,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x3f,
};
static constexpr std::uint8_t kGoldenLocalTimeBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0xe9,0x07,0x06,0x0f,
0xc0,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0xfe,
};
static constexpr std::uint8_t kGoldenTrackBytes[] = {
0x00,0x01,0x00,0x00,0x03,0x00,0x00,0x00,0x74,0x31,0x00,0x00,0x05,0x00,0x00,0x00,
0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
static constexpr std::uint8_t kGoldenSimpleDetectBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0xd2,0x02,0x96,0x49,
0x15,0xcd,0x5b,0x07,0x00,0x00,0x00,0x00,0x40,0x42,0x0f,0x00,0x00,0x00,0x00,0x00,
0x80,0x84,0x1e,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,
0xcd,0xcc,0xcc,0x3d,0xcd,0xcc,0x4c,0x3e,0x04,0x00,0x00,0x00,0x63,0x61,0x72,0x00,
0x48,0xe1,0x7a,0x3f,0x00,0x00,0x20,0x41,0x00,0x00,0xa0,0x40,0x03,0x00,0x00,0x00,
0x74,0x31,0x00,0x00,0x05,0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
static constexpr std::uint8_t kGoldenModelBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0x42,0x0f,0x00,0x00,0x00,0x00,0x00,0x40,0x4b,0x4c,0x00,0x00,0x00,0x00,0x00,
0x20,0xa1,0x07,0x00,0x00,0x00,0x00,0x00,0x40,0x0d,0x03,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0xcd,0xcc,0xcc,0x3d,0xcd,0xcc,0x4c,0x3e,
0x04,0x00,0x00,0x00,0x63,0x61,0x72,0x00,0x48,0xe1,0x7a,0x3f,0x00,0x00,0x20,0x41,
0x00,0x00,0xa0,0x40,0x03,0x00,0x00,0x00,0x74,0x31,0x00,0x00,0x05,0x00,0x00,0x00,
0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x08,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x01,
};
static constexpr std::uint8_t kGoldenModelInfoBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x04,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x80,0x02,0x00,0x00,
0x08,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x54,0x00,0x00,0x00,
0xd0,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
0x70,0x65,0x72,0x73,0x6f,0x6e,0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x61,0x72,0x00,
0x08,0x00,0x00,0x00,0x62,0x69,0x63,0x79,0x63,0x6c,0x65,0x00,0x11,0x00,0x00,0x00,
0x6f,0x62,0x6a,0x65,0x63,0x74,0x5f,0x64,0x65,0x74,0x65,0x63,0x74,0x69,0x6f,0x6e,
0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x44,0x65,0x65,0x70,0x56,0x69,0x65,0x77,
0x52,0x54,0x00,0x00,0x08,0x00,0x00,0x00,0x79,0x6f,0x6c,0x6f,0x76,0x38,0x6e,0x00,
};
static constexpr std::uint8_t kGoldenRadarCubeBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0xc0,0xba,0x8a,0x3c,
0xd5,0x62,0x04,0x00,0x04,0x00,0x00,0x00,0x06,0x01,0x05,0x02,0x04,0x00,0x00,0x00,
0x02,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x20,0x40,0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x3f,0x20,0x00,0x00,0x00,
0x00,0x00,0x64,0x00,0xc8,0x00,0x2c,0x01,0x90,0x01,0xf4,0x01,0x58,0x02,0xbc,0x02,
0x20,0x03,0x84,0x03,0xe8,0x03,0x4c,0x04,0xb0,0x04,0x14,0x05,0x78,0x05,0xdc,0x05,
0x40,0x06,0xa4,0x06,0x08,0x07,0x6c,0x07,0xd0,0x07,0x34,0x08,0x98,0x08,0xfc,0x08,
0x60,0x09,0xc4,0x09,0x28,0x0a,0x8c,0x0a,0xf0,0x0a,0x54,0x0b,0xb8,0x0b,0x1c,0x0c,
0x00,
};
static constexpr std::uint8_t kGoldenRadarInfoBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x06,0x00,0x00,0x00,
0x37,0x37,0x47,0x48,0x7a,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x77,0x69,0x64,0x65,
0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x6f,0x66,0x66,0x00,0x05,0x00,0x00,0x00,
0x68,0x69,0x67,0x68,0x00,0x01,
};
static constexpr std::uint8_t kGoldenPointCloud2Bytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x01,0x00,0x00,0x00,
0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
0x79,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0x02,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x40,
0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x40,
0x00,0x00,0x40,0x40,0x00,0x00,0x80,0x40,0x00,0x00,0x40,0x40,0x00,0x00,0x80,0x40,
0x00,0x00,0xa0,0x40,0x01,
};
static constexpr std::uint8_t kGoldenBoxBytes[] = {
0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0xcd,0xcc,0xcc,0x3d,
0xcd,0xcc,0x4c,0x3e,0x04,0x00,0x00,0x00,0x63,0x61,0x72,0x00,0x48,0xe1,0x7a,0x3f,
0x00,0x00,0x20,0x41,0x00,0x00,0xa0,0x40,0x03,0x00,0x00,0x00,0x74,0x31,0x00,0x00,
0x05,0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
TEST_CASE("ImuView error paths", "[buffer_backed][imu]") {
auto v = ef::ImuView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("ImuView move semantics", "[buffer_backed][imu]") {
auto v1 = ef::ImuView::from_cdr(
ef::span<const std::uint8_t>{kGoldenImuBytes, sizeof(kGoldenImuBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->stamp().sec == 1234567890u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.stamp().sec == 1234567890u);
CHECK(v2.orientation().w == Approx(1.0));
auto v3 = ef::ImuView::from_cdr(
ef::span<const std::uint8_t>{kGoldenImuBytes, sizeof(kGoldenImuBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.orientation().w == Approx(1.0));
}
TEST_CASE("NavSatFixView error paths", "[buffer_backed][nav_sat_fix]") {
auto v = ef::NavSatFixView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("NavSatFixView move semantics", "[buffer_backed][nav_sat_fix]") {
auto v1 = ef::NavSatFixView::from_cdr(
ef::span<const std::uint8_t>{kGoldenNavSatFixBytes, sizeof(kGoldenNavSatFixBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.latitude() == Approx(45.5017).epsilon(0.0001));
CHECK(v2.longitude() == Approx(-73.5673).epsilon(0.0001));
CHECK(v2.altitude() == Approx(100.0).epsilon(0.001));
auto v3 = ef::NavSatFixView::from_cdr(
ef::span<const std::uint8_t>{kGoldenNavSatFixBytes, sizeof(kGoldenNavSatFixBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.latitude() == Approx(45.5017).epsilon(0.0001));
}
TEST_CASE("CameraInfoView error paths", "[buffer_backed][camera_info]") {
auto v = ef::CameraInfoView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("CameraInfoView move semantics", "[buffer_backed][camera_info]") {
auto v1 = ef::CameraInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenCameraInfoBytes, sizeof(kGoldenCameraInfoBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->height() == 480u);
CHECK(v1->width() == 640u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.height() == 480u);
CHECK(v2.width() == 640u);
auto v3 = ef::CameraInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenCameraInfoBytes, sizeof(kGoldenCameraInfoBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.height() == 480u);
}
TEST_CASE("TransformStampedView error paths", "[buffer_backed][transform_stamped]") {
auto v = ef::TransformStampedView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("TransformStampedView move semantics", "[buffer_backed][transform_stamped]") {
auto v1 = ef::TransformStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTransformStampedBytes,
sizeof(kGoldenTransformStampedBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->child_frame_id() == "child_frame");
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.child_frame_id() == "child_frame");
auto v3 = ef::TransformStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTransformStampedBytes,
sizeof(kGoldenTransformStampedBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.child_frame_id() == "child_frame");
}
TEST_CASE("CompressedVideo encode+view roundtrip", "[buffer_backed][compressed_video]") {
const std::uint8_t vdata[] = {0x00, 0x00, 0x00, 0x01, 0x67};
ef::span<const std::uint8_t> data_span{vdata, sizeof(vdata)};
auto vid = ef::CompressedVideo::encode({500, 0}, "camera_front", data_span, "h264");
REQUIRE(vid.has_value());
CHECK(vid->stamp().sec == 500);
CHECK(vid->stamp().nanosec == 0);
CHECK(vid->frame_id() == "camera_front");
CHECK(vid->format() == "h264");
CHECK(vid->data().size() == 5);
CHECK(!vid->as_cdr().empty());
}
TEST_CASE("CompressedVideoView from_cdr error on empty span", "[buffer_backed][compressed_video]") {
auto v = ef::CompressedVideoView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("CompressedVideoView from_cdr + move", "[buffer_backed][compressed_video]") {
const std::uint8_t vd[] = {0x01, 0x02};
auto vid = ef::CompressedVideo::encode({7, 8}, "back_cam",
ef::span<const std::uint8_t>{vd, 2}, "h265");
REQUIRE(vid.has_value());
auto cdr = vid->as_cdr();
auto v1 = ef::CompressedVideoView::from_cdr(cdr);
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.format() == "h265");
CHECK(v2.frame_id() == "back_cam");
CHECK(v2.data().size() == 2);
}
TEST_CASE("CompressedVideo move semantics", "[buffer_backed][compressed_video]") {
const std::uint8_t vd[] = {0xFF};
auto v1 = ef::CompressedVideo::encode({0, 0}, "side",
ef::span<const std::uint8_t>{vd, 1}, "av1");
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.format() == "av1");
CHECK(!v2.as_cdr().empty());
}
TEST_CASE("Mask encode+view roundtrip", "[buffer_backed][mask]") {
const std::uint8_t mdata[] = {0x01, 0x00, 0x01, 0xFF};
ef::span<const std::uint8_t> data_span{mdata, sizeof(mdata)};
auto mask = ef::Mask::encode(2, 2, 4, "mono8", data_span, false);
REQUIRE(mask.has_value());
CHECK(mask->height() == 2);
CHECK(mask->width() == 2);
CHECK(mask->length() == 4);
CHECK(mask->encoding() == "mono8");
CHECK(mask->data().size() == 4);
CHECK(mask->boxed() == false);
CHECK(!mask->as_cdr().empty());
}
TEST_CASE("Mask encode boxed=true", "[buffer_backed][mask]") {
const std::uint8_t mdata[] = {0x01};
auto mask = ef::Mask::encode(1, 1, 1, "mono8",
ef::span<const std::uint8_t>{mdata, 1}, true);
REQUIRE(mask.has_value());
CHECK(mask->boxed() == true);
}
TEST_CASE("MaskView from_cdr error on empty span", "[buffer_backed][mask]") {
auto v = ef::MaskView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("MaskView from_cdr success + move", "[buffer_backed][mask]") {
const std::uint8_t mdata[] = {0xAA, 0xBB};
auto mask = ef::Mask::encode(1, 2, 2, "mono8",
ef::span<const std::uint8_t>{mdata, 2}, false);
REQUIRE(mask.has_value());
auto cdr = mask->as_cdr();
auto v1 = ef::MaskView::from_cdr(cdr);
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.height() == 1);
CHECK(v2.width() == 2);
CHECK(v2.encoding() == "mono8");
}
TEST_CASE("Mask move semantics", "[buffer_backed][mask]") {
const std::uint8_t mdata[] = {0x01, 0x02, 0x03};
auto m1 = ef::Mask::encode(1, 3, 3, "mono8",
ef::span<const std::uint8_t>{mdata, 3}, false);
REQUIRE(m1.has_value());
auto m2 = std::move(*m1);
CHECK(m2.height() == 1);
CHECK(m2.width() == 3);
CHECK(!m2.as_cdr().empty());
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
TEST_CASE("DmaBuffer encode+view roundtrip", "[buffer_backed][dmabuffer]") {
auto buf = ef::DmaBuffer::encode(
{1000, 2000}, "imx8",
1234, 5,
1920, 1080,
1920, 0x32315659, 2073600);
REQUIRE(buf.has_value());
CHECK(buf->stamp().sec == 1000);
CHECK(buf->stamp().nanosec == 2000);
CHECK(buf->frame_id() == "imx8");
CHECK(buf->pid() == 1234u);
CHECK(buf->fd() == 5);
CHECK(buf->width() == 1920u);
CHECK(buf->height() == 1080u);
CHECK(buf->stride() == 1920u);
CHECK(buf->fourcc() == 0x32315659u);
CHECK(buf->length() == 2073600u);
CHECK(!buf->as_cdr().empty());
}
TEST_CASE("DmaBufferView from_cdr error on empty span", "[buffer_backed][dmabuffer]") {
auto v = ef::DmaBufferView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("DmaBufferView from_cdr + move", "[buffer_backed][dmabuffer]") {
auto buf = ef::DmaBuffer::encode(
{0, 0}, "cam",
0u, 3, 640u, 480u, 640u, 0u, 307200u);
REQUIRE(buf.has_value());
auto cdr = buf->as_cdr();
auto v1 = ef::DmaBufferView::from_cdr(cdr);
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.fd() == 3);
CHECK(v2.width() == 640u);
CHECK(v2.height() == 480u);
}
TEST_CASE("DmaBuffer move semantics", "[buffer_backed][dmabuffer]") {
auto b1 = ef::DmaBuffer::encode(
{42, 0}, "lidar",
0u, -1, 0u, 0u, 0u, 0u, 0u);
REQUIRE(b1.has_value());
auto b2 = std::move(*b1);
CHECK(b2.frame_id() == "lidar");
CHECK(b2.fd() == -1);
CHECK(!b2.as_cdr().empty());
}
TEST_CASE("LocalTimeView error paths", "[buffer_backed][local_time]") {
auto v = ef::LocalTimeView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("LocalTimeView move semantics", "[buffer_backed][local_time]") {
auto v1 = ef::LocalTimeView::from_cdr(
ef::span<const std::uint8_t>{kGoldenLocalTimeBytes, sizeof(kGoldenLocalTimeBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->stamp().sec == 1234567890u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.stamp().sec == 1234567890u);
auto v3 = ef::LocalTimeView::from_cdr(
ef::span<const std::uint8_t>{kGoldenLocalTimeBytes, sizeof(kGoldenLocalTimeBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.stamp().sec == 1234567890u);
}
TEST_CASE("TrackView error paths", "[buffer_backed][track]") {
auto v = ef::TrackView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("TrackView move semantics", "[buffer_backed][track]") {
auto v1 = ef::TrackView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTrackBytes, sizeof(kGoldenTrackBytes)});
REQUIRE(v1.has_value());
CHECK(v1->id() == "t1");
CHECK(v1->lifetime() == 5);
auto v2 = std::move(*v1);
CHECK(v2.id() == "t1");
CHECK(v2.lifetime() == 5);
auto v3 = ef::TrackView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTrackBytes, sizeof(kGoldenTrackBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.id() == "t1");
CHECK(v2.lifetime() == 5);
}
TEST_CASE("DetectView move semantics", "[buffer_backed][detect]") {
auto v1 = ef::DetectView::from_cdr(
ef::span<const std::uint8_t>{kGoldenSimpleDetectBytes, sizeof(kGoldenSimpleDetectBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->boxes_len() == 1u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.boxes_len() == 1u);
auto v3 = ef::DetectView::from_cdr(
ef::span<const std::uint8_t>{kGoldenSimpleDetectBytes, sizeof(kGoldenSimpleDetectBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.boxes_len() == 1u);
}
TEST_CASE("ModelView move semantics", "[buffer_backed][model]") {
auto v1 = ef::ModelView::from_cdr(
ef::span<const std::uint8_t>{kGoldenModelBytes, sizeof(kGoldenModelBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->boxes_len() == 1u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.boxes_len() == 1u);
auto v3 = ef::ModelView::from_cdr(
ef::span<const std::uint8_t>{kGoldenModelBytes, sizeof(kGoldenModelBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.boxes_len() == 1u);
}
TEST_CASE("ModelInfoView move semantics", "[buffer_backed][model_info]") {
auto v1 = ef::ModelInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenModelInfoBytes, sizeof(kGoldenModelInfoBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->labels_len() == 3u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.labels_len() == 3u);
CHECK(v2.label(0) == "person");
auto v3 = ef::ModelInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenModelInfoBytes, sizeof(kGoldenModelInfoBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.labels_len() == 3u);
}
TEST_CASE("RadarCubeView move semantics", "[buffer_backed][radar_cube]") {
auto v1 = ef::RadarCubeView::from_cdr(
ef::span<const std::uint8_t>{kGoldenRadarCubeBytes, sizeof(kGoldenRadarCubeBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->timestamp() == 1234567890123456ull);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.timestamp() == 1234567890123456ull);
auto v3 = ef::RadarCubeView::from_cdr(
ef::span<const std::uint8_t>{kGoldenRadarCubeBytes, sizeof(kGoldenRadarCubeBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.timestamp() == 1234567890123456ull);
}
TEST_CASE("RadarInfoView move semantics", "[buffer_backed][radar_info]") {
auto v1 = ef::RadarInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenRadarInfoBytes, sizeof(kGoldenRadarInfoBytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->center_frequency() == "77GHz");
CHECK(v1->frequency_sweep() == "wide");
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.center_frequency() == "77GHz");
CHECK(v2.frequency_sweep() == "wide");
CHECK(v2.range_toggle() == "off");
CHECK(v2.detection_sensitivity() == "high");
CHECK(v2.cube() == true);
auto v3 = ef::RadarInfoView::from_cdr(
ef::span<const std::uint8_t>{kGoldenRadarInfoBytes, sizeof(kGoldenRadarInfoBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.center_frequency() == "77GHz");
}
TEST_CASE("PointCloud2View move semantics", "[buffer_backed][pointcloud2]") {
auto v1 = ef::PointCloud2View::from_cdr(
ef::span<const std::uint8_t>{kGoldenPointCloud2Bytes, sizeof(kGoldenPointCloud2Bytes)});
REQUIRE(v1.has_value());
CHECK(v1->frame_id() == "test_frame");
CHECK(v1->height() == 1u);
CHECK(v1->width() == 4u);
CHECK(v1->fields_len() == 3u);
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.height() == 1u);
CHECK(v2.width() == 4u);
CHECK(v2.fields_len() == 3u);
auto v3 = ef::PointCloud2View::from_cdr(
ef::span<const std::uint8_t>{kGoldenPointCloud2Bytes, sizeof(kGoldenPointCloud2Bytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.frame_id() == "test_frame");
CHECK(v2.fields_len() == 3u);
}
TEST_CASE("BoxView move semantics", "[buffer_backed][box]") {
auto v1 = ef::BoxView::from_cdr(
ef::span<const std::uint8_t>{kGoldenBoxBytes, sizeof(kGoldenBoxBytes)});
REQUIRE(v1.has_value());
CHECK(v1->label() == "car");
CHECK(v1->track_id() == "t1");
CHECK(v1->score() == Approx(0.98f).epsilon(0.01f));
auto v2 = std::move(*v1);
CHECK(v2.label() == "car");
CHECK(v2.track_id() == "t1");
CHECK(v2.score() == Approx(0.98f).epsilon(0.01f));
CHECK(v2.track_lifetime() == 5);
auto v3 = ef::BoxView::from_cdr(
ef::span<const std::uint8_t>{kGoldenBoxBytes, sizeof(kGoldenBoxBytes)});
REQUIRE(v3.has_value());
v2 = std::move(*v3);
CHECK(v2.label() == "car");
CHECK(v2.track_id() == "t1");
}
TEST_CASE("BoxView track_created accessor", "[buffer_backed][box][track_created]") {
auto v = ef::BoxView::from_cdr(
ef::span<const std::uint8_t>{kGoldenBoxBytes, sizeof(kGoldenBoxBytes)});
REQUIRE(v.has_value());
auto tc = v->track_created();
CHECK(tc.sec == 95);
CHECK(tc.nanosec == 0u);
}
static constexpr std::uint8_t kGoldenTwistStampedBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
TEST_CASE("TwistStampedView error paths", "[buffer_backed][twist_stamped]") {
auto v = ef::TwistStampedView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("TwistStampedView happy path", "[buffer_backed][twist_stamped]") {
auto v = ef::TwistStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTwistStampedBytes,
sizeof(kGoldenTwistStampedBytes)});
REQUIRE(v.has_value());
CHECK(v->stamp().sec == 1234567890);
CHECK(v->stamp().nanosec == 123456789u);
CHECK(v->frame_id() == "test_frame");
}
TEST_CASE("TwistStampedView move semantics", "[buffer_backed][twist_stamped]") {
auto v1 = ef::TwistStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenTwistStampedBytes,
sizeof(kGoldenTwistStampedBytes)});
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
}
static constexpr std::uint8_t kGoldenAccelStampedBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
TEST_CASE("AccelStampedView error paths", "[buffer_backed][accel_stamped]") {
auto v = ef::AccelStampedView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("AccelStampedView happy path", "[buffer_backed][accel_stamped]") {
auto v = ef::AccelStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenAccelStampedBytes,
sizeof(kGoldenAccelStampedBytes)});
REQUIRE(v.has_value());
CHECK(v->stamp().sec == 1234567890);
CHECK(v->stamp().nanosec == 123456789u);
CHECK(v->frame_id() == "test_frame");
}
TEST_CASE("AccelStampedView move semantics", "[buffer_backed][accel_stamped]") {
auto v1 = ef::AccelStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenAccelStampedBytes,
sizeof(kGoldenAccelStampedBytes)});
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
}
static constexpr std::uint8_t kGoldenPointStampedBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x40,
};
TEST_CASE("PointStampedView error paths", "[buffer_backed][point_stamped]") {
auto v = ef::PointStampedView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("PointStampedView happy path", "[buffer_backed][point_stamped]") {
auto v = ef::PointStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenPointStampedBytes,
sizeof(kGoldenPointStampedBytes)});
REQUIRE(v.has_value());
CHECK(v->stamp().sec == 1234567890);
CHECK(v->stamp().nanosec == 123456789u);
CHECK(v->frame_id() == "test_frame");
}
TEST_CASE("PointStampedView move semantics", "[buffer_backed][point_stamped]") {
auto v1 = ef::PointStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenPointStampedBytes,
sizeof(kGoldenPointStampedBytes)});
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
}
static constexpr std::uint8_t kGoldenInertiaStampedBytes[] = {
0x00,0x01,0x00,0x00,0xd2,0x02,0x96,0x49,0x15,0xcd,0x5b,0x07,0x0b,0x00,0x00,0x00,
0x74,0x65,0x73,0x74,0x5f,0x66,0x72,0x61,0x6d,0x65,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
TEST_CASE("InertiaStampedView error paths", "[buffer_backed][inertia_stamped]") {
auto v = ef::InertiaStampedView::from_cdr({});
REQUIRE_FALSE(v.has_value());
}
TEST_CASE("InertiaStampedView happy path", "[buffer_backed][inertia_stamped]") {
auto v = ef::InertiaStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenInertiaStampedBytes,
sizeof(kGoldenInertiaStampedBytes)});
REQUIRE(v.has_value());
CHECK(v->stamp().sec == 1234567890);
CHECK(v->stamp().nanosec == 123456789u);
CHECK(v->frame_id() == "test_frame");
}
TEST_CASE("InertiaStampedView move semantics", "[buffer_backed][inertia_stamped]") {
auto v1 = ef::InertiaStampedView::from_cdr(
ef::span<const std::uint8_t>{kGoldenInertiaStampedBytes,
sizeof(kGoldenInertiaStampedBytes)});
REQUIRE(v1.has_value());
auto v2 = std::move(*v1);
CHECK(v2.frame_id() == "test_frame");
}
#pragma GCC diagnostic pop