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