test/zserio/EnumsTest.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include <array> |
2 | | |
3 | | #include "zserio/Enums.h" |
4 | | #include "zserio/BitStreamReader.h" |
5 | | #include "zserio/BitStreamWriter.h" |
6 | | #include "zserio/CppRuntimeException.h" |
7 | | |
8 | | #include "gtest/gtest.h" |
9 | | |
10 | | namespace zserio |
11 | | { |
12 | | |
13 | | enum class Color : uint8_t |
14 | | { |
15 | | NONE = UINT8_C(0), |
16 | | RED = UINT8_C(2), |
17 | | BLUE = UINT8_C(3), |
18 | | BLACK = UINT8_C(7) |
19 | | }; |
20 | | |
21 | | template <> |
22 | | struct EnumTraits<Color> |
23 | | { |
24 | | static constexpr std::array<const char*, 4> names = {{"NONE", "RED", "BLUE", "BLACK"}}; |
25 | | static constexpr std::array<Color, 4> values = {{Color::NONE, Color::RED, Color::BLUE, Color::BLACK}}; |
26 | | static constexpr const char* enumName = "Color"; |
27 | | }; |
28 | | |
29 | | constexpr std::array<const char*, 4> EnumTraits<Color>::names; |
30 | | constexpr std::array<Color, 4> EnumTraits<Color>::values; |
31 | | constexpr const char* EnumTraits<Color>::enumName; |
32 | | |
33 | | template <> |
34 | | inline size_t enumToOrdinal<Color>(Color value) |
35 | 11 | { |
36 | 11 | switch (value) |
37 | 11 | { |
38 | 3 | case Color::NONE: |
39 | 3 | return 0; |
40 | 2 | case Color::RED: |
41 | 2 | return 1; |
42 | 2 | case Color::BLUE: |
43 | 2 | return 2; |
44 | 2 | case Color::BLACK: |
45 | 2 | return 3; |
46 | 2 | default: |
47 | 2 | throw CppRuntimeException("Unknown value for enumeration Color: ") << |
48 | 2 | static_cast<uint8_t>(value) << "!"; |
49 | 11 | } |
50 | 11 | } |
51 | | |
52 | | template <> |
53 | | inline Color valueToEnum<Color>(typename std::underlying_type<Color>::type rawValue) |
54 | 6 | { |
55 | 6 | switch (rawValue) |
56 | 6 | { |
57 | 2 | case UINT8_C(0): |
58 | 3 | case UINT8_C(2): |
59 | 4 | case UINT8_C(3): |
60 | 5 | case UINT8_C(7): |
61 | 5 | return static_cast<Color>(rawValue); |
62 | 1 | default: |
63 | 1 | throw CppRuntimeException("Unknown value for enumeration Color: ") << rawValue << "!"; |
64 | 6 | } |
65 | 6 | } |
66 | | |
67 | | template <> |
68 | | inline size_t bitSizeOf<Color>(Color) |
69 | 1 | { |
70 | 1 | return 3; |
71 | 1 | } |
72 | | |
73 | | template <> |
74 | | inline size_t initializeOffsets<Color>(size_t bitPosition, Color) |
75 | 1 | { |
76 | 1 | return bitPosition + 3; |
77 | 1 | } |
78 | | |
79 | | template <> |
80 | | inline Color read<Color>(zserio::BitStreamReader& in) |
81 | 1 | { |
82 | 1 | return valueToEnum<Color>(static_cast<typename std::underlying_type<Color>::type>(in.readSignedBits(3))); |
83 | 1 | } |
84 | | |
85 | | template <> |
86 | | inline void write<Color>(BitStreamWriter& out, Color value) |
87 | 1 | { |
88 | 1 | out.writeSignedBits(enumToValue(value), 3); |
89 | 1 | } |
90 | | |
91 | | TEST(EnumsTest, enumToOrdinal) |
92 | 1 | { |
93 | 1 | EXPECT_EQ(0, enumToOrdinal(Color::NONE)); |
94 | 1 | EXPECT_EQ(1, enumToOrdinal(Color::RED)); |
95 | 1 | EXPECT_EQ(2, enumToOrdinal(Color::BLUE)); |
96 | 1 | EXPECT_EQ(3, enumToOrdinal(Color::BLACK)); |
97 | | |
98 | 1 | EXPECT_THROW(enumToOrdinal(static_cast<Color>(1)), CppRuntimeException); |
99 | 1 | } |
100 | | |
101 | | TEST(EnumsTest, valueToEnum) |
102 | 1 | { |
103 | 1 | EXPECT_EQ(Color::NONE, valueToEnum<Color>(0)); |
104 | 1 | EXPECT_EQ(Color::RED, valueToEnum<Color>(2)); |
105 | 1 | EXPECT_EQ(Color::BLUE, valueToEnum<Color>(3)); |
106 | 1 | EXPECT_EQ(Color::BLACK, valueToEnum<Color>(7)); |
107 | | |
108 | 1 | EXPECT_THROW(valueToEnum<Color>(1), CppRuntimeException); |
109 | 1 | } |
110 | | |
111 | | TEST(EnumsTest, enumToValue) |
112 | 1 | { |
113 | 1 | EXPECT_EQ(0, enumToValue(Color::NONE)); |
114 | 1 | EXPECT_EQ(2, enumToValue(Color::RED)); |
115 | 1 | EXPECT_EQ(3, enumToValue(Color::BLUE)); |
116 | 1 | EXPECT_EQ(7, enumToValue(Color::BLACK)); |
117 | 1 | } |
118 | | |
119 | | TEST(EnumsTest, stringToEnum) |
120 | 1 | { |
121 | 1 | EXPECT_EQ(Color::NONE, stringToEnum<Color>("NONE")); |
122 | 1 | EXPECT_EQ(Color::RED, stringToEnum<Color>("RED")); |
123 | 1 | EXPECT_EQ(Color::BLUE, stringToEnum<Color>("BLUE")); |
124 | 1 | EXPECT_EQ(Color::BLACK, stringToEnum<Color>("BLACK")); |
125 | | |
126 | 1 | EXPECT_THROW(stringToEnum<Color>("NONEXISTING"), CppRuntimeException); |
127 | 1 | } |
128 | | |
129 | | TEST(EnumsTest, enumToString) |
130 | 1 | { |
131 | | // use std::string to prevent comparison of pointer values (which happened on MSVC in debug) |
132 | 1 | EXPECT_EQ(std::string("NONE"), enumToString(Color::NONE)); |
133 | 1 | EXPECT_EQ(std::string("RED"), enumToString(Color::RED)); |
134 | 1 | EXPECT_EQ(std::string("BLUE"), enumToString(Color::BLUE)); |
135 | 1 | EXPECT_EQ(std::string("BLACK"), enumToString(Color::BLACK)); |
136 | | |
137 | 1 | EXPECT_THROW(enumToString(static_cast<Color>(1)), CppRuntimeException); |
138 | 1 | } |
139 | | |
140 | | TEST(EnumsTest, bitSizeOf) |
141 | 1 | { |
142 | 1 | EXPECT_EQ(3, bitSizeOf(Color::NONE)); |
143 | 1 | } |
144 | | |
145 | | TEST(EnumsTest, initializeOffsets) |
146 | 1 | { |
147 | 1 | const size_t bitPosition = 1; |
148 | 1 | EXPECT_EQ(3 + bitPosition, initializeOffsets(bitPosition, Color::NONE)); |
149 | 1 | } |
150 | | |
151 | | TEST(EnumsTest, writeAndRead) |
152 | 1 | { |
153 | 1 | std::array<uint8_t, 1> writeBuffer = {0}; |
154 | 1 | BitStreamWriter out(writeBuffer.data(), writeBuffer.size()); |
155 | 1 | const Color writeColor = Color::NONE; |
156 | 1 | write(out, writeColor); |
157 | | |
158 | 1 | BitStreamReader in(out.getWriteBuffer(), out.getBitPosition(), BitsTag()); |
159 | | |
160 | 1 | const Color readColor = read<Color>(in); |
161 | 1 | EXPECT_EQ(writeColor, readColor); |
162 | 1 | } |
163 | | |
164 | | TEST(EnumsTest, cppRuntimeExceptionOperator) |
165 | 1 | { |
166 | 1 | CppRuntimeException exception = CppRuntimeException() << Color::NONE; |
167 | 1 | ASSERT_STREQ("NONE", exception.what()); |
168 | 1 | } |
169 | | |
170 | | } // namespace zserio |