James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 1 | #include "frc971/math/flatbuffers_matrix.h" |
| 2 | |
| 3 | #include "gtest/gtest.h" |
| 4 | |
| 5 | #include "aos/json_to_flatbuffer.h" |
| 6 | |
| 7 | namespace frc971::testing { |
| 8 | |
| 9 | class FlatbuffersMatrixTest : public ::testing::Test { |
| 10 | protected: |
| 11 | template <int Rows, int Cols, |
| 12 | fbs::StorageOrder StorageOrder = fbs::StorageOrder::ColMajor> |
| 13 | tl::expected<typename EigenMatrix<Rows, Cols, StorageOrder>::type, |
| 14 | ConversionFailure> |
| 15 | ToEigen(std::string_view json) { |
| 16 | return frc971::ToEigen<Rows, Cols, StorageOrder>( |
| 17 | aos::FlatbufferDetachedBuffer<fbs::Matrix>( |
| 18 | aos::JsonToFlatbuffer<fbs::Matrix>(json)) |
| 19 | .message()); |
| 20 | } |
| 21 | }; |
| 22 | |
| 23 | TEST_F(FlatbuffersMatrixTest, ReadWriteMatrix) { |
| 24 | const Eigen::Matrix<double, 3, 4> expected{ |
| 25 | {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}; |
| 26 | aos::fbs::Builder<fbs::MatrixStatic> builder; |
James Kuszmaul | 2739765 | 2024-03-15 21:44:52 -0700 | [diff] [blame] | 27 | flatbuffers::FlatBufferBuilder fbb; |
James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 28 | ASSERT_TRUE(FromEigen(expected, builder.get())); |
James Kuszmaul | 2739765 | 2024-03-15 21:44:52 -0700 | [diff] [blame] | 29 | fbb.Finish(FromEigen<3, 4>(expected, &fbb)); |
James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 30 | EXPECT_EQ( |
| 31 | "{ \"rows\": 3, \"cols\": 4, \"storage_order\": \"ColMajor\", \"data\": " |
James Kuszmaul | 98c798d | 2024-04-24 15:58:09 -0700 | [diff] [blame^] | 32 | "[ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11 ] }", |
James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 33 | aos::FlatbufferToJson(builder.AsFlatbufferSpan())); |
James Kuszmaul | 2739765 | 2024-03-15 21:44:52 -0700 | [diff] [blame] | 34 | EXPECT_EQ( |
| 35 | "{ \"rows\": 3, \"cols\": 4, \"storage_order\": \"ColMajor\", \"data\": " |
James Kuszmaul | 98c798d | 2024-04-24 15:58:09 -0700 | [diff] [blame^] | 36 | "[ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11 ] }", |
James Kuszmaul | 2739765 | 2024-03-15 21:44:52 -0700 | [diff] [blame] | 37 | aos::FlatbufferToJson( |
| 38 | aos::FlatbufferDetachedBuffer<fbs::Matrix>(fbb.Release()))); |
James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 39 | |
| 40 | const Eigen::Matrix<double, 3, 4> result = |
| 41 | ToEigenOrDie<3, 4>(builder->AsFlatbuffer()); |
| 42 | EXPECT_EQ(expected, result); |
| 43 | } |
| 44 | |
| 45 | TEST_F(FlatbuffersMatrixTest, ReadWriteMatrixRowMajor) { |
| 46 | const Eigen::Matrix<double, 3, 4, Eigen::StorageOptions::RowMajor> expected{ |
| 47 | {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}; |
| 48 | aos::fbs::Builder<fbs::MatrixStatic> builder; |
| 49 | ASSERT_TRUE(FromEigen(expected, builder.get())); |
| 50 | EXPECT_EQ( |
| 51 | "{ \"rows\": 3, \"cols\": 4, \"storage_order\": \"RowMajor\", \"data\": " |
James Kuszmaul | 98c798d | 2024-04-24 15:58:09 -0700 | [diff] [blame^] | 52 | "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] }", |
James Kuszmaul | 590e33e | 2024-01-14 17:54:00 -0800 | [diff] [blame] | 53 | aos::FlatbufferToJson(builder.AsFlatbufferSpan())); |
| 54 | |
| 55 | const Eigen::Matrix<double, 3, 4, Eigen::StorageOptions::RowMajor> result = |
| 56 | ToEigenOrDie<3, 4, fbs::StorageOrder::RowMajor>(builder->AsFlatbuffer()); |
| 57 | EXPECT_EQ(expected, result); |
| 58 | } |
| 59 | |
| 60 | class FlatbuffersMatrixParamTest |
| 61 | : public FlatbuffersMatrixTest, |
| 62 | public ::testing::WithParamInterface< |
| 63 | std::tuple<std::string, ConversionFailure>> {}; |
| 64 | TEST_P(FlatbuffersMatrixParamTest, ConversionFailures) { |
| 65 | auto result = this->ToEigen<3, 4>(std::get<0>(GetParam())); |
| 66 | EXPECT_FALSE(result.has_value()); |
| 67 | EXPECT_EQ(std::get<1>(GetParam()), result.error()); |
| 68 | } |
| 69 | |
| 70 | INSTANTIATE_TEST_SUITE_P( |
| 71 | ConversionFailureTests, FlatbuffersMatrixParamTest, |
| 72 | ::testing::Values( |
| 73 | std::make_tuple("{}", ConversionFailure{fbs::MatrixField::kRows, |
| 74 | fbs::FieldError::kMissing}), |
| 75 | std::make_tuple(R"json({"rows": 3})json", |
| 76 | ConversionFailure{fbs::MatrixField::kCols, |
| 77 | fbs::FieldError::kMissing}), |
| 78 | std::make_tuple(R"json({"rows": 3, "cols": 4})json", |
| 79 | ConversionFailure{fbs::MatrixField::kData, |
| 80 | fbs::FieldError::kMissing}), |
| 81 | std::make_tuple( |
| 82 | R"json({"rows": 1, "cols": 4, "data": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]})json", |
| 83 | ConversionFailure{fbs::MatrixField::kRows, |
| 84 | fbs::FieldError::kInconsistentWithTemplate}), |
| 85 | std::make_tuple( |
| 86 | R"json({"rows": 3, "cols": 7, "data": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]})json", |
| 87 | ConversionFailure{fbs::MatrixField::kCols, |
| 88 | fbs::FieldError::kInconsistentWithTemplate}), |
| 89 | std::make_tuple(R"json({"rows": 3, "cols": 4, "data": []})json", |
| 90 | ConversionFailure{ |
| 91 | fbs::MatrixField::kData, |
| 92 | fbs::FieldError::kInconsistentWithTemplate}), |
| 93 | std::make_tuple( |
| 94 | R"json({"rows": 3, "cols": 4, "storage_order": "RowMajor", "data": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]})json", |
| 95 | ConversionFailure{fbs::MatrixField::kStorageOrder, |
| 96 | fbs::FieldError::kInconsistentWithTemplate}))); |
| 97 | } // namespace frc971::testing |