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 <limits> 40#include <list> 41#include <vector> 42 43#include <google/protobuf/repeated_field.h> 44 45#include <google/protobuf/stubs/common.h> 46#include <google/protobuf/unittest.pb.h> 47#include <google/protobuf/stubs/strutil.h> 48#include <google/protobuf/testing/googletest.h> 49#include <gtest/gtest.h> 50#include <google/protobuf/stubs/stl_util.h> 51 52namespace google { 53using protobuf_unittest::TestAllTypes; 54 55namespace protobuf { 56namespace { 57 58// Test operations on a small RepeatedField. 59TEST(RepeatedField, Small) { 60 RepeatedField<int> field; 61 62 EXPECT_EQ(field.size(), 0); 63 64 field.Add(5); 65 66 EXPECT_EQ(field.size(), 1); 67 EXPECT_EQ(field.Get(0), 5); 68 69 field.Add(42); 70 71 EXPECT_EQ(field.size(), 2); 72 EXPECT_EQ(field.Get(0), 5); 73 EXPECT_EQ(field.Get(1), 42); 74 75 field.Set(1, 23); 76 77 EXPECT_EQ(field.size(), 2); 78 EXPECT_EQ(field.Get(0), 5); 79 EXPECT_EQ(field.Get(1), 23); 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 int expected_usage = 4 * sizeof(int); 90 EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage); 91} 92 93 94// Test operations on a RepeatedField which is large enough to allocate a 95// separate array. 96TEST(RepeatedField, Large) { 97 RepeatedField<int> field; 98 99 for (int i = 0; i < 16; i++) { 100 field.Add(i * i); 101 } 102 103 EXPECT_EQ(field.size(), 16); 104 105 for (int i = 0; i < 16; i++) { 106 EXPECT_EQ(field.Get(i), i * i); 107 } 108 109 int expected_usage = 16 * sizeof(int); 110 EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage); 111} 112 113// Test swapping between various types of RepeatedFields. 114TEST(RepeatedField, SwapSmallSmall) { 115 RepeatedField<int> field1; 116 RepeatedField<int> field2; 117 118 field1.Add(5); 119 field1.Add(42); 120 121 field1.Swap(&field2); 122 123 EXPECT_EQ(field1.size(), 0); 124 EXPECT_EQ(field2.size(), 2); 125 EXPECT_EQ(field2.Get(0), 5); 126 EXPECT_EQ(field2.Get(1), 42); 127} 128 129TEST(RepeatedField, SwapLargeSmall) { 130 RepeatedField<int> field1; 131 RepeatedField<int> field2; 132 133 for (int i = 0; i < 16; i++) { 134 field1.Add(i * i); 135 } 136 field2.Add(5); 137 field2.Add(42); 138 field1.Swap(&field2); 139 140 EXPECT_EQ(field1.size(), 2); 141 EXPECT_EQ(field1.Get(0), 5); 142 EXPECT_EQ(field1.Get(1), 42); 143 EXPECT_EQ(field2.size(), 16); 144 for (int i = 0; i < 16; i++) { 145 EXPECT_EQ(field2.Get(i), i * i); 146 } 147} 148 149TEST(RepeatedField, SwapLargeLarge) { 150 RepeatedField<int> field1; 151 RepeatedField<int> field2; 152 153 field1.Add(5); 154 field1.Add(42); 155 for (int i = 0; i < 16; i++) { 156 field1.Add(i); 157 field2.Add(i * i); 158 } 159 field2.Swap(&field1); 160 161 EXPECT_EQ(field1.size(), 16); 162 for (int i = 0; i < 16; i++) { 163 EXPECT_EQ(field1.Get(i), i * i); 164 } 165 EXPECT_EQ(field2.size(), 18); 166 EXPECT_EQ(field2.Get(0), 5); 167 EXPECT_EQ(field2.Get(1), 42); 168 for (int i = 2; i < 18; i++) { 169 EXPECT_EQ(field2.Get(i), i - 2); 170 } 171} 172 173// Determines how much space was reserved by the given field by adding elements 174// to it until it re-allocates its space. 175static int ReservedSpace(RepeatedField<int>* field) { 176 const int* ptr = field->data(); 177 do { 178 field->Add(0); 179 } while (field->data() == ptr); 180 181 return field->size() - 1; 182} 183 184TEST(RepeatedField, ReserveMoreThanDouble) { 185 // Reserve more than double the previous space in the field and expect the 186 // field to reserve exactly the amount specified. 187 RepeatedField<int> field; 188 field.Reserve(20); 189 190 EXPECT_EQ(20, ReservedSpace(&field)); 191} 192 193TEST(RepeatedField, ReserveLessThanDouble) { 194 // Reserve less than double the previous space in the field and expect the 195 // field to grow by double instead. 196 RepeatedField<int> field; 197 field.Reserve(20); 198 field.Reserve(30); 199 200 EXPECT_EQ(40, ReservedSpace(&field)); 201} 202 203TEST(RepeatedField, ReserveLessThanExisting) { 204 // Reserve less than the previous space in the field and expect the 205 // field to not re-allocate at all. 206 RepeatedField<int> field; 207 field.Reserve(20); 208 const int* previous_ptr = field.data(); 209 field.Reserve(10); 210 211 EXPECT_EQ(previous_ptr, field.data()); 212 EXPECT_EQ(20, ReservedSpace(&field)); 213} 214 215TEST(RepeatedField, MergeFrom) { 216 RepeatedField<int> source, destination; 217 source.Add(4); 218 source.Add(5); 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 EXPECT_EQ(1, destination.Get(0)); 227 EXPECT_EQ(2, destination.Get(1)); 228 EXPECT_EQ(3, destination.Get(2)); 229 EXPECT_EQ(4, destination.Get(3)); 230 EXPECT_EQ(5, destination.Get(4)); 231} 232 233TEST(RepeatedField, CopyFrom) { 234 RepeatedField<int> source, destination; 235 source.Add(4); 236 source.Add(5); 237 destination.Add(1); 238 destination.Add(2); 239 destination.Add(3); 240 241 destination.CopyFrom(source); 242 243 ASSERT_EQ(2, destination.size()); 244 EXPECT_EQ(4, destination.Get(0)); 245 EXPECT_EQ(5, destination.Get(1)); 246} 247 248TEST(RepeatedField, CopyConstruct) { 249 RepeatedField<int> source; 250 source.Add(1); 251 source.Add(2); 252 253 RepeatedField<int> destination(source); 254 255 ASSERT_EQ(2, destination.size()); 256 EXPECT_EQ(1, destination.Get(0)); 257 EXPECT_EQ(2, destination.Get(1)); 258} 259 260TEST(RepeatedField, IteratorConstruct) { 261 vector<int> values; 262 values.push_back(1); 263 values.push_back(2); 264 265 RepeatedField<int> field(values.begin(), values.end()); 266 ASSERT_EQ(values.size(), field.size()); 267 EXPECT_EQ(values[0], field.Get(0)); 268 EXPECT_EQ(values[1], field.Get(1)); 269 270 RepeatedField<int> other(field.begin(), field.end()); 271 ASSERT_EQ(values.size(), other.size()); 272 EXPECT_EQ(values[0], other.Get(0)); 273 EXPECT_EQ(values[1], other.Get(1)); 274} 275 276TEST(RepeatedField, CopyAssign) { 277 RepeatedField<int> source, destination; 278 source.Add(4); 279 source.Add(5); 280 destination.Add(1); 281 destination.Add(2); 282 destination.Add(3); 283 284 destination = source; 285 286 ASSERT_EQ(2, destination.size()); 287 EXPECT_EQ(4, destination.Get(0)); 288 EXPECT_EQ(5, destination.Get(1)); 289} 290 291TEST(RepeatedField, SelfAssign) { 292 // Verify that assignment to self does not destroy data. 293 RepeatedField<int> source, *p; 294 p = &source; 295 source.Add(7); 296 source.Add(8); 297 298 *p = source; 299 300 ASSERT_EQ(2, source.size()); 301 EXPECT_EQ(7, source.Get(0)); 302 EXPECT_EQ(8, source.Get(1)); 303} 304 305TEST(RepeatedField, MutableDataIsMutable) { 306 RepeatedField<int> field; 307 field.Add(1); 308 EXPECT_EQ(1, field.Get(0)); 309 // The fact that this line compiles would be enough, but we'll check the 310 // value anyway. 311 *field.mutable_data() = 2; 312 EXPECT_EQ(2, field.Get(0)); 313} 314 315TEST(RepeatedField, Truncate) { 316 RepeatedField<int> field; 317 318 field.Add(12); 319 field.Add(34); 320 field.Add(56); 321 field.Add(78); 322 EXPECT_EQ(4, field.size()); 323 324 field.Truncate(3); 325 EXPECT_EQ(3, field.size()); 326 327 field.Add(90); 328 EXPECT_EQ(4, field.size()); 329 EXPECT_EQ(90, field.Get(3)); 330 331 // Truncations that don't change the size are allowed, but growing is not 332 // allowed. 333 field.Truncate(field.size()); 334#ifdef PROTOBUF_HAS_DEATH_TEST 335 EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size"); 336#endif 337} 338 339 340TEST(RepeatedField, ExtractSubrange) { 341 // Exhaustively test every subrange in arrays of all sizes from 0 through 9. 342 for (int sz = 0; sz < 10; ++sz) { 343 for (int num = 0; num <= sz; ++num) { 344 for (int start = 0; start < sz - num; ++start) { 345 // Create RepeatedField with sz elements having values 0 through sz-1. 346 RepeatedField<int32> field; 347 for (int i = 0; i < sz; ++i) 348 field.Add(i); 349 EXPECT_EQ(field.size(), sz); 350 351 // Create a catcher array and call ExtractSubrange. 352 int32 catcher[10]; 353 for (int i = 0; i < 10; ++i) 354 catcher[i] = -1; 355 field.ExtractSubrange(start, num, catcher); 356 357 // Does the resulting array have the right size? 358 EXPECT_EQ(field.size(), sz - num); 359 360 // Were the removed elements extracted into the catcher array? 361 for (int i = 0; i < num; ++i) 362 EXPECT_EQ(catcher[i], start + i); 363 EXPECT_EQ(catcher[num], -1); 364 365 // Does the resulting array contain the right values? 366 for (int i = 0; i < start; ++i) 367 EXPECT_EQ(field.Get(i), i); 368 for (int i = start; i < field.size(); ++i) 369 EXPECT_EQ(field.Get(i), i + num); 370 } 371 } 372 } 373} 374 375// =================================================================== 376// RepeatedPtrField tests. These pretty much just mirror the RepeatedField 377// tests above. 378 379TEST(RepeatedPtrField, Small) { 380 RepeatedPtrField<string> field; 381 382 EXPECT_EQ(field.size(), 0); 383 384 field.Add()->assign("foo"); 385 386 EXPECT_EQ(field.size(), 1); 387 EXPECT_EQ(field.Get(0), "foo"); 388 389 field.Add()->assign("bar"); 390 391 EXPECT_EQ(field.size(), 2); 392 EXPECT_EQ(field.Get(0), "foo"); 393 EXPECT_EQ(field.Get(1), "bar"); 394 395 field.Mutable(1)->assign("baz"); 396 397 EXPECT_EQ(field.size(), 2); 398 EXPECT_EQ(field.Get(0), "foo"); 399 EXPECT_EQ(field.Get(1), "baz"); 400 401 field.RemoveLast(); 402 403 EXPECT_EQ(field.size(), 1); 404 EXPECT_EQ(field.Get(0), "foo"); 405 406 field.Clear(); 407 408 EXPECT_EQ(field.size(), 0); 409} 410 411 412TEST(RepeatedPtrField, Large) { 413 RepeatedPtrField<string> field; 414 415 for (int i = 0; i < 16; i++) { 416 *field.Add() += 'a' + i; 417 } 418 419 EXPECT_EQ(field.size(), 16); 420 421 for (int i = 0; i < 16; i++) { 422 EXPECT_EQ(field.Get(i).size(), 1); 423 EXPECT_EQ(field.Get(i)[0], 'a' + i); 424 } 425 426 int min_expected_usage = 16 * sizeof(string); 427 EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); 428} 429 430TEST(RepeatedPtrField, SwapSmallSmall) { 431 RepeatedPtrField<string> field1; 432 RepeatedPtrField<string> field2; 433 434 field1.Add()->assign("foo"); 435 field1.Add()->assign("bar"); 436 field1.Swap(&field2); 437 438 EXPECT_EQ(field1.size(), 0); 439 EXPECT_EQ(field2.size(), 2); 440 EXPECT_EQ(field2.Get(0), "foo"); 441 EXPECT_EQ(field2.Get(1), "bar"); 442} 443 444TEST(RepeatedPtrField, SwapLargeSmall) { 445 RepeatedPtrField<string> field1; 446 RepeatedPtrField<string> field2; 447 448 field2.Add()->assign("foo"); 449 field2.Add()->assign("bar"); 450 for (int i = 0; i < 16; i++) { 451 *field1.Add() += 'a' + i; 452 } 453 field1.Swap(&field2); 454 455 EXPECT_EQ(field1.size(), 2); 456 EXPECT_EQ(field1.Get(0), "foo"); 457 EXPECT_EQ(field1.Get(1), "bar"); 458 EXPECT_EQ(field2.size(), 16); 459 for (int i = 0; i < 16; i++) { 460 EXPECT_EQ(field2.Get(i).size(), 1); 461 EXPECT_EQ(field2.Get(i)[0], 'a' + i); 462 } 463} 464 465TEST(RepeatedPtrField, SwapLargeLarge) { 466 RepeatedPtrField<string> field1; 467 RepeatedPtrField<string> field2; 468 469 field1.Add()->assign("foo"); 470 field1.Add()->assign("bar"); 471 for (int i = 0; i < 16; i++) { 472 *field1.Add() += 'A' + i; 473 *field2.Add() += 'a' + i; 474 } 475 field2.Swap(&field1); 476 477 EXPECT_EQ(field1.size(), 16); 478 for (int i = 0; i < 16; i++) { 479 EXPECT_EQ(field1.Get(i).size(), 1); 480 EXPECT_EQ(field1.Get(i)[0], 'a' + i); 481 } 482 EXPECT_EQ(field2.size(), 18); 483 EXPECT_EQ(field2.Get(0), "foo"); 484 EXPECT_EQ(field2.Get(1), "bar"); 485 for (int i = 2; i < 18; i++) { 486 EXPECT_EQ(field2.Get(i).size(), 1); 487 EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); 488 } 489} 490 491static int ReservedSpace(RepeatedPtrField<string>* field) { 492 const string* const* ptr = field->data(); 493 do { 494 field->Add(); 495 } while (field->data() == ptr); 496 497 return field->size() - 1; 498} 499 500TEST(RepeatedPtrField, ReserveMoreThanDouble) { 501 RepeatedPtrField<string> field; 502 field.Reserve(20); 503 504 EXPECT_EQ(20, ReservedSpace(&field)); 505} 506 507TEST(RepeatedPtrField, ReserveLessThanDouble) { 508 RepeatedPtrField<string> field; 509 field.Reserve(20); 510 field.Reserve(30); 511 512 EXPECT_EQ(40, ReservedSpace(&field)); 513} 514 515TEST(RepeatedPtrField, ReserveLessThanExisting) { 516 RepeatedPtrField<string> field; 517 field.Reserve(20); 518 const string* const* previous_ptr = field.data(); 519 field.Reserve(10); 520 521 EXPECT_EQ(previous_ptr, field.data()); 522 EXPECT_EQ(20, ReservedSpace(&field)); 523} 524 525TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { 526 // Check that a bug is fixed: An earlier implementation of Reserve() 527 // failed to copy pointers to allocated-but-cleared objects, possibly 528 // leading to segfaults. 529 RepeatedPtrField<string> field; 530 string* first = field.Add(); 531 field.RemoveLast(); 532 533 field.Reserve(20); 534 EXPECT_EQ(first, field.Add()); 535} 536 537// Clearing elements is tricky with RepeatedPtrFields since the memory for 538// the elements is retained and reused. 539TEST(RepeatedPtrField, ClearedElements) { 540 RepeatedPtrField<string> field; 541 542 string* original = field.Add(); 543 *original = "foo"; 544 545 EXPECT_EQ(field.ClearedCount(), 0); 546 547 field.RemoveLast(); 548 EXPECT_TRUE(original->empty()); 549 EXPECT_EQ(field.ClearedCount(), 1); 550 551 EXPECT_EQ(field.Add(), original); // Should return same string for reuse. 552 553 EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. 554 EXPECT_EQ(field.ClearedCount(), 0); 555 556 EXPECT_NE(field.Add(), original); // Should NOT return the same string. 557 EXPECT_EQ(field.ClearedCount(), 0); 558 559 field.AddAllocated(original); // Give ownership back. 560 EXPECT_EQ(field.ClearedCount(), 0); 561 EXPECT_EQ(field.Mutable(1), original); 562 563 field.Clear(); 564 EXPECT_EQ(field.ClearedCount(), 2); 565 EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. 566 EXPECT_EQ(field.ClearedCount(), 1); 567 EXPECT_NE(field.Add(), original); 568 EXPECT_EQ(field.ClearedCount(), 0); 569 EXPECT_NE(field.Add(), original); 570 EXPECT_EQ(field.ClearedCount(), 0); 571 572 field.AddCleared(original); // Give ownership back, but as a cleared object. 573 EXPECT_EQ(field.ClearedCount(), 1); 574 EXPECT_EQ(field.Add(), original); 575 EXPECT_EQ(field.ClearedCount(), 0); 576} 577 578// Test all code paths in AddAllocated(). 579TEST(RepeatedPtrField, AddAlocated) { 580 RepeatedPtrField<string> field; 581 while (field.size() < field.Capacity()) { 582 field.Add()->assign("filler"); 583 } 584 585 int index = field.size(); 586 587 // First branch: Field is at capacity with no cleared objects. 588 string* foo = new string("foo"); 589 field.AddAllocated(foo); 590 EXPECT_EQ(index + 1, field.size()); 591 EXPECT_EQ(0, field.ClearedCount()); 592 EXPECT_EQ(foo, &field.Get(index)); 593 594 // Last branch: Field is not at capacity and there are no cleared objects. 595 string* bar = new string("bar"); 596 field.AddAllocated(bar); 597 ++index; 598 EXPECT_EQ(index + 1, field.size()); 599 EXPECT_EQ(0, field.ClearedCount()); 600 EXPECT_EQ(bar, &field.Get(index)); 601 602 // Third branch: Field is not at capacity and there are no cleared objects. 603 field.RemoveLast(); 604 string* baz = new string("baz"); 605 field.AddAllocated(baz); 606 EXPECT_EQ(index + 1, field.size()); 607 EXPECT_EQ(1, field.ClearedCount()); 608 EXPECT_EQ(baz, &field.Get(index)); 609 610 // Second branch: Field is at capacity but has some cleared objects. 611 while (field.size() < field.Capacity()) { 612 field.Add()->assign("filler2"); 613 } 614 field.RemoveLast(); 615 index = field.size(); 616 string* qux = new string("qux"); 617 field.AddAllocated(qux); 618 EXPECT_EQ(index + 1, field.size()); 619 // We should have discarded the cleared object. 620 EXPECT_EQ(0, field.ClearedCount()); 621 EXPECT_EQ(qux, &field.Get(index)); 622} 623 624TEST(RepeatedPtrField, MergeFrom) { 625 RepeatedPtrField<string> source, destination; 626 source.Add()->assign("4"); 627 source.Add()->assign("5"); 628 destination.Add()->assign("1"); 629 destination.Add()->assign("2"); 630 destination.Add()->assign("3"); 631 632 destination.MergeFrom(source); 633 634 ASSERT_EQ(5, destination.size()); 635 EXPECT_EQ("1", destination.Get(0)); 636 EXPECT_EQ("2", destination.Get(1)); 637 EXPECT_EQ("3", destination.Get(2)); 638 EXPECT_EQ("4", destination.Get(3)); 639 EXPECT_EQ("5", destination.Get(4)); 640} 641 642TEST(RepeatedPtrField, CopyFrom) { 643 RepeatedPtrField<string> source, destination; 644 source.Add()->assign("4"); 645 source.Add()->assign("5"); 646 destination.Add()->assign("1"); 647 destination.Add()->assign("2"); 648 destination.Add()->assign("3"); 649 650 destination.CopyFrom(source); 651 652 ASSERT_EQ(2, destination.size()); 653 EXPECT_EQ("4", destination.Get(0)); 654 EXPECT_EQ("5", destination.Get(1)); 655} 656 657TEST(RepeatedPtrField, CopyConstruct) { 658 RepeatedPtrField<string> source; 659 source.Add()->assign("1"); 660 source.Add()->assign("2"); 661 662 RepeatedPtrField<string> destination(source); 663 664 ASSERT_EQ(2, destination.size()); 665 EXPECT_EQ("1", destination.Get(0)); 666 EXPECT_EQ("2", destination.Get(1)); 667} 668 669TEST(RepeatedPtrField, IteratorConstruct_String) { 670 vector<string> values; 671 values.push_back("1"); 672 values.push_back("2"); 673 674 RepeatedPtrField<string> field(values.begin(), values.end()); 675 ASSERT_EQ(values.size(), field.size()); 676 EXPECT_EQ(values[0], field.Get(0)); 677 EXPECT_EQ(values[1], field.Get(1)); 678 679 RepeatedPtrField<string> other(field.begin(), field.end()); 680 ASSERT_EQ(values.size(), other.size()); 681 EXPECT_EQ(values[0], other.Get(0)); 682 EXPECT_EQ(values[1], other.Get(1)); 683} 684 685TEST(RepeatedPtrField, IteratorConstruct_Proto) { 686 typedef TestAllTypes::NestedMessage Nested; 687 vector<Nested> values; 688 values.push_back(Nested()); 689 values.back().set_bb(1); 690 values.push_back(Nested()); 691 values.back().set_bb(2); 692 693 RepeatedPtrField<Nested> field(values.begin(), values.end()); 694 ASSERT_EQ(values.size(), field.size()); 695 EXPECT_EQ(values[0].bb(), field.Get(0).bb()); 696 EXPECT_EQ(values[1].bb(), field.Get(1).bb()); 697 698 RepeatedPtrField<Nested> other(field.begin(), field.end()); 699 ASSERT_EQ(values.size(), other.size()); 700 EXPECT_EQ(values[0].bb(), other.Get(0).bb()); 701 EXPECT_EQ(values[1].bb(), other.Get(1).bb()); 702} 703 704TEST(RepeatedPtrField, CopyAssign) { 705 RepeatedPtrField<string> source, destination; 706 source.Add()->assign("4"); 707 source.Add()->assign("5"); 708 destination.Add()->assign("1"); 709 destination.Add()->assign("2"); 710 destination.Add()->assign("3"); 711 712 destination = source; 713 714 ASSERT_EQ(2, destination.size()); 715 EXPECT_EQ("4", destination.Get(0)); 716 EXPECT_EQ("5", destination.Get(1)); 717} 718 719TEST(RepeatedPtrField, SelfAssign) { 720 // Verify that assignment to self does not destroy data. 721 RepeatedPtrField<string> source, *p; 722 p = &source; 723 source.Add()->assign("7"); 724 source.Add()->assign("8"); 725 726 *p = source; 727 728 ASSERT_EQ(2, source.size()); 729 EXPECT_EQ("7", source.Get(0)); 730 EXPECT_EQ("8", source.Get(1)); 731} 732 733TEST(RepeatedPtrField, MutableDataIsMutable) { 734 RepeatedPtrField<string> field; 735 *field.Add() = "1"; 736 EXPECT_EQ("1", field.Get(0)); 737 // The fact that this line compiles would be enough, but we'll check the 738 // value anyway. 739 string** data = field.mutable_data(); 740 **data = "2"; 741 EXPECT_EQ("2", field.Get(0)); 742} 743 744TEST(RepeatedPtrField, ExtractSubrange) { 745 // Exhaustively test every subrange in arrays of all sizes from 0 through 9 746 // with 0 through 3 cleared elements at the end. 747 for (int sz = 0; sz < 10; ++sz) { 748 for (int num = 0; num <= sz; ++num) { 749 for (int start = 0; start < sz - num; ++start) { 750 for (int extra = 0; extra < 4; ++extra) { 751 vector<string*> subject; 752 753 // Create an array with "sz" elements and "extra" cleared elements. 754 RepeatedPtrField<string> field; 755 for (int i = 0; i < sz + extra; ++i) { 756 subject.push_back(new string()); 757 field.AddAllocated(subject[i]); 758 } 759 EXPECT_EQ(field.size(), sz + extra); 760 for (int i = 0; i < extra; ++i) 761 field.RemoveLast(); 762 EXPECT_EQ(field.size(), sz); 763 EXPECT_EQ(field.ClearedCount(), extra); 764 765 // Create a catcher array and call ExtractSubrange. 766 string* catcher[10]; 767 for (int i = 0; i < 10; ++i) 768 catcher[i] = NULL; 769 field.ExtractSubrange(start, num, catcher); 770 771 // Does the resulting array have the right size? 772 EXPECT_EQ(field.size(), sz - num); 773 774 // Were the removed elements extracted into the catcher array? 775 for (int i = 0; i < num; ++i) 776 EXPECT_EQ(catcher[i], subject[start + i]); 777 EXPECT_EQ(NULL, catcher[num]); 778 779 // Does the resulting array contain the right values? 780 for (int i = 0; i < start; ++i) 781 EXPECT_EQ(field.Mutable(i), subject[i]); 782 for (int i = start; i < field.size(); ++i) 783 EXPECT_EQ(field.Mutable(i), subject[i + num]); 784 785 // Reinstate the cleared elements. 786 EXPECT_EQ(field.ClearedCount(), extra); 787 for (int i = 0; i < extra; ++i) 788 field.Add(); 789 EXPECT_EQ(field.ClearedCount(), 0); 790 EXPECT_EQ(field.size(), sz - num + extra); 791 792 // Make sure the extra elements are all there (in some order). 793 for (int i = sz; i < sz + extra; ++i) { 794 int count = 0; 795 for (int j = sz; j < sz + extra; ++j) { 796 if (field.Mutable(j - num) == subject[i]) 797 count += 1; 798 } 799 EXPECT_EQ(count, 1); 800 } 801 802 // Release the caught elements. 803 for (int i = 0; i < num; ++i) 804 delete catcher[i]; 805 } 806 } 807 } 808 } 809} 810 811TEST(RepeatedPtrField, DeleteSubrange) { 812 // DeleteSubrange is a trivial extension of ExtendSubrange. 813} 814 815// =================================================================== 816 817// Iterator tests stolen from net/proto/proto-array_unittest. 818class RepeatedFieldIteratorTest : public testing::Test { 819 protected: 820 virtual void SetUp() { 821 for (int i = 0; i < 3; ++i) { 822 proto_array_.Add(i); 823 } 824 } 825 826 RepeatedField<int> proto_array_; 827}; 828 829TEST_F(RepeatedFieldIteratorTest, Convertible) { 830 RepeatedField<int>::iterator iter = proto_array_.begin(); 831 RepeatedField<int>::const_iterator c_iter = iter; 832 RepeatedField<int>::value_type value = *c_iter; 833 EXPECT_EQ(0, value); 834} 835 836TEST_F(RepeatedFieldIteratorTest, MutableIteration) { 837 RepeatedField<int>::iterator iter = proto_array_.begin(); 838 EXPECT_EQ(0, *iter); 839 ++iter; 840 EXPECT_EQ(1, *iter++); 841 EXPECT_EQ(2, *iter); 842 ++iter; 843 EXPECT_TRUE(proto_array_.end() == iter); 844 845 EXPECT_EQ(2, *(proto_array_.end() - 1)); 846} 847 848TEST_F(RepeatedFieldIteratorTest, ConstIteration) { 849 const RepeatedField<int>& const_proto_array = proto_array_; 850 RepeatedField<int>::const_iterator iter = const_proto_array.begin(); 851 EXPECT_EQ(0, *iter); 852 ++iter; 853 EXPECT_EQ(1, *iter++); 854 EXPECT_EQ(2, *iter); 855 ++iter; 856 EXPECT_TRUE(proto_array_.end() == iter); 857 EXPECT_EQ(2, *(proto_array_.end() - 1)); 858} 859 860TEST_F(RepeatedFieldIteratorTest, Mutation) { 861 RepeatedField<int>::iterator iter = proto_array_.begin(); 862 *iter = 7; 863 EXPECT_EQ(7, proto_array_.Get(0)); 864} 865 866// ------------------------------------------------------------------- 867 868class RepeatedPtrFieldIteratorTest : public testing::Test { 869 protected: 870 virtual void SetUp() { 871 proto_array_.Add()->assign("foo"); 872 proto_array_.Add()->assign("bar"); 873 proto_array_.Add()->assign("baz"); 874 } 875 876 RepeatedPtrField<string> proto_array_; 877}; 878 879TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { 880 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 881 RepeatedPtrField<string>::const_iterator c_iter = iter; 882 RepeatedPtrField<string>::value_type value = *c_iter; 883 EXPECT_EQ("foo", value); 884} 885 886TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { 887 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 888 EXPECT_EQ("foo", *iter); 889 ++iter; 890 EXPECT_EQ("bar", *(iter++)); 891 EXPECT_EQ("baz", *iter); 892 ++iter; 893 EXPECT_TRUE(proto_array_.end() == iter); 894 EXPECT_EQ("baz", *(--proto_array_.end())); 895} 896 897TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { 898 const RepeatedPtrField<string>& const_proto_array = proto_array_; 899 RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin(); 900 EXPECT_EQ("foo", *iter); 901 ++iter; 902 EXPECT_EQ("bar", *(iter++)); 903 EXPECT_EQ("baz", *iter); 904 ++iter; 905 EXPECT_TRUE(const_proto_array.end() == iter); 906 EXPECT_EQ("baz", *(--const_proto_array.end())); 907} 908 909TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) { 910 RepeatedPtrField<string>::reverse_iterator iter = proto_array_.rbegin(); 911 EXPECT_EQ("baz", *iter); 912 ++iter; 913 EXPECT_EQ("bar", *(iter++)); 914 EXPECT_EQ("foo", *iter); 915 ++iter; 916 EXPECT_TRUE(proto_array_.rend() == iter); 917 EXPECT_EQ("foo", *(--proto_array_.rend())); 918} 919 920TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) { 921 const RepeatedPtrField<string>& const_proto_array = proto_array_; 922 RepeatedPtrField<string>::const_reverse_iterator iter 923 = const_proto_array.rbegin(); 924 EXPECT_EQ("baz", *iter); 925 ++iter; 926 EXPECT_EQ("bar", *(iter++)); 927 EXPECT_EQ("foo", *iter); 928 ++iter; 929 EXPECT_TRUE(const_proto_array.rend() == iter); 930 EXPECT_EQ("foo", *(--const_proto_array.rend())); 931} 932 933TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { 934 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 935 RepeatedPtrField<string>::iterator iter2 = iter; 936 ++iter2; 937 ++iter2; 938 EXPECT_TRUE(iter + 2 == iter2); 939 EXPECT_TRUE(iter == iter2 - 2); 940 EXPECT_EQ("baz", iter[2]); 941 EXPECT_EQ("baz", *(iter + 2)); 942 EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); 943} 944 945TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { 946 RepeatedPtrField<string>::const_iterator iter = proto_array_.begin(); 947 RepeatedPtrField<string>::const_iterator iter2 = iter + 1; 948 EXPECT_TRUE(iter == iter); 949 EXPECT_TRUE(iter != iter2); 950 EXPECT_TRUE(iter < iter2); 951 EXPECT_TRUE(iter <= iter2); 952 EXPECT_TRUE(iter <= iter); 953 EXPECT_TRUE(iter2 > iter); 954 EXPECT_TRUE(iter2 >= iter); 955 EXPECT_TRUE(iter >= iter); 956} 957 958// Uninitialized iterator does not point to any of the RepeatedPtrField. 959TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { 960 RepeatedPtrField<string>::iterator iter; 961 EXPECT_TRUE(iter != proto_array_.begin()); 962 EXPECT_TRUE(iter != proto_array_.begin() + 1); 963 EXPECT_TRUE(iter != proto_array_.begin() + 2); 964 EXPECT_TRUE(iter != proto_array_.begin() + 3); 965 EXPECT_TRUE(iter != proto_array_.end()); 966} 967 968TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { 969 proto_array_.Clear(); 970 proto_array_.Add()->assign("a"); 971 proto_array_.Add()->assign("c"); 972 proto_array_.Add()->assign("d"); 973 proto_array_.Add()->assign("n"); 974 proto_array_.Add()->assign("p"); 975 proto_array_.Add()->assign("x"); 976 proto_array_.Add()->assign("y"); 977 978 string v = "f"; 979 RepeatedPtrField<string>::const_iterator it = 980 lower_bound(proto_array_.begin(), proto_array_.end(), v); 981 982 EXPECT_EQ(*it, "n"); 983 EXPECT_TRUE(it == proto_array_.begin() + 3); 984} 985 986TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { 987 RepeatedPtrField<string>::iterator iter = proto_array_.begin(); 988 *iter = "qux"; 989 EXPECT_EQ("qux", proto_array_.Get(0)); 990} 991 992// ------------------------------------------------------------------- 993 994class RepeatedPtrFieldPtrsIteratorTest : public testing::Test { 995 protected: 996 virtual void SetUp() { 997 proto_array_.Add()->assign("foo"); 998 proto_array_.Add()->assign("bar"); 999 proto_array_.Add()->assign("baz"); 1000 const_proto_array_ = &proto_array_; 1001 } 1002 1003 RepeatedPtrField<string> proto_array_; 1004 const RepeatedPtrField<string>* const_proto_array_; 1005}; 1006 1007TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) { 1008 RepeatedPtrField<string>::pointer_iterator iter = 1009 proto_array_.pointer_begin(); 1010 (void) iter; 1011} 1012 1013TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) { 1014 RepeatedPtrField<string>::const_pointer_iterator iter = 1015 const_proto_array_->pointer_begin(); 1016 (void) iter; 1017} 1018 1019TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) { 1020 RepeatedPtrField<string>::pointer_iterator iter = 1021 proto_array_.pointer_begin(); 1022 EXPECT_EQ("foo", **iter); 1023 ++iter; 1024 EXPECT_EQ("bar", **(iter++)); 1025 EXPECT_EQ("baz", **iter); 1026 ++iter; 1027 EXPECT_TRUE(proto_array_.pointer_end() == iter); 1028 EXPECT_EQ("baz", **(--proto_array_.pointer_end())); 1029} 1030 1031TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) { 1032 RepeatedPtrField<string>::const_pointer_iterator iter = 1033 const_proto_array_->pointer_begin(); 1034 EXPECT_EQ("foo", **iter); 1035 ++iter; 1036 EXPECT_EQ("bar", **(iter++)); 1037 EXPECT_EQ("baz", **iter); 1038 ++iter; 1039 EXPECT_TRUE(const_proto_array_->pointer_end() == iter); 1040 EXPECT_EQ("baz", **(--const_proto_array_->pointer_end())); 1041} 1042 1043TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) { 1044 RepeatedPtrField<string>::pointer_iterator iter = 1045 proto_array_.pointer_begin(); 1046 RepeatedPtrField<string>::pointer_iterator iter2 = iter; 1047 ++iter2; 1048 ++iter2; 1049 EXPECT_TRUE(iter + 2 == iter2); 1050 EXPECT_TRUE(iter == iter2 - 2); 1051 EXPECT_EQ("baz", *iter[2]); 1052 EXPECT_EQ("baz", **(iter + 2)); 1053 EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); 1054} 1055 1056TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) { 1057 RepeatedPtrField<string>::const_pointer_iterator iter = 1058 const_proto_array_->pointer_begin(); 1059 RepeatedPtrField<string>::const_pointer_iterator iter2 = iter; 1060 ++iter2; 1061 ++iter2; 1062 EXPECT_TRUE(iter + 2 == iter2); 1063 EXPECT_TRUE(iter == iter2 - 2); 1064 EXPECT_EQ("baz", *iter[2]); 1065 EXPECT_EQ("baz", **(iter + 2)); 1066 EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin()); 1067} 1068 1069TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) { 1070 RepeatedPtrField<string>::pointer_iterator iter = 1071 proto_array_.pointer_begin(); 1072 RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1; 1073 EXPECT_TRUE(iter == iter); 1074 EXPECT_TRUE(iter != iter2); 1075 EXPECT_TRUE(iter < iter2); 1076 EXPECT_TRUE(iter <= iter2); 1077 EXPECT_TRUE(iter <= iter); 1078 EXPECT_TRUE(iter2 > iter); 1079 EXPECT_TRUE(iter2 >= iter); 1080 EXPECT_TRUE(iter >= iter); 1081} 1082 1083TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) { 1084 RepeatedPtrField<string>::const_pointer_iterator iter = 1085 const_proto_array_->pointer_begin(); 1086 RepeatedPtrField<string>::const_pointer_iterator iter2 = iter + 1; 1087 EXPECT_TRUE(iter == iter); 1088 EXPECT_TRUE(iter != iter2); 1089 EXPECT_TRUE(iter < iter2); 1090 EXPECT_TRUE(iter <= iter2); 1091 EXPECT_TRUE(iter <= iter); 1092 EXPECT_TRUE(iter2 > iter); 1093 EXPECT_TRUE(iter2 >= iter); 1094 EXPECT_TRUE(iter >= iter); 1095} 1096 1097// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs. 1098// Dereferencing an uninitialized iterator crashes the process. 1099TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) { 1100 RepeatedPtrField<string>::pointer_iterator iter; 1101 EXPECT_TRUE(iter != proto_array_.pointer_begin()); 1102 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1); 1103 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2); 1104 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3); 1105 EXPECT_TRUE(iter != proto_array_.pointer_end()); 1106} 1107 1108TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) { 1109 RepeatedPtrField<string>::const_pointer_iterator iter; 1110 EXPECT_TRUE(iter != const_proto_array_->pointer_begin()); 1111 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1); 1112 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2); 1113 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3); 1114 EXPECT_TRUE(iter != const_proto_array_->pointer_end()); 1115} 1116 1117// This comparison functor is required by the tests for RepeatedPtrOverPtrs. 1118// They operate on strings and need to compare strings as strings in 1119// any stl algorithm, even though the iterator returns a pointer to a string 1120// - i.e. *iter has type string*. 1121struct StringLessThan { 1122 bool operator()(const string* z, const string& y) { 1123 return *z < y; 1124 } 1125 bool operator()(const string* z, const string* y) { 1126 return *z < *y; 1127 } 1128}; 1129 1130TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) { 1131 proto_array_.Clear(); 1132 proto_array_.Add()->assign("a"); 1133 proto_array_.Add()->assign("c"); 1134 proto_array_.Add()->assign("d"); 1135 proto_array_.Add()->assign("n"); 1136 proto_array_.Add()->assign("p"); 1137 proto_array_.Add()->assign("x"); 1138 proto_array_.Add()->assign("y"); 1139 1140 { 1141 string v = "f"; 1142 RepeatedPtrField<string>::pointer_iterator it = 1143 lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(), 1144 &v, StringLessThan()); 1145 1146 GOOGLE_CHECK(*it != NULL); 1147 1148 EXPECT_EQ(**it, "n"); 1149 EXPECT_TRUE(it == proto_array_.pointer_begin() + 3); 1150 } 1151 { 1152 string v = "f"; 1153 RepeatedPtrField<string>::const_pointer_iterator it = 1154 lower_bound(const_proto_array_->pointer_begin(), 1155 const_proto_array_->pointer_end(), 1156 &v, StringLessThan()); 1157 1158 GOOGLE_CHECK(*it != NULL); 1159 1160 EXPECT_EQ(**it, "n"); 1161 EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3); 1162 } 1163} 1164 1165TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) { 1166 RepeatedPtrField<string>::pointer_iterator iter = 1167 proto_array_.pointer_begin(); 1168 **iter = "qux"; 1169 EXPECT_EQ("qux", proto_array_.Get(0)); 1170 1171 EXPECT_EQ("bar", proto_array_.Get(1)); 1172 EXPECT_EQ("baz", proto_array_.Get(2)); 1173 ++iter; 1174 delete *iter; 1175 *iter = new string("a"); 1176 ++iter; 1177 delete *iter; 1178 *iter = new string("b"); 1179 EXPECT_EQ("a", proto_array_.Get(1)); 1180 EXPECT_EQ("b", proto_array_.Get(2)); 1181} 1182 1183TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) { 1184 proto_array_.Add()->assign("c"); 1185 proto_array_.Add()->assign("d"); 1186 proto_array_.Add()->assign("n"); 1187 proto_array_.Add()->assign("p"); 1188 proto_array_.Add()->assign("a"); 1189 proto_array_.Add()->assign("y"); 1190 proto_array_.Add()->assign("x"); 1191 EXPECT_EQ("foo", proto_array_.Get(0)); 1192 EXPECT_EQ("n", proto_array_.Get(5)); 1193 EXPECT_EQ("x", proto_array_.Get(9)); 1194 sort(proto_array_.pointer_begin(), 1195 proto_array_.pointer_end(), 1196 StringLessThan()); 1197 EXPECT_EQ("a", proto_array_.Get(0)); 1198 EXPECT_EQ("baz", proto_array_.Get(2)); 1199 EXPECT_EQ("y", proto_array_.Get(9)); 1200} 1201 1202 1203// ----------------------------------------------------------------------------- 1204// Unit-tests for the insert iterators 1205// google::protobuf::RepeatedFieldBackInserter, 1206// google::protobuf::AllocatedRepeatedPtrFieldBackInserter 1207// Ported from util/gtl/proto-array-iterators_unittest. 1208 1209class RepeatedFieldInsertionIteratorsTest : public testing::Test { 1210 protected: 1211 std::list<double> halves; 1212 std::list<int> fibonacci; 1213 std::vector<string> words; 1214 typedef TestAllTypes::NestedMessage Nested; 1215 Nested nesteds[2]; 1216 std::vector<Nested*> nested_ptrs; 1217 TestAllTypes protobuffer; 1218 1219 virtual void SetUp() { 1220 fibonacci.push_back(1); 1221 fibonacci.push_back(1); 1222 fibonacci.push_back(2); 1223 fibonacci.push_back(3); 1224 fibonacci.push_back(5); 1225 fibonacci.push_back(8); 1226 std::copy(fibonacci.begin(), fibonacci.end(), 1227 RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32())); 1228 1229 halves.push_back(1.0); 1230 halves.push_back(0.5); 1231 halves.push_back(0.25); 1232 halves.push_back(0.125); 1233 halves.push_back(0.0625); 1234 std::copy(halves.begin(), halves.end(), 1235 RepeatedFieldBackInserter(protobuffer.mutable_repeated_double())); 1236 1237 words.push_back("Able"); 1238 words.push_back("was"); 1239 words.push_back("I"); 1240 words.push_back("ere"); 1241 words.push_back("I"); 1242 words.push_back("saw"); 1243 words.push_back("Elba"); 1244 std::copy(words.begin(), words.end(), 1245 RepeatedFieldBackInserter(protobuffer.mutable_repeated_string())); 1246 1247 nesteds[0].set_bb(17); 1248 nesteds[1].set_bb(4711); 1249 std::copy(&nesteds[0], &nesteds[2], 1250 RepeatedFieldBackInserter( 1251 protobuffer.mutable_repeated_nested_message())); 1252 1253 nested_ptrs.push_back(new Nested); 1254 nested_ptrs.back()->set_bb(170); 1255 nested_ptrs.push_back(new Nested); 1256 nested_ptrs.back()->set_bb(47110); 1257 std::copy(nested_ptrs.begin(), nested_ptrs.end(), 1258 RepeatedFieldBackInserter( 1259 protobuffer.mutable_repeated_nested_message())); 1260 1261 } 1262 1263 virtual void TearDown() { 1264 STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end()); 1265 } 1266}; 1267 1268TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) { 1269 EXPECT_TRUE(std::equal(fibonacci.begin(), 1270 fibonacci.end(), 1271 protobuffer.repeated_int32().begin())); 1272 EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(), 1273 protobuffer.repeated_int32().end(), 1274 fibonacci.begin())); 1275} 1276 1277TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) { 1278 EXPECT_TRUE(std::equal(halves.begin(), 1279 halves.end(), 1280 protobuffer.repeated_double().begin())); 1281 EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(), 1282 protobuffer.repeated_double().end(), 1283 halves.begin())); 1284} 1285 1286TEST_F(RepeatedFieldInsertionIteratorsTest, Words) { 1287 ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); 1288 for (int i = 0; i < words.size(); ++i) 1289 EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); 1290} 1291 1292TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) { 1293 words.clear(); 1294 words.push_back("sing"); 1295 words.push_back("a"); 1296 words.push_back("song"); 1297 words.push_back("of"); 1298 words.push_back("six"); 1299 words.push_back("pence"); 1300 protobuffer.mutable_repeated_string()->Clear(); 1301 std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter( 1302 protobuffer.mutable_repeated_string())); 1303 ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); 1304 for (int i = 0; i < words.size(); ++i) 1305 EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); 1306} 1307 1308TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) { 1309 ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4); 1310 EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17); 1311 EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711); 1312 EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170); 1313 EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110); 1314} 1315 1316TEST_F(RepeatedFieldInsertionIteratorsTest, 1317 AllocatedRepeatedPtrFieldWithStringIntData) { 1318 vector<Nested*> data; 1319 TestAllTypes goldenproto; 1320 for (int i = 0; i < 10; ++i) { 1321 Nested* new_data = new Nested; 1322 new_data->set_bb(i); 1323 data.push_back(new_data); 1324 1325 new_data = goldenproto.add_repeated_nested_message(); 1326 new_data->set_bb(i); 1327 } 1328 TestAllTypes testproto; 1329 copy(data.begin(), data.end(), 1330 AllocatedRepeatedPtrFieldBackInserter( 1331 testproto.mutable_repeated_nested_message())); 1332 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); 1333} 1334 1335TEST_F(RepeatedFieldInsertionIteratorsTest, 1336 AllocatedRepeatedPtrFieldWithString) { 1337 vector<string*> data; 1338 TestAllTypes goldenproto; 1339 for (int i = 0; i < 10; ++i) { 1340 string* new_data = new string; 1341 *new_data = "name-" + SimpleItoa(i); 1342 data.push_back(new_data); 1343 1344 new_data = goldenproto.add_repeated_string(); 1345 *new_data = "name-" + SimpleItoa(i); 1346 } 1347 TestAllTypes testproto; 1348 copy(data.begin(), data.end(), 1349 AllocatedRepeatedPtrFieldBackInserter( 1350 testproto.mutable_repeated_string())); 1351 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); 1352} 1353 1354} // namespace 1355 1356} // namespace protobuf 1357} // namespace google 1358