repeated_field_unittest.cc revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34// 35// TODO(kenton): Improve this unittest to bring it up to the standards of 36// other proto2 unittests. 37 38#include <algorithm> 39#include <list> 40 41#include <google/protobuf/repeated_field.h> 42 43#include <google/protobuf/stubs/common.h> 44#include <google/protobuf/unittest.pb.h> 45#include <google/protobuf/stubs/strutil.h> 46#include <google/protobuf/testing/googletest.h> 47#include <gtest/gtest.h> 48#include <google/protobuf/stubs/stl_util-inl.h> 49 50namespace google { 51using protobuf_unittest::TestAllTypes; 52 53namespace protobuf { 54namespace { 55 56// Test operations on a RepeatedField which is small enough that it does 57// not allocate a separate array for storage. 58TEST(RepeatedField, Small) { 59 RepeatedField<int> field; 60 61 EXPECT_EQ(field.size(), 0); 62 63 field.Add(5); 64 65 EXPECT_EQ(field.size(), 1); 66 EXPECT_EQ(field.Get(0), 5); 67 68 field.Add(42); 69 70 EXPECT_EQ(field.size(), 2); 71 EXPECT_EQ(field.Get(0), 5); 72 EXPECT_EQ(field.Get(1), 42); 73 74 field.Set(1, 23); 75 76 EXPECT_EQ(field.size(), 2); 77 EXPECT_EQ(field.Get(0), 5); 78 EXPECT_EQ(field.Get(1), 23); 79 EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0); 80 81 field.RemoveLast(); 82 83 EXPECT_EQ(field.size(), 1); 84 EXPECT_EQ(field.Get(0), 5); 85 86 field.Clear(); 87 88 EXPECT_EQ(field.size(), 0); 89 EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0); 90} 91 92// Test operations on a RepeatedField which is large enough to allocate a 93// separate array. 94TEST(RepeatedField, Large) { 95 RepeatedField<int> field; 96 97 for (int i = 0; i < 16; i++) { 98 field.Add(i * i); 99 } 100 101 EXPECT_EQ(field.size(), 16); 102 103 for (int i = 0; i < 16; i++) { 104 EXPECT_EQ(field.Get(i), i * i); 105 } 106 107 int expected_usage = 16 * sizeof(int); 108 EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage); 109} 110 111// Test swapping between various types of RepeatedFields. 112TEST(RepeatedField, SwapSmallSmall) { 113 RepeatedField<int> field1; 114 RepeatedField<int> field2; 115 116 field1.Add(5); 117 field1.Add(42); 118 119 field1.Swap(&field2); 120 121 EXPECT_EQ(field1.size(), 0); 122 EXPECT_EQ(field2.size(), 2); 123 EXPECT_EQ(field2.Get(0), 5); 124 EXPECT_EQ(field2.Get(1), 42); 125} 126 127TEST(RepeatedField, SwapLargeSmall) { 128 RepeatedField<int> field1; 129 RepeatedField<int> field2; 130 131 for (int i = 0; i < 16; i++) { 132 field1.Add(i * i); 133 } 134 field2.Add(5); 135 field2.Add(42); 136 field1.Swap(&field2); 137 138 EXPECT_EQ(field1.size(), 2); 139 EXPECT_EQ(field1.Get(0), 5); 140 EXPECT_EQ(field1.Get(1), 42); 141 EXPECT_EQ(field2.size(), 16); 142 for (int i = 0; i < 16; i++) { 143 EXPECT_EQ(field2.Get(i), i * i); 144 } 145} 146 147TEST(RepeatedField, SwapLargeLarge) { 148 RepeatedField<int> field1; 149 RepeatedField<int> field2; 150 151 field1.Add(5); 152 field1.Add(42); 153 for (int i = 0; i < 16; i++) { 154 field1.Add(i); 155 field2.Add(i * i); 156 } 157 field2.Swap(&field1); 158 159 EXPECT_EQ(field1.size(), 16); 160 for (int i = 0; i < 16; i++) { 161 EXPECT_EQ(field1.Get(i), i * i); 162 } 163 EXPECT_EQ(field2.size(), 18); 164 EXPECT_EQ(field2.Get(0), 5); 165 EXPECT_EQ(field2.Get(1), 42); 166 for (int i = 2; i < 18; i++) { 167 EXPECT_EQ(field2.Get(i), i - 2); 168 } 169} 170 171// Determines how much space was reserved by the given field by adding elements 172// to it until it re-allocates its space. 173static int ReservedSpace(RepeatedField<int>* field) { 174 const int* ptr = field->data(); 175 do { 176 field->Add(0); 177 } while (field->data() == ptr); 178 179 return field->size() - 1; 180} 181 182TEST(RepeatedField, ReserveMoreThanDouble) { 183 // Reserve more than double the previous space in the field and expect the 184 // field to reserve exactly the amount specified. 185 RepeatedField<int> field; 186 field.Reserve(20); 187 188 EXPECT_EQ(20, ReservedSpace(&field)); 189} 190 191TEST(RepeatedField, ReserveLessThanDouble) { 192 // Reserve less than double the previous space in the field and expect the 193 // field to grow by double instead. 194 RepeatedField<int> field; 195 field.Reserve(20); 196 field.Reserve(30); 197 198 EXPECT_EQ(40, ReservedSpace(&field)); 199} 200 201TEST(RepeatedField, ReserveLessThanExisting) { 202 // Reserve less than the previous space in the field and expect the 203 // field to not re-allocate at all. 204 RepeatedField<int> field; 205 field.Reserve(20); 206 const int* previous_ptr = field.data(); 207 field.Reserve(10); 208 209 EXPECT_EQ(previous_ptr, field.data()); 210 EXPECT_EQ(20, ReservedSpace(&field)); 211} 212 213TEST(RepeatedField, MergeFrom) { 214 RepeatedField<int> source, destination; 215 216 source.Add(4); 217 source.Add(5); 218 219 destination.Add(1); 220 destination.Add(2); 221 destination.Add(3); 222 223 destination.MergeFrom(source); 224 225 ASSERT_EQ(5, destination.size()); 226 227 EXPECT_EQ(1, destination.Get(0)); 228 EXPECT_EQ(2, destination.Get(1)); 229 EXPECT_EQ(3, destination.Get(2)); 230 EXPECT_EQ(4, destination.Get(3)); 231 EXPECT_EQ(5, destination.Get(4)); 232} 233 234TEST(RepeatedField, MutableDataIsMutable) { 235 RepeatedField<int> field; 236 field.Add(1); 237 EXPECT_EQ(1, field.Get(0)); 238 // The fact that this line compiles would be enough, but we'll check the 239 // value anyway. 240 *field.mutable_data() = 2; 241 EXPECT_EQ(2, field.Get(0)); 242} 243 244// =================================================================== 245// RepeatedPtrField tests. These pretty much just mirror the RepeatedField 246// tests above. 247 248TEST(RepeatedPtrField, Small) { 249 RepeatedPtrField<string> field; 250 251 EXPECT_EQ(field.size(), 0); 252 253 field.Add()->assign("foo"); 254 255 EXPECT_EQ(field.size(), 1); 256 EXPECT_EQ(field.Get(0), "foo"); 257 258 field.Add()->assign("bar"); 259 260 EXPECT_EQ(field.size(), 2); 261 EXPECT_EQ(field.Get(0), "foo"); 262 EXPECT_EQ(field.Get(1), "bar"); 263 264 field.Mutable(1)->assign("baz"); 265 266 EXPECT_EQ(field.size(), 2); 267 EXPECT_EQ(field.Get(0), "foo"); 268 EXPECT_EQ(field.Get(1), "baz"); 269 270 field.RemoveLast(); 271 272 EXPECT_EQ(field.size(), 1); 273 EXPECT_EQ(field.Get(0), "foo"); 274 275 field.Clear(); 276 277 EXPECT_EQ(field.size(), 0); 278} 279 280TEST(RepeatedPtrField, Large) { 281 RepeatedPtrField<string> field; 282 283 for (int i = 0; i < 16; i++) { 284 *field.Add() += 'a' + i; 285 } 286 287 EXPECT_EQ(field.size(), 16); 288 289 for (int i = 0; i < 16; i++) { 290 EXPECT_EQ(field.Get(i).size(), 1); 291 EXPECT_EQ(field.Get(i)[0], 'a' + i); 292 } 293 294 int min_expected_usage = 16 * sizeof(string); 295 EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); 296} 297 298TEST(RepeatedPtrField, SwapSmallSmall) { 299 RepeatedPtrField<string> field1; 300 RepeatedPtrField<string> field2; 301 302 field1.Add()->assign("foo"); 303 field1.Add()->assign("bar"); 304 field1.Swap(&field2); 305 306 EXPECT_EQ(field1.size(), 0); 307 EXPECT_EQ(field2.size(), 2); 308 EXPECT_EQ(field2.Get(0), "foo"); 309 EXPECT_EQ(field2.Get(1), "bar"); 310} 311 312TEST(RepeatedPtrField, SwapLargeSmall) { 313 RepeatedPtrField<string> field1; 314 RepeatedPtrField<string> field2; 315 316 field2.Add()->assign("foo"); 317 field2.Add()->assign("bar"); 318 for (int i = 0; i < 16; i++) { 319 *field1.Add() += 'a' + i; 320 } 321 field1.Swap(&field2); 322 323 EXPECT_EQ(field1.size(), 2); 324 EXPECT_EQ(field1.Get(0), "foo"); 325 EXPECT_EQ(field1.Get(1), "bar"); 326 EXPECT_EQ(field2.size(), 16); 327 for (int i = 0; i < 16; i++) { 328 EXPECT_EQ(field2.Get(i).size(), 1); 329 EXPECT_EQ(field2.Get(i)[0], 'a' + i); 330 } 331} 332 333TEST(RepeatedPtrField, SwapLargeLarge) { 334 RepeatedPtrField<string> field1; 335 RepeatedPtrField<string> field2; 336 337 field1.Add()->assign("foo"); 338 field1.Add()->assign("bar"); 339 for (int i = 0; i < 16; i++) { 340 *field1.Add() += 'A' + i; 341 *field2.Add() += 'a' + i; 342 } 343 field2.Swap(&field1); 344 345 EXPECT_EQ(field1.size(), 16); 346 for (int i = 0; i < 16; i++) { 347 EXPECT_EQ(field1.Get(i).size(), 1); 348 EXPECT_EQ(field1.Get(i)[0], 'a' + i); 349 } 350 EXPECT_EQ(field2.size(), 18); 351 EXPECT_EQ(field2.Get(0), "foo"); 352 EXPECT_EQ(field2.Get(1), "bar"); 353 for (int i = 2; i < 18; i++) { 354 EXPECT_EQ(field2.Get(i).size(), 1); 355 EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); 356 } 357} 358 359static int ReservedSpace(RepeatedPtrField<string>* field) { 360 const string* const* ptr = field->data(); 361 do { 362 field->Add(); 363 } while (field->data() == ptr); 364 365 return field->size() - 1; 366} 367 368TEST(RepeatedPtrField, ReserveMoreThanDouble) { 369 RepeatedPtrField<string> field; 370 field.Reserve(20); 371 372 EXPECT_EQ(20, ReservedSpace(&field)); 373} 374 375TEST(RepeatedPtrField, ReserveLessThanDouble) { 376 RepeatedPtrField<string> field; 377 field.Reserve(20); 378 field.Reserve(30); 379 380 EXPECT_EQ(40, ReservedSpace(&field)); 381} 382 383TEST(RepeatedPtrField, ReserveLessThanExisting) { 384 RepeatedPtrField<string> field; 385 field.Reserve(20); 386 const string* const* previous_ptr = field.data(); 387 field.Reserve(10); 388 389 EXPECT_EQ(previous_ptr, field.data()); 390 EXPECT_EQ(20, ReservedSpace(&field)); 391} 392 393TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { 394 // Check that a bug is fixed: An earlier implementation of Reserve() 395 // failed to copy pointers to allocated-but-cleared objects, possibly 396 // leading to segfaults. 397 RepeatedPtrField<string> field; 398 string* first = field.Add(); 399 field.RemoveLast(); 400 401 field.Reserve(20); 402 EXPECT_EQ(first, field.Add()); 403} 404 405// Clearing elements is tricky with RepeatedPtrFields since the memory for 406// the elements is retained and reused. 407TEST(RepeatedPtrField, ClearedElements) { 408 RepeatedPtrField<string> field; 409 410 string* original = field.Add(); 411 *original = "foo"; 412 413 EXPECT_EQ(field.ClearedCount(), 0); 414 415 field.RemoveLast(); 416 EXPECT_TRUE(original->empty()); 417 EXPECT_EQ(field.ClearedCount(), 1); 418 419 EXPECT_EQ(field.Add(), original); // Should return same string for reuse. 420 421 EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. 422 EXPECT_EQ(field.ClearedCount(), 0); 423 424 EXPECT_NE(field.Add(), original); // Should NOT return the same string. 425 EXPECT_EQ(field.ClearedCount(), 0); 426 427 field.AddAllocated(original); // Give ownership back. 428 EXPECT_EQ(field.ClearedCount(), 0); 429 EXPECT_EQ(field.Mutable(1), original); 430 431 field.Clear(); 432 EXPECT_EQ(field.ClearedCount(), 2); 433 EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. 434 EXPECT_EQ(field.ClearedCount(), 1); 435 EXPECT_NE(field.Add(), original); 436 EXPECT_EQ(field.ClearedCount(), 0); 437 EXPECT_NE(field.Add(), original); 438 EXPECT_EQ(field.ClearedCount(), 0); 439 440 field.AddCleared(original); // Give ownership back, but as a cleared object. 441 EXPECT_EQ(field.ClearedCount(), 1); 442 EXPECT_EQ(field.Add(), original); 443 EXPECT_EQ(field.ClearedCount(), 0); 444} 445 446TEST(RepeatedPtrField, MergeFrom) { 447 RepeatedPtrField<string> source, destination; 448 449 source.Add()->assign("4"); 450 source.Add()->assign("5"); 451 452 destination.Add()->assign("1"); 453 destination.Add()->assign("2"); 454 destination.Add()->assign("3"); 455 456 destination.MergeFrom(source); 457 458 ASSERT_EQ(5, destination.size()); 459 460 EXPECT_EQ("1", destination.Get(0)); 461 EXPECT_EQ("2", destination.Get(1)); 462 EXPECT_EQ("3", destination.Get(2)); 463 EXPECT_EQ("4", destination.Get(3)); 464 EXPECT_EQ("5", destination.Get(4)); 465} 466 467TEST(RepeatedPtrField, MutableDataIsMutable) { 468 RepeatedPtrField<string> field; 469 *field.Add() = "1"; 470 EXPECT_EQ("1", field.Get(0)); 471 // The fact that this line compiles would be enough, but we'll check the 472 // value anyway. 473 string** data = field.mutable_data(); 474 **data = "2"; 475 EXPECT_EQ("2", field.Get(0)); 476} 477 478// =================================================================== 479 480// Iterator tests stolen from net/proto/proto-array_unittest. 481class RepeatedFieldIteratorTest : public testing::Test { 482 protected: 483 virtual void SetUp() { 484 for (int i = 0; i < 3; ++i) { 485 proto_array_.Add(i); 486 } 487 } 488 489 RepeatedField<int> proto_array_; 490}; 491 492TEST_F(RepeatedFieldIteratorTest, Convertible) { 493 RepeatedField<int>::iterator iter = proto_array_.begin(); 494 RepeatedField<int>::const_iterator c_iter = iter; 495 EXPECT_EQ(0, *c_iter); 496} 497 498TEST_F(RepeatedFieldIteratorTest, MutableIteration) { 499 RepeatedField<int>::iterator iter = proto_array_.begin(); 500 EXPECT_EQ(0, *iter); 501 ++iter; 502 EXPECT_EQ(1, *iter++); 503 EXPECT_EQ(2, *iter); 504 ++iter; 505 EXPECT_TRUE(proto_array_.end() == iter); 506 507 EXPECT_EQ(2, *(proto_array_.end() - 1)); 508} 509 510TEST_F(RepeatedFieldIteratorTest, ConstIteration) { 511 const RepeatedField<int>& const_proto_array = proto_array_; 512 RepeatedField<int>::const_iterator iter = const_proto_array.begin(); 513 EXPECT_EQ(0, *iter); 514 ++iter; 515 EXPECT_EQ(1, *iter++); 516 EXPECT_EQ(2, *iter); 517 ++iter; 518 EXPECT_TRUE(proto_array_.end() == iter); 519 EXPECT_EQ(2, *(proto_array_.end() - 1)); 520} 521 522TEST_F(RepeatedFieldIteratorTest, Mutation) { 523 RepeatedField<int>::iterator iter = proto_array_.begin(); 524 *iter = 7; 525 EXPECT_EQ(7, proto_array_.Get(0)); 526} 527 528// ------------------------------------------------------------------- 529 530class RepeatedPtrFieldIteratorTest : public testing::Test { 531 protected: 532 virtual void SetUp() { 533 proto_array_.Add()->assign("foo"); 534 proto_array_.Add()->assign("bar"); 535 proto_array_.Add()->assign("baz"); 536 } 537 538 RepeatedPtrField<string> proto_array_; 539}; 540 541TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { 542 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 543 RepeatedPtrField<string>::const_iterator c_iter = iter; 544} 545 546TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { 547 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 548 EXPECT_EQ("foo", *iter); 549 ++iter; 550 EXPECT_EQ("bar", *(iter++)); 551 EXPECT_EQ("baz", *iter); 552 ++iter; 553 EXPECT_TRUE(proto_array_.end() == iter); 554 EXPECT_EQ("baz", *(--proto_array_.end())); 555} 556 557TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { 558 const RepeatedPtrField<string>& const_proto_array = proto_array_; 559 RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin(); 560 EXPECT_EQ("foo", *iter); 561 ++iter; 562 EXPECT_EQ("bar", *(iter++)); 563 EXPECT_EQ("baz", *iter); 564 ++iter; 565 EXPECT_TRUE(const_proto_array.end() == iter); 566 EXPECT_EQ("baz", *(--const_proto_array.end())); 567} 568 569TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { 570 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 571 RepeatedPtrField<string>::iterator iter2 = iter; 572 ++iter2; 573 ++iter2; 574 EXPECT_TRUE(iter + 2 == iter2); 575 EXPECT_TRUE(iter == iter2 - 2); 576 EXPECT_EQ("baz", iter[2]); 577 EXPECT_EQ("baz", *(iter + 2)); 578 EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); 579} 580 581TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { 582 RepeatedPtrField<string>::const_iterator iter = proto_array_.begin(); 583 RepeatedPtrField<string>::const_iterator iter2 = iter + 1; 584 EXPECT_TRUE(iter == iter); 585 EXPECT_TRUE(iter != iter2); 586 EXPECT_TRUE(iter < iter2); 587 EXPECT_TRUE(iter <= iter2); 588 EXPECT_TRUE(iter <= iter); 589 EXPECT_TRUE(iter2 > iter); 590 EXPECT_TRUE(iter2 >= iter); 591 EXPECT_TRUE(iter >= iter); 592} 593 594// Uninitialized iterator does not point to any of the RepeatedPtrField. 595// Dereferencing an uninitialized iterator crashes the process. 596TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { 597 RepeatedPtrField<string>::iterator iter; 598 EXPECT_TRUE(iter != proto_array_.begin()); 599 EXPECT_TRUE(iter != proto_array_.begin() + 1); 600 EXPECT_TRUE(iter != proto_array_.begin() + 2); 601 EXPECT_TRUE(iter != proto_array_.begin() + 3); 602 EXPECT_TRUE(iter != proto_array_.end()); 603#ifdef GTEST_HAS_DEATH_TEST 604 ASSERT_DEATH(GOOGLE_LOG(INFO) << *iter, ""); 605#endif 606} 607 608TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { 609 proto_array_.Clear(); 610 proto_array_.Add()->assign("a"); 611 proto_array_.Add()->assign("c"); 612 proto_array_.Add()->assign("d"); 613 proto_array_.Add()->assign("n"); 614 proto_array_.Add()->assign("p"); 615 proto_array_.Add()->assign("x"); 616 proto_array_.Add()->assign("y"); 617 618 string v = "f"; 619 RepeatedPtrField<string>::const_iterator it = 620 lower_bound(proto_array_.begin(), proto_array_.end(), v); 621 EXPECT_EQ(*it, "n"); 622 EXPECT_TRUE(it == proto_array_.begin() + 3); 623} 624 625TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { 626 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 627 *iter = "qux"; 628 EXPECT_EQ("qux", proto_array_.Get(0)); 629} 630 631// ----------------------------------------------------------------------------- 632// Unit-tests for the insert iterators 633// google::protobuf::RepeatedFieldBackInserter, 634// google::protobuf::AllocatedRepeatedPtrFieldBackInserter 635// Ported from util/gtl/proto-array-iterators_unittest. 636 637class RepeatedFieldInsertionIteratorsTest : public testing::Test { 638 protected: 639 std::list<double> halves; 640 std::list<int> fibonacci; 641 std::vector<string> words; 642 typedef TestAllTypes::NestedMessage Nested; 643 Nested nesteds[2]; 644 std::vector<Nested*> nested_ptrs; 645 TestAllTypes protobuffer; 646 647 virtual void SetUp() { 648 fibonacci.push_back(1); 649 fibonacci.push_back(1); 650 fibonacci.push_back(2); 651 fibonacci.push_back(3); 652 fibonacci.push_back(5); 653 fibonacci.push_back(8); 654 std::copy(fibonacci.begin(), fibonacci.end(), 655 RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32())); 656 657 halves.push_back(1.0); 658 halves.push_back(0.5); 659 halves.push_back(0.25); 660 halves.push_back(0.125); 661 halves.push_back(0.0625); 662 std::copy(halves.begin(), halves.end(), 663 RepeatedFieldBackInserter(protobuffer.mutable_repeated_double())); 664 665 words.push_back("Able"); 666 words.push_back("was"); 667 words.push_back("I"); 668 words.push_back("ere"); 669 words.push_back("I"); 670 words.push_back("saw"); 671 words.push_back("Elba"); 672 std::copy(words.begin(), words.end(), 673 RepeatedFieldBackInserter(protobuffer.mutable_repeated_string())); 674 675 nesteds[0].set_bb(17); 676 nesteds[1].set_bb(4711); 677 std::copy(&nesteds[0], &nesteds[2], 678 RepeatedFieldBackInserter( 679 protobuffer.mutable_repeated_nested_message())); 680 681 nested_ptrs.push_back(new Nested); 682 nested_ptrs.back()->set_bb(170); 683 nested_ptrs.push_back(new Nested); 684 nested_ptrs.back()->set_bb(47110); 685 std::copy(nested_ptrs.begin(), nested_ptrs.end(), 686 RepeatedFieldBackInserter( 687 protobuffer.mutable_repeated_nested_message())); 688 689 } 690 691 virtual void TearDown() { 692 STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end()); 693 } 694}; 695 696TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) { 697 EXPECT_TRUE(std::equal(fibonacci.begin(), 698 fibonacci.end(), 699 protobuffer.repeated_int32().begin())); 700 EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(), 701 protobuffer.repeated_int32().end(), 702 fibonacci.begin())); 703} 704 705TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) { 706 EXPECT_TRUE(std::equal(halves.begin(), 707 halves.end(), 708 protobuffer.repeated_double().begin())); 709 EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(), 710 protobuffer.repeated_double().end(), 711 halves.begin())); 712} 713 714TEST_F(RepeatedFieldInsertionIteratorsTest, Words) { 715 ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); 716 EXPECT_EQ(words.at(0), protobuffer.repeated_string(0)); 717 EXPECT_EQ(words.at(1), protobuffer.repeated_string(1)); 718 EXPECT_EQ(words.at(2), protobuffer.repeated_string(2)); 719 EXPECT_EQ(words.at(3), protobuffer.repeated_string(3)); 720 EXPECT_EQ(words.at(4), protobuffer.repeated_string(4)); 721 EXPECT_EQ(words.at(5), protobuffer.repeated_string(5)); 722 EXPECT_EQ(words.at(6), protobuffer.repeated_string(6)); 723} 724 725TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) { 726 ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4); 727 EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17); 728 EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711); 729 EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170); 730 EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110); 731} 732 733TEST_F(RepeatedFieldInsertionIteratorsTest, 734 AllocatedRepeatedPtrFieldWithStringIntData) { 735 vector<Nested*> data; 736 TestAllTypes goldenproto; 737 for (int i = 0; i < 10; ++i) { 738 Nested* new_data = new Nested; 739 new_data->set_bb(i); 740 data.push_back(new_data); 741 742 new_data = goldenproto.add_repeated_nested_message(); 743 new_data->set_bb(i); 744 } 745 TestAllTypes testproto; 746 copy(data.begin(), data.end(), 747 AllocatedRepeatedPtrFieldBackInserter( 748 testproto.mutable_repeated_nested_message())); 749 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); 750} 751 752TEST_F(RepeatedFieldInsertionIteratorsTest, 753 AllocatedRepeatedPtrFieldWithString) { 754 vector<string*> data; 755 TestAllTypes goldenproto; 756 for (int i = 0; i < 10; ++i) { 757 string* new_data = new string; 758 *new_data = "name-" + SimpleItoa(i); 759 data.push_back(new_data); 760 761 new_data = goldenproto.add_repeated_string(); 762 *new_data = "name-" + SimpleItoa(i); 763 } 764 TestAllTypes testproto; 765 copy(data.begin(), data.end(), 766 AllocatedRepeatedPtrFieldBackInserter( 767 testproto.mutable_repeated_string())); 768 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); 769} 770 771} // namespace 772 773} // namespace protobuf 774} // namespace google 775