Coverage Report

Created: 2023-12-13 14:58

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