Coverage Report

Created: 2023-12-13 14:58

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