1#include <msgpack.hpp> 2#include <gtest/gtest.h> 3 4 5enum enum_test { 6 elem 7}; 8 9MSGPACK_ADD_ENUM(enum_test); 10 11struct outer_enum { 12 enum enum_test { 13 elem 14 }; 15}; 16 17MSGPACK_ADD_ENUM(outer_enum::enum_test); 18 19#if !defined(MSGPACK_USE_CPP03) 20 21enum class enum_class_test { 22 elem 23}; 24 25MSGPACK_ADD_ENUM(enum_class_test); 26 27struct outer_enum_class { 28 enum class enum_class_test { 29 elem 30 }; 31}; 32 33MSGPACK_ADD_ENUM(outer_enum_class::enum_class_test); 34 35#endif // !defined(MSGPACK_USE_CPP03) 36 37struct myclass { 38 myclass() : num(0), str("default") { } 39 40 myclass(int num, const std::string& str) : 41 num(num), str(str) { } 42 43 ~myclass() { } 44 45 int num; 46 std::string str; 47 std::vector<double> vec; 48 std::map<std::string, std::vector<char> > map; 49 50 MSGPACK_DEFINE(num, str, vec, map); 51 52 bool operator==(const myclass& o) const 53 { 54 return num == o.num && str == o.str && vec == o.vec && map == o.map; 55 } 56}; 57 58std::ostream& operator<<(std::ostream& o, const myclass& m) 59{ 60 return o << "myclass("<<m.num<<",\""<<m.str<<"\")"; 61} 62 63 64TEST(object, convert) 65{ 66 myclass m1(1, "custom"); 67 68 msgpack::sbuffer sbuf; 69 msgpack::pack(sbuf, m1); 70 71 msgpack::unpacked ret; 72 msgpack::unpack(ret, sbuf.data(), sbuf.size()); 73 74 myclass m2; 75 ret.get().convert(m2); 76 77 EXPECT_EQ(m1, m2); 78} 79 80 81TEST(object, as) 82{ 83 myclass m1(1, "custom"); 84 85 msgpack::sbuffer sbuf; 86 msgpack::pack(sbuf, m1); 87 88 msgpack::unpacked ret; 89 msgpack::unpack(ret, sbuf.data(), sbuf.size()); 90 91 EXPECT_EQ(m1, ret.get().as<myclass>()); 92} 93 94TEST(object, cross_zone_copy) 95{ 96 myclass m1(1, "custom"); 97 m1.vec.push_back(1.0); 98 m1.vec.push_back(0.1); 99 std::vector<char> vc; 100 vc.push_back('t'); 101 vc.push_back('w'); 102 vc.push_back('o'); 103 m1.map["one"] = vc; 104 105 msgpack::zone z1; 106 msgpack::object::with_zone obj1(z1); 107 108 { 109 msgpack::zone z2; 110 msgpack::object::with_zone obj2(z2); 111 obj2 << m1; 112 113 obj1 << obj2; 114 115 EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.f64, 1.0); 116#if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT) 117 EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0); 118#endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT 119 EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o'); 120 EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't'); 121 EXPECT_NE( 122 obj1.via.array.ptr[2].via.array.ptr, 123 obj2.via.array.ptr[2].via.array.ptr); 124 EXPECT_NE( 125 obj1.via.array.ptr[3].via.map.ptr, 126 obj2.via.array.ptr[3].via.map.ptr); 127 EXPECT_NE( 128 obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr, 129 obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr); 130 EXPECT_NE( 131 obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr, 132 obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr); 133 } 134 135 EXPECT_EQ(m1, obj1.as<myclass>()); 136} 137 138TEST(object, cross_zone_copy_construct) 139{ 140 myclass m1(1, "custom"); 141 m1.vec.push_back(1.0); 142 m1.vec.push_back(0.1); 143 std::vector<char> vc; 144 vc.push_back('t'); 145 vc.push_back('w'); 146 vc.push_back('o'); 147 m1.map["one"] = vc; 148 149 msgpack::zone z1; 150 msgpack::zone z2; 151 msgpack::object::with_zone obj2(z2); 152 obj2 << m1; 153 154 msgpack::object obj1(obj2, z1); 155 156 EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.f64, 1.0); 157#if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT) 158 EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0); 159#endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT 160 EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o'); 161 EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't'); 162 EXPECT_NE( 163 obj1.via.array.ptr[2].via.array.ptr, 164 obj2.via.array.ptr[2].via.array.ptr); 165 EXPECT_NE( 166 obj1.via.array.ptr[3].via.map.ptr, 167 obj2.via.array.ptr[3].via.map.ptr); 168 EXPECT_NE( 169 obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr, 170 obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr); 171 EXPECT_NE( 172 obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr, 173 obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr); 174 EXPECT_EQ(m1, obj1.as<myclass>()); 175} 176 177TEST(object, cross_zone_copy_ext) 178{ 179 msgpack::zone z1; 180 msgpack::zone z2; 181 msgpack::object::with_zone obj1(z1); 182 183 obj1.type = msgpack::type::EXT; 184 char* ptr = static_cast<char*>(obj1.zone.allocate_align(2)); 185 ptr[0] = 1; 186 ptr[1] = 2; 187 obj1.via.ext.ptr = ptr; 188 obj1.via.ext.size = 1; 189 190 msgpack::object::with_zone obj2(z2); 191 obj2 << obj1; 192 EXPECT_EQ(obj2.via.ext.size, 1u); 193 EXPECT_EQ(obj2.via.ext.ptr[0], 1); 194 EXPECT_EQ(obj2.via.ext.ptr[1], 2); 195 EXPECT_NE( 196 obj1.via.ext.ptr, 197 obj2.via.ext.ptr); 198} 199 200TEST(object, cross_zone_copy_construct_ext) 201{ 202 msgpack::zone z1; 203 msgpack::zone z2; 204 msgpack::object::with_zone obj1(z1); 205 206 obj1.type = msgpack::type::EXT; 207 char* ptr = static_cast<char*>(obj1.zone.allocate_align(2)); 208 ptr[0] = 1; 209 ptr[1] = 2; 210 obj1.via.ext.ptr = ptr; 211 obj1.via.ext.size = 1; 212 213 msgpack::object obj2(obj1, z2); 214 EXPECT_EQ(obj2.via.ext.size, 1u); 215 EXPECT_EQ(obj2.via.ext.ptr[0], 1); 216 EXPECT_EQ(obj2.via.ext.ptr[1], 2); 217 EXPECT_NE( 218 obj1.via.ext.ptr, 219 obj2.via.ext.ptr); 220} 221 222TEST(object, print) 223{ 224 msgpack::object obj; 225 std::cout << obj << std::endl; 226} 227 228 229TEST(object, is_nil) 230{ 231 msgpack::object obj; 232 EXPECT_TRUE(obj.is_nil()); 233} 234 235 236TEST(object, type_error) 237{ 238 msgpack::object obj(1); 239 EXPECT_THROW(obj.as<std::string>(), msgpack::type_error); 240 EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error); 241 EXPECT_EQ(1, obj.as<int>()); 242 EXPECT_EQ(1, obj.as<short>()); 243 EXPECT_EQ(1u, obj.as<unsigned int>()); 244 EXPECT_EQ(1u, obj.as<unsigned long>()); 245} 246 247 248TEST(object, equal_primitive) 249{ 250 msgpack::object obj_nil; 251 EXPECT_EQ(obj_nil, msgpack::object()); 252 253 msgpack::object obj_int(1); 254 EXPECT_EQ(obj_int, msgpack::object(1)); 255 EXPECT_EQ(obj_int, 1); 256 257 msgpack::object obj_float(1.2); 258 EXPECT_EQ(obj_float, msgpack::object(1.2)); 259 EXPECT_EQ(obj_float, 1.2); 260 261 msgpack::object obj_bool(true); 262 EXPECT_EQ(obj_bool, msgpack::object(true)); 263 EXPECT_EQ(obj_bool, true); 264} 265 266 267TEST(object, construct_primitive) 268{ 269 msgpack::object obj_nil; 270 EXPECT_EQ(msgpack::type::NIL, obj_nil.type); 271 272 msgpack::object obj_uint(1); 273 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type); 274 EXPECT_EQ(1u, obj_uint.via.u64); 275 276 msgpack::object obj_int(-1); 277 EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type); 278 EXPECT_EQ(-1, obj_int.via.i64); 279 280 msgpack::object obj_float(1.2); 281 EXPECT_EQ(msgpack::type::FLOAT, obj_float.type); 282 EXPECT_EQ(1.2, obj_float.via.f64); 283#if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT) 284 EXPECT_EQ(msgpack::type::DOUBLE, obj_float.type); 285 EXPECT_EQ(1.2, obj_float.via.dec); 286#endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT 287 288 msgpack::object obj_bool(true); 289 EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type); 290 EXPECT_EQ(true, obj_bool.via.boolean); 291} 292 293TEST(object, construct_enum) 294{ 295 msgpack::object obj(elem); 296 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 297 EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64); 298} 299 300#if !defined(MSGPACK_USE_CPP03) 301 302TEST(object, construct_enum_newstyle) 303{ 304 msgpack::object obj(enum_test::elem); 305 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 306 EXPECT_EQ(elem, obj.via.u64); 307} 308 309#endif // !defined(MSGPACK_USE_CPP03) 310 311TEST(object, construct_enum_outer) 312{ 313 msgpack::object obj(outer_enum::elem); 314 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 315 EXPECT_EQ(static_cast<uint64_t>(elem), obj.via.u64); 316} 317 318#if !defined(MSGPACK_USE_CPP03) 319 320TEST(object, construct_enum_outer_newstyle) 321{ 322 msgpack::object obj(outer_enum::enum_test::elem); 323 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 324 EXPECT_EQ(elem, obj.via.u64); 325} 326 327TEST(object, construct_class_enum) 328{ 329 msgpack::object obj(enum_class_test::elem); 330 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 331 EXPECT_EQ(elem, obj.via.u64); 332} 333 334 335TEST(object, construct_class_enum_outer) 336{ 337 msgpack::object obj(outer_enum_class::enum_class_test::elem); 338 EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj.type); 339 EXPECT_EQ(elem, obj.via.u64); 340} 341 342#endif // !defined(MSGPACK_USE_CPP03) 343 344TEST(object, clone_int) 345{ 346 int v = 0; 347 msgpack::object obj(v); 348 std::size_t sz1 = msgpack::aligned_zone_size(obj); 349 msgpack::object_handle h = msgpack::clone(obj); 350 EXPECT_EQ(h.get(), obj); 351 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 352 h = msgpack::clone(obj); 353 EXPECT_EQ(h.get(), obj); 354 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 355} 356 357TEST(object, clone_str) 358{ 359 msgpack::zone z; 360 std::string v = "123456789"; 361 msgpack::object obj(v, z); 362 std::size_t sz1 = msgpack::aligned_zone_size(obj); 363 msgpack::object_handle h = msgpack::clone(obj); 364 EXPECT_EQ(h.get(), obj); 365 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 366 h = msgpack::clone(obj); 367 EXPECT_EQ(h.get(), obj); 368 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 369} 370 371TEST(object, clone_bin) 372{ 373 msgpack::zone z; 374 std::vector<char> v; 375 v.push_back('A'); 376 v.push_back('B'); 377 v.push_back('C'); 378 msgpack::object obj(v, z); 379 std::size_t sz1 = msgpack::aligned_zone_size(obj); 380 msgpack::object_handle h = msgpack::clone(obj); 381 EXPECT_EQ(h.get(), obj); 382 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 383 h = msgpack::clone(obj); 384 EXPECT_EQ(h.get(), obj); 385 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 386} 387 388TEST(object, clone_array) 389{ 390 msgpack::zone z; 391 std::vector<int> v; 392 v.push_back(1); 393 v.push_back(2); 394 v.push_back(3); 395 msgpack::object obj(v, z); 396 std::size_t sz1 = msgpack::aligned_zone_size(obj); 397 msgpack::object_handle h = msgpack::clone(obj); 398 EXPECT_EQ(h.get(), obj); 399 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 400 h = msgpack::clone(obj); 401 EXPECT_EQ(h.get(), obj); 402 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 403} 404 405TEST(object, clone_map) 406{ 407 msgpack::zone z; 408 std::map<int, std::string> v; 409 v.insert(std::map<int, std::string>::value_type(1, "ABC")); 410 v.insert(std::map<int, std::string>::value_type(2, "DEF")); 411 v.insert(std::map<int, std::string>::value_type(3, "GHI")); 412 msgpack::object obj(v, z); 413 std::size_t sz1 = msgpack::aligned_zone_size(obj); 414 msgpack::object_handle h = msgpack::clone(obj); 415 EXPECT_EQ(h.get(), obj); 416 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 417 h = msgpack::clone(obj); 418 EXPECT_EQ(h.get(), obj); 419 EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); 420} 421