Coverage Report

Created: 2024-04-30 09:35

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