Coverage Report

Created: 2024-04-30 09:35

test/zserio/HashCodeUtilTest.cpp
Line
Count
Source
1
#include "gtest/gtest.h"
2
#include "zserio/Array.h"
3
#include "zserio/BitBuffer.h"
4
#include "zserio/FloatUtil.h"
5
#include "zserio/HashCodeUtil.h"
6
7
namespace zserio
8
{
9
10
namespace
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
class Permissions
22
{
23
public:
24
    using underlying_type = uint8_t;
25
26
    enum class Values : underlying_type
27
    {
28
        READ = UINT8_C(1),
29
        WRITE = UINT8_C(2),
30
        CREATE = UINT8_C(4)
31
    };
32
33
    constexpr Permissions(Values value) noexcept :
34
            m_value(static_cast<underlying_type>(value))
35
7
    {}
36
37
    constexpr underlying_type getValue() const
38
3
    {
39
3
        return m_value;
40
3
    }
41
42
    uint32_t hashCode() const
43
4
    {
44
4
        uint32_t result = HASH_SEED;
45
4
        result = calcHashCode(result, m_value);
46
4
        return result;
47
4
    }
48
49
private:
50
    underlying_type m_value;
51
};
52
53
class DummyObject
54
{
55
public:
56
    explicit DummyObject(uint32_t hashCode) :
57
            m_hashCode(hashCode)
58
7
    {}
59
    uint32_t hashCode() const
60
7
    {
61
7
        return m_hashCode;
62
7
    }
63
64
private:
65
    uint32_t m_hashCode;
66
};
67
68
} // namespace
69
70
template <>
71
uint32_t enumHashCode<Color>(Color value)
72
5
{
73
5
    uint32_t result = HASH_SEED;
74
5
    result = calcHashCode(result, enumToValue(value));
75
5
    return result;
76
5
}
77
78
TEST(HashCodeUtilTest, simpleTypes)
79
1
{
80
1
    const uint32_t hashSeed = 1;
81
82
1
    const int intValue = 10;
83
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, intValue));
84
85
1
    const bool boolValue = true;
86
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 1, calcHashCode(hashSeed, boolValue));
87
88
1
    const uint8_t uint8Value = 10;
89
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, uint8Value));
90
91
1
    const uint16_t uint16Value = 10;
92
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, uint16Value));
93
94
1
    const uint32_t uint32Value = 10;
95
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, uint32Value));
96
97
1
    const uint64_t uint64Value = 10;
98
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, uint64Value));
99
100
1
    const int8_t int8Value = 10;
101
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, int8Value));
102
103
1
    const int16_t int16Value = 10;
104
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, int16Value));
105
106
1
    const int32_t int32Value = 10;
107
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, int32Value));
108
1
    const int32_t int32Value2 = -1;
109
1
    EXPECT_EQ(HASH_PRIME_NUMBER - 1, calcHashCode(hashSeed, int32Value2));
110
111
1
    const int64_t int64Value = -1;
112
1
    EXPECT_EQ(HASH_PRIME_NUMBER, calcHashCode(hashSeed, int64Value));
113
114
1
    const float floatValue = 10.0F;
115
1
    EXPECT_EQ(HASH_PRIME_NUMBER + convertFloatToUInt32(floatValue), calcHashCode(hashSeed, floatValue));
116
117
1
    const double doubleValue = 10.0;
118
1
    const uint64_t uint64DoubleValue = convertDoubleToUInt64(doubleValue);
119
1
    const uint32_t expectedHashCode =
120
1
            HASH_PRIME_NUMBER + static_cast<uint32_t>(uint64DoubleValue ^ (uint64DoubleValue >> 32U));
121
1
    EXPECT_EQ(expectedHashCode, calcHashCode(hashSeed, doubleValue));
122
1
}
123
124
TEST(HashCodeUtilTest, stringType)
125
1
{
126
1
    const uint32_t hashSeed = 1;
127
1
    const std::string stringValue = "0";
128
1
    EXPECT_EQ(HASH_PRIME_NUMBER + '0', calcHashCode(hashSeed, stringValue));
129
1
}
130
131
TEST(HashCodeUtilTest, bitBufferType)
132
1
{
133
1
    const uint32_t hashSeed = 1;
134
1
    const BitBuffer bitBufferValue;
135
1
    EXPECT_EQ(HASH_PRIME_NUMBER + HASH_SEED, calcHashCode(hashSeed, bitBufferValue));
136
1
}
137
138
TEST(HashCodeUtilTest, enumType)
139
1
{
140
1
    const uint32_t hashSeed = 1;
141
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Color::NONE)),
142
1
            calcHashCode(hashSeed, Color::NONE));
143
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Color::RED)),
144
1
            calcHashCode(hashSeed, Color::RED));
145
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Color::BLUE)),
146
1
            calcHashCode(hashSeed, Color::BLUE));
147
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Color::BLACK)),
148
1
            calcHashCode(hashSeed, Color::BLACK));
149
1
}
150
151
TEST(HashCodeUtilTest, bitmaskType)
152
1
{
153
1
    const uint32_t hashSeed = 1;
154
1
    EXPECT_EQ(HASH_PRIME_NUMBER +
155
1
                    (HASH_PRIME_NUMBER * HASH_SEED + Permissions(Permissions::Values::READ).getValue()),
156
1
            calcHashCode(hashSeed, Permissions(Permissions::Values::READ)));
157
1
    EXPECT_EQ(HASH_PRIME_NUMBER +
158
1
                    (HASH_PRIME_NUMBER * HASH_SEED + Permissions(Permissions::Values::WRITE).getValue()),
159
1
            calcHashCode(hashSeed, Permissions(Permissions::Values::WRITE)));
160
1
    EXPECT_EQ(HASH_PRIME_NUMBER +
161
1
                    (HASH_PRIME_NUMBER * HASH_SEED + Permissions(Permissions::Values::CREATE).getValue()),
162
1
            calcHashCode(hashSeed, Permissions(Permissions::Values::CREATE)));
163
1
}
164
165
TEST(HashCodeUtilTest, objectType)
166
1
{
167
1
    const uint32_t hashSeed = 1;
168
1
    const DummyObject objectValue(10);
169
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 10, calcHashCode(hashSeed, objectValue));
170
1
}
171
172
TEST(HashCodeUtilTest, emptyOptionalHolderType)
173
1
{
174
1
    const uint32_t hashSeed = 1;
175
1
    const InplaceOptionalHolder<DummyObject> optionalHolder{};
176
1
    EXPECT_EQ(HASH_PRIME_NUMBER, calcHashCode(hashSeed, optionalHolder));
177
1
}
178
179
TEST(HashCodeUtilTest, simpleOptionalHolderType)
180
1
{
181
1
    const uint32_t hashSeed = 1;
182
1
    const InplaceOptionalHolder<uint8_t> optionalHolder(3);
183
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 3, calcHashCode(hashSeed, optionalHolder));
184
1
}
185
186
TEST(HashCodeUtilTest, objectOptionalHolderType)
187
1
{
188
1
    const uint32_t hashSeed = 1;
189
1
    const InplaceOptionalHolder<DummyObject> optionalHolder(DummyObject(3));
190
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 3, calcHashCode(hashSeed, optionalHolder));
191
1
}
192
193
TEST(HashCodeUtilTest, emptyHeapOptionalHolderType)
194
1
{
195
1
    const uint32_t hashSeed = 1;
196
1
    const HeapOptionalHolder<DummyObject> optionalHolder;
197
1
    EXPECT_EQ(HASH_PRIME_NUMBER, calcHashCode(hashSeed, optionalHolder));
198
1
}
199
200
TEST(HashCodeUtilTest, objectHeapOptionalHolderType)
201
1
{
202
1
    const uint32_t hashSeed = 1;
203
1
    const HeapOptionalHolder<DummyObject> optionalHolder(DummyObject(13));
204
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 13, calcHashCode(hashSeed, optionalHolder));
205
1
}
206
207
TEST(HashCodeUtilTest, arrayType)
208
1
{
209
1
    const uint32_t hashSeed = 1;
210
1
    Array<std::vector<int32_t>, StdIntArrayTraits<int32_t>, ArrayType::NORMAL> arrayValue(
211
1
            std::vector<int32_t>{{3, 7}});
212
1
    const uint32_t rawArrayHashCode = (HASH_PRIME_NUMBER * HASH_SEED + 3) * HASH_PRIME_NUMBER + 7;
213
1
    EXPECT_EQ(HASH_PRIME_NUMBER + rawArrayHashCode, calcHashCode(hashSeed, arrayValue));
214
1
}
215
216
TEST(HashCodeUtilTest, simpleArrayType)
217
1
{
218
1
    const uint32_t hashSeed = 1;
219
1
    const std::vector<uint8_t> arrayValue = {3, 7};
220
1
    EXPECT_EQ((HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7, calcHashCode(hashSeed, arrayValue));
221
1
}
222
223
TEST(HashCodeUtil, stringArrayType)
224
1
{
225
1
    const uint32_t hashSeed = 1;
226
1
    const std::vector<std::string> arrayValue = {"0"};
227
1
    EXPECT_EQ(HASH_PRIME_NUMBER + '0', calcHashCode(hashSeed, arrayValue));
228
1
}
229
230
TEST(HashCodeUtil, bitBufferArrayType)
231
1
{
232
1
    const uint32_t hashSeed = 1;
233
1
    const std::vector<BitBuffer> arrayValue = {BitBuffer()};
234
1
    EXPECT_EQ(HASH_PRIME_NUMBER + HASH_SEED, calcHashCode(hashSeed, arrayValue));
235
1
}
236
237
TEST(HashCodeUtil, bytesArrayType)
238
1
{
239
1
    const uint32_t hashSeed = 1;
240
1
    const std::vector<std::vector<uint8_t>> arrayValue = {{1}};
241
1
    EXPECT_EQ(HASH_PRIME_NUMBER + 1, calcHashCode(hashSeed, arrayValue));
242
1
}
243
244
TEST(HashCodeUtil, enumArrayType)
245
1
{
246
1
    const uint32_t hashSeed = 1;
247
1
    const std::vector<Color> arrayValue = {Color::NONE};
248
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Color::NONE)),
249
1
            calcHashCode(hashSeed, arrayValue));
250
1
}
251
252
TEST(HashCodeUtil, bitmaskArrayType)
253
1
{
254
1
    const uint32_t hashSeed = 1;
255
1
    const std::vector<Permissions> arrayValue = {Permissions::Values::READ};
256
1
    EXPECT_EQ(HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + enumToValue(Permissions::Values::READ)),
257
1
            calcHashCode(hashSeed, arrayValue));
258
1
}
259
260
TEST(HashCodeUtilTest, objectArrayType)
261
1
{
262
1
    const uint32_t hashSeed = 1;
263
1
    const std::vector<DummyObject> arrayValue = {DummyObject(3), DummyObject(7)};
264
1
    EXPECT_EQ((HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7, calcHashCode(hashSeed, arrayValue));
265
1
}
266
267
TEST(HashCodeUtilTest, optionalSimpleArrayType)
268
1
{
269
1
    const uint32_t hashSeed = 1;
270
1
    const InplaceOptionalHolder<std::vector<uint32_t>> optionalArrayValue = {{3, 7}};
271
1
    EXPECT_EQ((HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7, calcHashCode(hashSeed, optionalArrayValue));
272
1
}
273
274
TEST(HashCodeUtilTest, optionalObjectArrayType)
275
1
{
276
1
    const uint32_t hashSeed = 1;
277
1
    const InplaceOptionalHolder<std::vector<DummyObject>> optionalArrayValue = {
278
1
            {DummyObject(3), DummyObject(7)}};
279
1
    EXPECT_EQ((HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7, calcHashCode(hashSeed, optionalArrayValue));
280
1
}
281
282
} // namespace zserio