Skip to content

Commit 5c8d6c5

Browse files
committed
Add matching test suites for variant tagging
1 parent 4537a17 commit 5c8d6c5

6 files changed

+368
-72
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include <cassert>
2+
#include <rfl.hpp>
3+
#include <rfl/json.hpp>
4+
#include <string>
5+
#include <vector>
6+
7+
#include "write_and_read.hpp"
8+
9+
// NOTE TO MAINTAINERS:
10+
// These tests are very similar to the others in test_add_*tags_to_*variants.cpp, so please keep them
11+
// in sync.
12+
namespace test_add_namespaced_tags_to_rfl_variants {
13+
14+
// test 1 -> normal behaviour
15+
16+
struct button_pressed_t {};
17+
18+
// Test that we can still use structs that must be moved
19+
struct button_released_t {
20+
rfl::Box<int> button;
21+
};
22+
23+
struct key_pressed_t {
24+
// Manually specified tags don't get the namespace prefixed
25+
using Tag = rfl::Literal<"key_pressed">;
26+
char key;
27+
};
28+
29+
using my_event_type_t =
30+
rfl::Variant<button_pressed_t, button_released_t, key_pressed_t, int>;
31+
32+
TEST(json, test_add_namespaced_tags_to_rfl_variants) {
33+
std::vector<my_event_type_t> vec;
34+
vec.emplace_back(button_pressed_t{});
35+
vec.emplace_back(button_released_t{rfl::make_box<int>(4)});
36+
vec.emplace_back(key_pressed_t{'c'});
37+
vec.emplace_back(3);
38+
39+
write_and_read<rfl::AddNamespacedTagsToVariants>(
40+
vec,
41+
R"([{"test_add_namespaced_tags_to_rfl_variants::button_pressed_t":{}},{"test_add_namespaced_tags_to_rfl_variants::button_released_t":{"button":4}},{"key_pressed":{"key":99}},{"int":3}])");
42+
}
43+
44+
// test 2 -> 'Generic' within a struct like this can be read/written with
45+
// rfl::AddNamespacedTagsToVariants so that the underlying `std::variant` holds two 'Generic' fields
46+
// with different namespaces. See the similar test in test_add_tags_to_variants.cpp.
47+
// A hypothetical alternative would be adding an optional manual tag to rfl::Generic
48+
49+
struct APIResult {
50+
rfl::Generic result;
51+
};
52+
struct APIError {
53+
rfl::Generic error;
54+
};
55+
56+
using APICallOutput = rfl::Variant<APIResult, APIError>;
57+
58+
TEST(json, test_add_namespaced_tags_to_rfl_variants_with_generic) {
59+
APICallOutput output = APIResult{"200"};
60+
write_and_read<rfl::AddNamespacedTagsToVariants>(output,
61+
R"({"test_add_namespaced_tags_to_rfl_variants::APIResult":{"result":{"std::string":"200"}}})");
62+
}
63+
64+
// test 3 -> two structs with the same name in different namespaces should still
65+
// be serializable because we're using rfl::AddNamespacedTagsToVariants
66+
67+
namespace Result {
68+
struct Message {
69+
std::string result;
70+
};
71+
} // namespace Result
72+
73+
namespace Error {
74+
struct Message {
75+
std::string error;
76+
int error_id;
77+
};
78+
}; // namespace Error
79+
80+
using Messages = rfl::Variant<Result::Message, Error::Message>;
81+
82+
TEST(json, test_add_namespaced_tags_to_rfl_variants_different_namespaces) {
83+
std::vector<Messages> msgs{
84+
Result::Message{.result="a result"},
85+
Error::Message{.error="an error", .error_id=2},
86+
};
87+
write_and_read<rfl::AddNamespacedTagsToVariants>(msgs,
88+
R"([{"test_add_namespaced_tags_to_rfl_variants::Result::Message":{"result":"a result"}},{"test_add_namespaced_tags_to_rfl_variants::Error::Message":{"error":"an error","error_id":2}}])");
89+
}
90+
} // namespace test_add_namespaced_tags_to_rfl_variants
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <cassert>
2+
#include <rfl.hpp>
3+
#include <rfl/json.hpp>
4+
#include <string>
5+
#include <variant>
6+
#include <vector>
7+
8+
#include "write_and_read.hpp"
9+
10+
// NOTE TO MAINTAINERS:
11+
// These tests are very similar to the others in test_add_*tags_to_*variants.cpp, so please keep them
12+
// in sync.
13+
namespace test_add_namespaced_tags_to_variants {
14+
15+
// test 1 -> normal behaviour
16+
17+
struct button_pressed_t {};
18+
19+
// Test that we can still use structs that must be moved
20+
struct button_released_t {
21+
rfl::Box<int> button;
22+
};
23+
24+
struct key_pressed_t {
25+
// Manually specified tags don't get the namespace prefixed
26+
using Tag = rfl::Literal<"key_pressed">;
27+
char key;
28+
};
29+
30+
using my_event_type_t =
31+
std::variant<button_pressed_t, button_released_t, key_pressed_t, int>;
32+
33+
TEST(json, test_add_namespaced_tags_to_variants) {
34+
std::vector<my_event_type_t> vec;
35+
vec.emplace_back(button_pressed_t{});
36+
vec.emplace_back(button_released_t{rfl::make_box<int>(4)});
37+
vec.emplace_back(key_pressed_t{'c'});
38+
vec.emplace_back(3);
39+
40+
write_and_read<rfl::AddNamespacedTagsToVariants>(
41+
vec,
42+
R"([{"test_add_namespaced_tags_to_variants::button_pressed_t":{}},{"test_add_namespaced_tags_to_variants::button_released_t":{"button":4}},{"key_pressed":{"key":99}},{"int":3}])");
43+
}
44+
45+
// test 2 -> 'Generic' within a struct like this can be read/written with
46+
// rfl::AddNamespacedTagsToVariants so that the underlying `std::variant` holds two 'Generic' fields
47+
// with different namespaces. See the similar test in test_add_tags_to_variants.cpp.
48+
// A hypothetical alternative would be adding an optional manual tag to rfl::Generic
49+
50+
struct APIResult {
51+
rfl::Generic result;
52+
};
53+
struct APIError {
54+
rfl::Generic error;
55+
};
56+
57+
using APICallOutput = std::variant<APIResult, APIError>;
58+
59+
TEST(json, test_add_namespaced_tags_to_variants_with_generic) {
60+
APICallOutput output = APIResult{"200"};
61+
write_and_read<rfl::AddNamespacedTagsToVariants>(output,
62+
R"({"test_add_namespaced_tags_to_variants::APIResult":{"result":{"std::string":"200"}}})");
63+
}
64+
65+
// test 3 -> two structs with the same name in different namespaces should still
66+
// be serializable because we're using rfl::AddNamespacedTagsToVariants
67+
68+
namespace Result {
69+
struct Message {
70+
std::string result;
71+
};
72+
} // namespace Result
73+
74+
namespace Error {
75+
struct Message {
76+
std::string error;
77+
int error_id;
78+
};
79+
}; // namespace Error
80+
81+
using Messages = std::variant<Result::Message, Error::Message>;
82+
83+
TEST(json, test_add_namespaced_tags_to_variants_different_namespaces) {
84+
std::vector<Messages> msgs{
85+
Result::Message{.result="a result"},
86+
Error::Message{.error="an error", .error_id=2},
87+
};
88+
write_and_read<rfl::AddNamespacedTagsToVariants>(msgs,
89+
R"([{"test_add_namespaced_tags_to_variants::Result::Message":{"result":"a result"}},{"test_add_namespaced_tags_to_variants::Error::Message":{"error":"an error","error_id":2}}])");
90+
}
91+
} // namespace test_add_namespaced_tags_to_variants

tests/json/test_add_tag_to_rfl_variant.cpp

Lines changed: 0 additions & 39 deletions
This file was deleted.

tests/json/test_add_tag_to_variant.cpp

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <cassert>
2+
#include <rfl.hpp>
3+
#include <rfl/json.hpp>
4+
#include <string>
5+
#include <vector>
6+
7+
#include "write_and_read.hpp"
8+
9+
// NOTE TO MAINTAINERS:
10+
// These tests are very similar to the others in test_add_*tags_to_*variants.cpp, so please keep them
11+
// in sync.
12+
namespace test_add_tags_to_rfl_variants {
13+
14+
// test 1 -> normal behaviour
15+
16+
struct button_pressed_t {};
17+
18+
// Test that we can still use structs that must be moved
19+
struct button_released_t {
20+
rfl::Box<int> button;
21+
};
22+
23+
struct key_pressed_t {
24+
using Tag = rfl::Literal<"key_pressed">;
25+
char key;
26+
};
27+
28+
using my_event_type_t =
29+
rfl::Variant<button_pressed_t, button_released_t, key_pressed_t, int>;
30+
31+
TEST(json, test_add_tags_to_rfl_variants) {
32+
std::vector<my_event_type_t> vec;
33+
vec.emplace_back(button_pressed_t{});
34+
vec.emplace_back(button_released_t{rfl::make_box<int>(4)});
35+
vec.emplace_back(key_pressed_t{'c'});
36+
vec.emplace_back(3);
37+
38+
write_and_read<rfl::AddTagsToVariants>(
39+
vec,
40+
R"([{"button_pressed_t":{}},{"button_released_t":{"button":4}},{"key_pressed":{"key":99}},{"int":3}])");
41+
}
42+
43+
// test 2 -> 'Generic' within a struct like this cannot be read/written without using
44+
// rfl::AddNamespacedTagsToVariants due to the underlying `rfl::Variant` holding two fields with
45+
// name 'Generic'. See the similar test in test_add_namespaced_tags_to_rfl_variant.cpp
46+
// A hypothetical solution would be adding an optional manual tag to rfl::Generic
47+
48+
// struct APIResult {
49+
// rfl::Generic result;
50+
// };
51+
// struct APIError {
52+
// rfl::Generic error;
53+
// };
54+
55+
// using APICallOutput = rfl::Variant<APIResult, APIError>;
56+
57+
// TEST(json, test_add_tags_to_rfl_variants_with_generic) {
58+
// APICallOutput output = APIResult{"200"};
59+
// write_and_read<rfl::AddTagsToVariants>(output,
60+
// R"({"APIResult":{"result":{"std::string":"200"}}})");
61+
// }
62+
63+
// test 3 -> two structs with the same name in different namespaces should still
64+
// be serializable without rfl::AddNamespacedTagsToVariants, but only with manual tags
65+
66+
namespace Result {
67+
struct Message {
68+
// Avoid duplicate typenames from different namespaces using manual tag
69+
using Tag = rfl::Literal<"result_msg">;
70+
std::string result;
71+
};
72+
} // namespace Result
73+
74+
namespace Error {
75+
struct Message {
76+
// Avoid duplicate typenames from different namespaces using manual tag
77+
using Tag = rfl::Literal<"error_msg">;
78+
std::string error;
79+
int error_id;
80+
};
81+
}; // namespace Error
82+
83+
using Messages = rfl::Variant<Result::Message, Error::Message>;
84+
85+
TEST(json, test_add_tags_to_rfl_variants_different_namespaces) {
86+
std::vector<Messages> msgs{
87+
Result::Message{.result="a result"},
88+
Error::Message{.error="an error", .error_id=2},
89+
};
90+
write_and_read<rfl::AddTagsToVariants>(msgs,
91+
R"([{"result_msg":{"result":"a result"}},{"error_msg":{"error":"an error","error_id":2}}])");
92+
}
93+
} // namespace test_add_tags_to_rfl_variants

0 commit comments

Comments
 (0)