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