1#include <msgpack.hpp>
2#include <string>
3#include <cmath>
4
5#include <gtest/gtest.h>
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11
12
13using namespace std;
14
15const unsigned int kLoop = 1000;
16const unsigned int kElements = 100;
17const double kEPS = 1e-10;
18
19// User-Defined Structures
20
21class TestEnumMemberClass
22{
23public:
24  TestEnumMemberClass()
25    : t1(STATE_A), t2(STATE_B), t3(STATE_C) {}
26
27  enum TestEnumType {
28    STATE_INVALID = 0,
29    STATE_A = 1,
30    STATE_B = 2,
31    STATE_C = 3
32  };
33  TestEnumType t1;
34  TestEnumType t2;
35  TestEnumType t3;
36
37  MSGPACK_DEFINE(t1, t2, t3);
38};
39
40MSGPACK_ADD_ENUM(TestEnumMemberClass::TestEnumType);
41
42class TestClass
43{
44public:
45  TestClass() : i(0), s("kzk") {}
46  int i;
47  string s;
48  MSGPACK_DEFINE(i, s);
49};
50
51TEST(MSGPACK_USER_DEFINED, simple_buffer_class)
52{
53  for (unsigned int k = 0; k < kLoop; k++) {
54    TestClass val1;
55    msgpack::sbuffer sbuf;
56    msgpack::pack(sbuf, val1);
57    msgpack::unpacked ret;
58    msgpack::unpack(ret, sbuf.data(), sbuf.size());
59    TestClass val2 = ret.get().as<TestClass>();
60    EXPECT_EQ(val1.i, val2.i);
61    EXPECT_EQ(val1.s, val2.s);
62  }
63}
64
65class TestClass2
66{
67public:
68  TestClass2() : i(0), s("kzk") {
69    for (unsigned int i = 0; i < kElements; i++)
70      v.push_back(rand());
71  }
72  int i;
73  string s;
74  vector<int> v;
75  MSGPACK_DEFINE(i, s, v);
76};
77
78TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new)
79{
80  for (unsigned int k = 0; k < kLoop; k++) {
81    TestClass val1;
82    msgpack::sbuffer sbuf;
83    msgpack::pack(sbuf, val1);
84    msgpack::unpacked ret;
85    msgpack::unpack(ret, sbuf.data(), sbuf.size());
86    TestClass2 val2 = ret.get().as<TestClass2>();
87    EXPECT_EQ(val1.i, val2.i);
88    EXPECT_EQ(val1.s, val2.s);
89    EXPECT_FALSE(val2.s.empty());
90  }
91}
92
93TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old)
94{
95  for (unsigned int k = 0; k < kLoop; k++) {
96    TestClass2 val1;
97    msgpack::sbuffer sbuf;
98    msgpack::pack(sbuf, val1);
99    msgpack::unpacked ret;
100    msgpack::unpack(ret, sbuf.data(), sbuf.size());
101    TestClass val2 = ret.get().as<TestClass>();
102    EXPECT_EQ(val1.i, val2.i);
103    EXPECT_EQ(val1.s, val2.s);
104    EXPECT_FALSE(val2.s.empty());
105  }
106}
107
108TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member)
109{
110  TestEnumMemberClass val1;
111  msgpack::sbuffer sbuf;
112  msgpack::pack(sbuf, val1);
113  msgpack::unpacked ret;
114  msgpack::unpack(ret, sbuf.data(), sbuf.size());
115  TestEnumMemberClass val2 = ret.get().as<TestEnumMemberClass>();
116  EXPECT_EQ(val1.t1, val2.t1);
117  EXPECT_EQ(val1.t2, val2.t2);
118  EXPECT_EQ(val1.t3, val2.t3);
119}
120
121class TestUnionMemberClass
122{
123public:
124  TestUnionMemberClass() {}
125  TestUnionMemberClass(double f) {
126    is_double = true;
127    value.f = f;
128  }
129  TestUnionMemberClass(int i) {
130    is_double = false;
131    value.i = i;
132  }
133
134  union {
135    double f;
136    int i;
137  } value;
138  bool is_double;
139
140  template <typename Packer>
141  void msgpack_pack(Packer& pk) const
142  {
143    if (is_double)
144      pk.pack(msgpack::type::tuple<bool, double>(true, value.f));
145    else
146      pk.pack(msgpack::type::tuple<bool, int>(false, value.i));
147  }
148
149  void msgpack_unpack(msgpack::object o)
150  {
151    msgpack::type::tuple<bool, msgpack::object> tuple;
152    o.convert(tuple);
153
154    is_double = tuple.get<0>();
155    if (is_double)
156      tuple.get<1>().convert(value.f);
157    else
158      tuple.get<1>().convert(value.i);
159  }
160};
161
162TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member)
163{
164  {
165    // double
166    TestUnionMemberClass val1(1.0);
167    msgpack::sbuffer sbuf;
168    msgpack::pack(sbuf, val1);
169    msgpack::unpacked ret;
170    msgpack::unpack(ret, sbuf.data(), sbuf.size());
171    TestUnionMemberClass val2 = ret.get().as<TestUnionMemberClass>();
172    EXPECT_EQ(val1.is_double, val2.is_double);
173    EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS);
174  }
175  {
176    // int
177    TestUnionMemberClass val1(1);
178    msgpack::sbuffer sbuf;
179    msgpack::pack(sbuf, val1);
180    msgpack::unpacked ret;
181    msgpack::unpack(ret, sbuf.data(), sbuf.size());
182    TestUnionMemberClass val2 = ret.get().as<TestUnionMemberClass>();
183    EXPECT_EQ(val1.is_double, val2.is_double);
184    EXPECT_EQ(val1.value.i, 1);
185    EXPECT_EQ(val1.value.i, val2.value.i);
186  }
187}
188
189// inheritance
190
191// define
192
193struct d_top {
194    int t;
195    MSGPACK_DEFINE(t);
196};
197
198struct d_mid1 : d_top {
199    int m1;
200    MSGPACK_DEFINE(MSGPACK_BASE(d_top), m1);
201};
202
203struct d_mid2 : d_top {
204    int m2;
205    MSGPACK_DEFINE(m2, MSGPACK_BASE(d_top));
206};
207
208struct d_bottom : d_mid1, d_mid2 {
209    int b;
210    MSGPACK_DEFINE(MSGPACK_BASE(d_mid1), MSGPACK_BASE(d_mid2), b);
211};
212
213TEST(MSGPACK_INHERIT, define_non_virtual)
214{
215    d_bottom b;
216    b.b = 1;
217    b.m1 = 2;
218    b.m2 = 3;
219    b.d_mid1::t = 4;
220    b.d_mid2::t = 5;
221    msgpack::sbuffer sbuf;
222    msgpack::pack(sbuf, b);
223    msgpack::unpacked ret;
224    msgpack::unpack(ret, sbuf.data(), sbuf.size());
225    d_bottom br = ret.get().as<d_bottom>();
226    EXPECT_EQ(b.b, br.b);
227    EXPECT_EQ(b.m1, br.m1);
228    EXPECT_EQ(b.m2, br.m2);
229    EXPECT_EQ(b.d_mid1::t, br.d_mid1::t);
230    EXPECT_EQ(b.d_mid2::t, br.d_mid2::t);
231}
232
233struct v_d_top {
234    int t;
235    MSGPACK_DEFINE(t);
236};
237
238struct v_d_mid1 : virtual v_d_top {
239    int m1;
240    MSGPACK_DEFINE(m1);
241};
242
243struct v_d_mid2 : virtual v_d_top {
244    int m2;
245    MSGPACK_DEFINE(m2);
246};
247
248struct v_d_bottom : v_d_mid1, v_d_mid2 {
249    int b;
250    MSGPACK_DEFINE(MSGPACK_BASE(v_d_mid1), MSGPACK_BASE(v_d_mid2), MSGPACK_BASE(v_d_top), b);
251};
252
253TEST(MSGPACK_INHERIT, define_virtual)
254{
255    v_d_bottom b;
256    b.b = 1;
257    b.m1 = 2;
258    b.m2 = 3;
259    b.t = 4;
260    msgpack::sbuffer sbuf;
261    msgpack::pack(sbuf, b);
262    msgpack::unpacked ret;
263    msgpack::unpack(ret, sbuf.data(), sbuf.size());
264    v_d_bottom br = ret.get().as<v_d_bottom>();
265    EXPECT_EQ(b.b, br.b);
266    EXPECT_EQ(b.m1, br.m1);
267    EXPECT_EQ(b.m2, br.m2);
268    EXPECT_EQ(b.t, br.t);
269}
270
271// define_array
272
273struct da_top {
274    int t;
275    MSGPACK_DEFINE_ARRAY(t);
276};
277
278struct da_mid1 : da_top {
279    int m1;
280    MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_top), m1);
281};
282
283struct da_mid2 : da_top {
284    int m2;
285    MSGPACK_DEFINE_ARRAY(m2, MSGPACK_BASE_ARRAY(da_top));
286};
287
288struct da_bottom : da_mid1, da_mid2 {
289    int b;
290    MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_mid1), MSGPACK_BASE_ARRAY(da_mid2), b);
291};
292
293TEST(MSGPACK_INHERIT, define_array_non_virtual)
294{
295    da_bottom b;
296    b.b = 1;
297    b.m1 = 2;
298    b.m2 = 3;
299    b.da_mid1::t = 4;
300    b.da_mid2::t = 5;
301    msgpack::sbuffer sbuf;
302    msgpack::pack(sbuf, b);
303    msgpack::unpacked ret;
304    msgpack::unpack(ret, sbuf.data(), sbuf.size());
305    da_bottom br = ret.get().as<da_bottom>();
306    EXPECT_EQ(b.b, br.b);
307    EXPECT_EQ(b.m1, br.m1);
308    EXPECT_EQ(b.m2, br.m2);
309    EXPECT_EQ(b.da_mid1::t, br.da_mid1::t);
310    EXPECT_EQ(b.da_mid2::t, br.da_mid2::t);
311}
312
313struct v_da_top {
314    int t;
315    MSGPACK_DEFINE_ARRAY(t);
316};
317
318struct v_da_mid1 : virtual v_da_top {
319    int m1;
320    MSGPACK_DEFINE_ARRAY(m1);
321};
322
323struct v_da_mid2 : virtual v_da_top {
324    int m2;
325    MSGPACK_DEFINE_ARRAY(m2);
326};
327
328struct v_da_bottom : v_da_mid1, v_da_mid2 {
329    int b;
330    MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(v_da_mid1), MSGPACK_BASE_ARRAY(v_da_mid2), MSGPACK_BASE_ARRAY(v_da_top), b);
331};
332
333TEST(MSGPACK_INHERIT, define_array_virtual)
334{
335    v_da_bottom b;
336    b.b = 1;
337    b.m1 = 2;
338    b.m2 = 3;
339    b.t = 4;
340    msgpack::sbuffer sbuf;
341    msgpack::pack(sbuf, b);
342    msgpack::unpacked ret;
343    msgpack::unpack(ret, sbuf.data(), sbuf.size());
344    v_da_bottom br = ret.get().as<v_da_bottom>();
345    EXPECT_EQ(b.b, br.b);
346    EXPECT_EQ(b.m1, br.m1);
347    EXPECT_EQ(b.m2, br.m2);
348    EXPECT_EQ(b.t, br.t);
349}
350
351// define_map
352
353struct dm_top {
354    int t;
355    MSGPACK_DEFINE_MAP(t);
356};
357
358struct dm_mid1 : dm_top {
359    int m1;
360    MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_top), m1);
361};
362
363struct dm_mid2 : dm_top {
364    int m2;
365    MSGPACK_DEFINE_MAP(m2, MSGPACK_BASE_MAP(dm_top));
366};
367
368struct dm_bottom : dm_mid1, dm_mid2 {
369    int b;
370    MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_mid1), MSGPACK_BASE_MAP(dm_mid2), b);
371};
372
373TEST(MSGPACK_INHERIT, define_map_non_virtual)
374{
375    dm_bottom b;
376    b.b = 1;
377    b.m1 = 2;
378    b.m2 = 3;
379    b.dm_mid1::t = 4;
380    b.dm_mid2::t = 5;
381    msgpack::sbuffer sbuf;
382    msgpack::pack(sbuf, b);
383    msgpack::unpacked ret;
384    msgpack::unpack(ret, sbuf.data(), sbuf.size());
385    dm_bottom br = ret.get().as<dm_bottom>();
386    EXPECT_EQ(b.b, br.b);
387    EXPECT_EQ(b.m1, br.m1);
388    EXPECT_EQ(b.m2, br.m2);
389    EXPECT_EQ(b.dm_mid1::t, br.dm_mid1::t);
390    EXPECT_EQ(b.dm_mid2::t, br.dm_mid2::t);
391}
392
393struct v_dm_top {
394    int t;
395    MSGPACK_DEFINE_MAP(t);
396};
397
398struct v_dm_mid1 : virtual v_dm_top {
399    int m1;
400    MSGPACK_DEFINE_MAP(m1);
401};
402
403struct v_dm_mid2 : virtual v_dm_top {
404    int m2;
405    MSGPACK_DEFINE_MAP(m2);
406};
407
408struct v_dm_bottom : v_dm_mid1, v_dm_mid2 {
409    int b;
410    MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(v_dm_mid1), MSGPACK_BASE_MAP(v_dm_mid2), MSGPACK_BASE_MAP(v_dm_top), b);
411};
412
413TEST(MSGPACK_INHERIT, define_map_virtual)
414{
415    v_dm_bottom b;
416    b.b = 1;
417    b.m1 = 2;
418    b.m2 = 3;
419    b.t = 4;
420    msgpack::sbuffer sbuf;
421    msgpack::pack(sbuf, b);
422    msgpack::unpacked ret;
423    msgpack::unpack(ret, sbuf.data(), sbuf.size());
424    v_dm_bottom br = ret.get().as<v_dm_bottom>();
425    EXPECT_EQ(b.b, br.b);
426    EXPECT_EQ(b.m1, br.m1);
427    EXPECT_EQ(b.m2, br.m2);
428    EXPECT_EQ(b.t, br.t);
429}
430
431// map migration
432
433struct s_v1 {
434    int i;
435    std::string s;
436    s_v1():i(42), s("foo") {}
437    MSGPACK_DEFINE_MAP(i, s);
438};
439
440struct s_v2 {
441    char c; // new member variable
442    std::string s;
443    int i;
444    s_v2():c('A'), s("bar"), i(77) {}
445    MSGPACK_DEFINE_MAP(c, s, i); // variable added, order changed
446};
447
448TEST(MSGPACK_MIGRATION, order_number_changed)
449{
450    s_v1 v1;
451    msgpack::sbuffer sbuf;
452    msgpack::pack(sbuf, v1);
453
454    msgpack::unpacked ret;
455    msgpack::unpack(ret, sbuf.data(), sbuf.size());
456    s_v2 v2 = ret.get().as<s_v2>();
457
458    EXPECT_EQ(v2.c, 'A');
459    EXPECT_EQ(v2.s, "foo"); // from v1
460    EXPECT_EQ(v2.i, 42);    // from v1
461}
462