Home | History | Annotate | Download | only in protobuf
      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 (at) 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 #include <vector>
     41 
     42 #include <google/protobuf/repeated_field.h>
     43 
     44 #include <google/protobuf/stubs/common.h>
     45 #include <google/protobuf/unittest.pb.h>
     46 #include <google/protobuf/stubs/strutil.h>
     47 #include <google/protobuf/testing/googletest.h>
     48 #include <gtest/gtest.h>
     49 #include <google/protobuf/stubs/stl_util-inl.h>
     50 
     51 namespace google {
     52 using protobuf_unittest::TestAllTypes;
     53 
     54 namespace protobuf {
     55 namespace {
     56 
     57 // Test operations on a RepeatedField which is small enough that it does
     58 // not allocate a separate array for storage.
     59 TEST(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   EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
     81 
     82   field.RemoveLast();
     83 
     84   EXPECT_EQ(field.size(), 1);
     85   EXPECT_EQ(field.Get(0), 5);
     86 
     87   field.Clear();
     88 
     89   EXPECT_EQ(field.size(), 0);
     90   EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
     91 }
     92 
     93 // Test operations on a RepeatedField which is large enough to allocate a
     94 // separate array.
     95 TEST(RepeatedField, Large) {
     96   RepeatedField<int> field;
     97 
     98   for (int i = 0; i < 16; i++) {
     99     field.Add(i * i);
    100   }
    101 
    102   EXPECT_EQ(field.size(), 16);
    103 
    104   for (int i = 0; i < 16; i++) {
    105     EXPECT_EQ(field.Get(i), i * i);
    106   }
    107 
    108   int expected_usage = 16 * sizeof(int);
    109   EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
    110 }
    111 
    112 // Test swapping between various types of RepeatedFields.
    113 TEST(RepeatedField, SwapSmallSmall) {
    114   RepeatedField<int> field1;
    115   RepeatedField<int> field2;
    116 
    117   field1.Add(5);
    118   field1.Add(42);
    119 
    120   field1.Swap(&field2);
    121 
    122   EXPECT_EQ(field1.size(), 0);
    123   EXPECT_EQ(field2.size(), 2);
    124   EXPECT_EQ(field2.Get(0), 5);
    125   EXPECT_EQ(field2.Get(1), 42);
    126 }
    127 
    128 TEST(RepeatedField, SwapLargeSmall) {
    129   RepeatedField<int> field1;
    130   RepeatedField<int> field2;
    131 
    132   for (int i = 0; i < 16; i++) {
    133     field1.Add(i * i);
    134   }
    135   field2.Add(5);
    136   field2.Add(42);
    137   field1.Swap(&field2);
    138 
    139   EXPECT_EQ(field1.size(), 2);
    140   EXPECT_EQ(field1.Get(0), 5);
    141   EXPECT_EQ(field1.Get(1), 42);
    142   EXPECT_EQ(field2.size(), 16);
    143   for (int i = 0; i < 16; i++) {
    144     EXPECT_EQ(field2.Get(i), i * i);
    145   }
    146 }
    147 
    148 TEST(RepeatedField, SwapLargeLarge) {
    149   RepeatedField<int> field1;
    150   RepeatedField<int> field2;
    151 
    152   field1.Add(5);
    153   field1.Add(42);
    154   for (int i = 0; i < 16; i++) {
    155     field1.Add(i);
    156     field2.Add(i * i);
    157   }
    158   field2.Swap(&field1);
    159 
    160   EXPECT_EQ(field1.size(), 16);
    161   for (int i = 0; i < 16; i++) {
    162     EXPECT_EQ(field1.Get(i), i * i);
    163   }
    164   EXPECT_EQ(field2.size(), 18);
    165   EXPECT_EQ(field2.Get(0), 5);
    166   EXPECT_EQ(field2.Get(1), 42);
    167   for (int i = 2; i < 18; i++) {
    168     EXPECT_EQ(field2.Get(i), i - 2);
    169   }
    170 }
    171 
    172 // Determines how much space was reserved by the given field by adding elements
    173 // to it until it re-allocates its space.
    174 static int ReservedSpace(RepeatedField<int>* field) {
    175   const int* ptr = field->data();
    176   do {
    177     field->Add(0);
    178   } while (field->data() == ptr);
    179 
    180   return field->size() - 1;
    181 }
    182 
    183 TEST(RepeatedField, ReserveMoreThanDouble) {
    184   // Reserve more than double the previous space in the field and expect the
    185   // field to reserve exactly the amount specified.
    186   RepeatedField<int> field;
    187   field.Reserve(20);
    188 
    189   EXPECT_EQ(20, ReservedSpace(&field));
    190 }
    191 
    192 TEST(RepeatedField, ReserveLessThanDouble) {
    193   // Reserve less than double the previous space in the field and expect the
    194   // field to grow by double instead.
    195   RepeatedField<int> field;
    196   field.Reserve(20);
    197   field.Reserve(30);
    198 
    199   EXPECT_EQ(40, ReservedSpace(&field));
    200 }
    201 
    202 TEST(RepeatedField, ReserveLessThanExisting) {
    203   // Reserve less than the previous space in the field and expect the
    204   // field to not re-allocate at all.
    205   RepeatedField<int> field;
    206   field.Reserve(20);
    207   const int* previous_ptr = field.data();
    208   field.Reserve(10);
    209 
    210   EXPECT_EQ(previous_ptr, field.data());
    211   EXPECT_EQ(20, ReservedSpace(&field));
    212 }
    213 
    214 TEST(RepeatedField, MergeFrom) {
    215   RepeatedField<int> source, destination;
    216 
    217   source.Add(4);
    218   source.Add(5);
    219 
    220   destination.Add(1);
    221   destination.Add(2);
    222   destination.Add(3);
    223 
    224   destination.MergeFrom(source);
    225 
    226   ASSERT_EQ(5, destination.size());
    227 
    228   EXPECT_EQ(1, destination.Get(0));
    229   EXPECT_EQ(2, destination.Get(1));
    230   EXPECT_EQ(3, destination.Get(2));
    231   EXPECT_EQ(4, destination.Get(3));
    232   EXPECT_EQ(5, destination.Get(4));
    233 }
    234 
    235 TEST(RepeatedField, MutableDataIsMutable) {
    236   RepeatedField<int> field;
    237   field.Add(1);
    238   EXPECT_EQ(1, field.Get(0));
    239   // The fact that this line compiles would be enough, but we'll check the
    240   // value anyway.
    241   *field.mutable_data() = 2;
    242   EXPECT_EQ(2, field.Get(0));
    243 }
    244 
    245 TEST(RepeatedField, Truncate) {
    246   RepeatedField<int> field;
    247 
    248   field.Add(12);
    249   field.Add(34);
    250   field.Add(56);
    251   field.Add(78);
    252   EXPECT_EQ(4, field.size());
    253 
    254   field.Truncate(3);
    255   EXPECT_EQ(3, field.size());
    256 
    257   field.Add(90);
    258   EXPECT_EQ(4, field.size());
    259   EXPECT_EQ(90, field.Get(3));
    260 
    261   // Truncations that don't change the size are allowed, but growing is not
    262   // allowed.
    263   field.Truncate(field.size());
    264 #ifdef GTEST_HAS_DEATH_TEST
    265   EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
    266 #endif
    267 }
    268 
    269 
    270 // ===================================================================
    271 // RepeatedPtrField tests.  These pretty much just mirror the RepeatedField
    272 // tests above.
    273 
    274 TEST(RepeatedPtrField, Small) {
    275   RepeatedPtrField<string> field;
    276 
    277   EXPECT_EQ(field.size(), 0);
    278 
    279   field.Add()->assign("foo");
    280 
    281   EXPECT_EQ(field.size(), 1);
    282   EXPECT_EQ(field.Get(0), "foo");
    283 
    284   field.Add()->assign("bar");
    285 
    286   EXPECT_EQ(field.size(), 2);
    287   EXPECT_EQ(field.Get(0), "foo");
    288   EXPECT_EQ(field.Get(1), "bar");
    289 
    290   field.Mutable(1)->assign("baz");
    291 
    292   EXPECT_EQ(field.size(), 2);
    293   EXPECT_EQ(field.Get(0), "foo");
    294   EXPECT_EQ(field.Get(1), "baz");
    295 
    296   field.RemoveLast();
    297 
    298   EXPECT_EQ(field.size(), 1);
    299   EXPECT_EQ(field.Get(0), "foo");
    300 
    301   field.Clear();
    302 
    303   EXPECT_EQ(field.size(), 0);
    304 }
    305 
    306 TEST(RepeatedPtrField, Large) {
    307   RepeatedPtrField<string> field;
    308 
    309   for (int i = 0; i < 16; i++) {
    310     *field.Add() += 'a' + i;
    311   }
    312 
    313   EXPECT_EQ(field.size(), 16);
    314 
    315   for (int i = 0; i < 16; i++) {
    316     EXPECT_EQ(field.Get(i).size(), 1);
    317     EXPECT_EQ(field.Get(i)[0], 'a' + i);
    318   }
    319 
    320   int min_expected_usage = 16 * sizeof(string);
    321   EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
    322 }
    323 
    324 TEST(RepeatedPtrField, SwapSmallSmall) {
    325   RepeatedPtrField<string> field1;
    326   RepeatedPtrField<string> field2;
    327 
    328   field1.Add()->assign("foo");
    329   field1.Add()->assign("bar");
    330   field1.Swap(&field2);
    331 
    332   EXPECT_EQ(field1.size(), 0);
    333   EXPECT_EQ(field2.size(), 2);
    334   EXPECT_EQ(field2.Get(0), "foo");
    335   EXPECT_EQ(field2.Get(1), "bar");
    336 }
    337 
    338 TEST(RepeatedPtrField, SwapLargeSmall) {
    339   RepeatedPtrField<string> field1;
    340   RepeatedPtrField<string> field2;
    341 
    342   field2.Add()->assign("foo");
    343   field2.Add()->assign("bar");
    344   for (int i = 0; i < 16; i++) {
    345     *field1.Add() += 'a' + i;
    346   }
    347   field1.Swap(&field2);
    348 
    349   EXPECT_EQ(field1.size(), 2);
    350   EXPECT_EQ(field1.Get(0), "foo");
    351   EXPECT_EQ(field1.Get(1), "bar");
    352   EXPECT_EQ(field2.size(), 16);
    353   for (int i = 0; i < 16; i++) {
    354     EXPECT_EQ(field2.Get(i).size(), 1);
    355     EXPECT_EQ(field2.Get(i)[0], 'a' + i);
    356   }
    357 }
    358 
    359 TEST(RepeatedPtrField, SwapLargeLarge) {
    360   RepeatedPtrField<string> field1;
    361   RepeatedPtrField<string> field2;
    362 
    363   field1.Add()->assign("foo");
    364   field1.Add()->assign("bar");
    365   for (int i = 0; i < 16; i++) {
    366     *field1.Add() += 'A' + i;
    367     *field2.Add() += 'a' + i;
    368   }
    369   field2.Swap(&field1);
    370 
    371   EXPECT_EQ(field1.size(), 16);
    372   for (int i = 0; i < 16; i++) {
    373     EXPECT_EQ(field1.Get(i).size(), 1);
    374     EXPECT_EQ(field1.Get(i)[0], 'a' + i);
    375   }
    376   EXPECT_EQ(field2.size(), 18);
    377   EXPECT_EQ(field2.Get(0), "foo");
    378   EXPECT_EQ(field2.Get(1), "bar");
    379   for (int i = 2; i < 18; i++) {
    380     EXPECT_EQ(field2.Get(i).size(), 1);
    381     EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
    382   }
    383 }
    384 
    385 static int ReservedSpace(RepeatedPtrField<string>* field) {
    386   const string* const* ptr = field->data();
    387   do {
    388     field->Add();
    389   } while (field->data() == ptr);
    390 
    391   return field->size() - 1;
    392 }
    393 
    394 TEST(RepeatedPtrField, ReserveMoreThanDouble) {
    395   RepeatedPtrField<string> field;
    396   field.Reserve(20);
    397 
    398   EXPECT_EQ(20, ReservedSpace(&field));
    399 }
    400 
    401 TEST(RepeatedPtrField, ReserveLessThanDouble) {
    402   RepeatedPtrField<string> field;
    403   field.Reserve(20);
    404   field.Reserve(30);
    405 
    406   EXPECT_EQ(40, ReservedSpace(&field));
    407 }
    408 
    409 TEST(RepeatedPtrField, ReserveLessThanExisting) {
    410   RepeatedPtrField<string> field;
    411   field.Reserve(20);
    412   const string* const* previous_ptr = field.data();
    413   field.Reserve(10);
    414 
    415   EXPECT_EQ(previous_ptr, field.data());
    416   EXPECT_EQ(20, ReservedSpace(&field));
    417 }
    418 
    419 TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
    420   // Check that a bug is fixed:  An earlier implementation of Reserve()
    421   // failed to copy pointers to allocated-but-cleared objects, possibly
    422   // leading to segfaults.
    423   RepeatedPtrField<string> field;
    424   string* first = field.Add();
    425   field.RemoveLast();
    426 
    427   field.Reserve(20);
    428   EXPECT_EQ(first, field.Add());
    429 }
    430 
    431 // Clearing elements is tricky with RepeatedPtrFields since the memory for
    432 // the elements is retained and reused.
    433 TEST(RepeatedPtrField, ClearedElements) {
    434   RepeatedPtrField<string> field;
    435 
    436   string* original = field.Add();
    437   *original = "foo";
    438 
    439   EXPECT_EQ(field.ClearedCount(), 0);
    440 
    441   field.RemoveLast();
    442   EXPECT_TRUE(original->empty());
    443   EXPECT_EQ(field.ClearedCount(), 1);
    444 
    445   EXPECT_EQ(field.Add(), original);  // Should return same string for reuse.
    446 
    447   EXPECT_EQ(field.ReleaseLast(), original);  // We take ownership.
    448   EXPECT_EQ(field.ClearedCount(), 0);
    449 
    450   EXPECT_NE(field.Add(), original);  // Should NOT return the same string.
    451   EXPECT_EQ(field.ClearedCount(), 0);
    452 
    453   field.AddAllocated(original);  // Give ownership back.
    454   EXPECT_EQ(field.ClearedCount(), 0);
    455   EXPECT_EQ(field.Mutable(1), original);
    456 
    457   field.Clear();
    458   EXPECT_EQ(field.ClearedCount(), 2);
    459   EXPECT_EQ(field.ReleaseCleared(), original);  // Take ownership again.
    460   EXPECT_EQ(field.ClearedCount(), 1);
    461   EXPECT_NE(field.Add(), original);
    462   EXPECT_EQ(field.ClearedCount(), 0);
    463   EXPECT_NE(field.Add(), original);
    464   EXPECT_EQ(field.ClearedCount(), 0);
    465 
    466   field.AddCleared(original);  // Give ownership back, but as a cleared object.
    467   EXPECT_EQ(field.ClearedCount(), 1);
    468   EXPECT_EQ(field.Add(), original);
    469   EXPECT_EQ(field.ClearedCount(), 0);
    470 }
    471 
    472 // Test all code paths in AddAllocated().
    473 TEST(RepeatedPtrField, AddAlocated) {
    474   RepeatedPtrField<string> field;
    475   while (field.size() < field.Capacity()) {
    476     field.Add()->assign("filler");
    477   }
    478 
    479   int index = field.size();
    480 
    481   // First branch:  Field is at capacity with no cleared objects.
    482   string* foo = new string("foo");
    483   field.AddAllocated(foo);
    484   EXPECT_EQ(index + 1, field.size());
    485   EXPECT_EQ(0, field.ClearedCount());
    486   EXPECT_EQ(foo, &field.Get(index));
    487 
    488   // Last branch:  Field is not at capacity and there are no cleared objects.
    489   string* bar = new string("bar");
    490   field.AddAllocated(bar);
    491   ++index;
    492   EXPECT_EQ(index + 1, field.size());
    493   EXPECT_EQ(0, field.ClearedCount());
    494   EXPECT_EQ(bar, &field.Get(index));
    495 
    496   // Third branch:  Field is not at capacity and there are no cleared objects.
    497   field.RemoveLast();
    498   string* baz = new string("baz");
    499   field.AddAllocated(baz);
    500   EXPECT_EQ(index + 1, field.size());
    501   EXPECT_EQ(1, field.ClearedCount());
    502   EXPECT_EQ(baz, &field.Get(index));
    503 
    504   // Second branch:  Field is at capacity but has some cleared objects.
    505   while (field.size() < field.Capacity()) {
    506     field.Add()->assign("filler2");
    507   }
    508   field.RemoveLast();
    509   index = field.size();
    510   string* qux = new string("qux");
    511   field.AddAllocated(qux);
    512   EXPECT_EQ(index + 1, field.size());
    513   // We should have discarded the cleared object.
    514   EXPECT_EQ(0, field.ClearedCount());
    515   EXPECT_EQ(qux, &field.Get(index));
    516 }
    517 
    518 TEST(RepeatedPtrField, MergeFrom) {
    519   RepeatedPtrField<string> source, destination;
    520 
    521   source.Add()->assign("4");
    522   source.Add()->assign("5");
    523 
    524   destination.Add()->assign("1");
    525   destination.Add()->assign("2");
    526   destination.Add()->assign("3");
    527 
    528   destination.MergeFrom(source);
    529 
    530   ASSERT_EQ(5, destination.size());
    531 
    532   EXPECT_EQ("1", destination.Get(0));
    533   EXPECT_EQ("2", destination.Get(1));
    534   EXPECT_EQ("3", destination.Get(2));
    535   EXPECT_EQ("4", destination.Get(3));
    536   EXPECT_EQ("5", destination.Get(4));
    537 }
    538 
    539 TEST(RepeatedPtrField, MutableDataIsMutable) {
    540   RepeatedPtrField<string> field;
    541   *field.Add() = "1";
    542   EXPECT_EQ("1", field.Get(0));
    543   // The fact that this line compiles would be enough, but we'll check the
    544   // value anyway.
    545   string** data = field.mutable_data();
    546   **data = "2";
    547   EXPECT_EQ("2", field.Get(0));
    548 }
    549 
    550 // ===================================================================
    551 
    552 // Iterator tests stolen from net/proto/proto-array_unittest.
    553 class RepeatedFieldIteratorTest : public testing::Test {
    554  protected:
    555   virtual void SetUp() {
    556     for (int i = 0; i < 3; ++i) {
    557       proto_array_.Add(i);
    558     }
    559   }
    560 
    561   RepeatedField<int> proto_array_;
    562 };
    563 
    564 TEST_F(RepeatedFieldIteratorTest, Convertible) {
    565   RepeatedField<int>::iterator iter = proto_array_.begin();
    566   RepeatedField<int>::const_iterator c_iter = iter;
    567   EXPECT_EQ(0, *c_iter);
    568 }
    569 
    570 TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
    571   RepeatedField<int>::iterator iter = proto_array_.begin();
    572   EXPECT_EQ(0, *iter);
    573   ++iter;
    574   EXPECT_EQ(1, *iter++);
    575   EXPECT_EQ(2, *iter);
    576   ++iter;
    577   EXPECT_TRUE(proto_array_.end() == iter);
    578 
    579   EXPECT_EQ(2, *(proto_array_.end() - 1));
    580 }
    581 
    582 TEST_F(RepeatedFieldIteratorTest, ConstIteration) {
    583   const RepeatedField<int>& const_proto_array = proto_array_;
    584   RepeatedField<int>::const_iterator iter = const_proto_array.begin();
    585   EXPECT_EQ(0, *iter);
    586   ++iter;
    587   EXPECT_EQ(1, *iter++);
    588   EXPECT_EQ(2, *iter);
    589   ++iter;
    590   EXPECT_TRUE(proto_array_.end() == iter);
    591   EXPECT_EQ(2, *(proto_array_.end() - 1));
    592 }
    593 
    594 TEST_F(RepeatedFieldIteratorTest, Mutation) {
    595   RepeatedField<int>::iterator iter = proto_array_.begin();
    596   *iter = 7;
    597   EXPECT_EQ(7, proto_array_.Get(0));
    598 }
    599 
    600 // -------------------------------------------------------------------
    601 
    602 class RepeatedPtrFieldIteratorTest : public testing::Test {
    603  protected:
    604   virtual void SetUp() {
    605     proto_array_.Add()->assign("foo");
    606     proto_array_.Add()->assign("bar");
    607     proto_array_.Add()->assign("baz");
    608   }
    609 
    610   RepeatedPtrField<string> proto_array_;
    611 };
    612 
    613 TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
    614   RepeatedPtrField<string>::iterator iter = proto_array_.begin();
    615   RepeatedPtrField<string>::const_iterator c_iter = iter;
    616 }
    617 
    618 TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
    619   RepeatedPtrField<string>::iterator iter = proto_array_.begin();
    620   EXPECT_EQ("foo", *iter);
    621   ++iter;
    622   EXPECT_EQ("bar", *(iter++));
    623   EXPECT_EQ("baz", *iter);
    624   ++iter;
    625   EXPECT_TRUE(proto_array_.end() == iter);
    626   EXPECT_EQ("baz", *(--proto_array_.end()));
    627 }
    628 
    629 TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
    630   const RepeatedPtrField<string>& const_proto_array = proto_array_;
    631   RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin();
    632   EXPECT_EQ("foo", *iter);
    633   ++iter;
    634   EXPECT_EQ("bar", *(iter++));
    635   EXPECT_EQ("baz", *iter);
    636   ++iter;
    637   EXPECT_TRUE(const_proto_array.end() == iter);
    638   EXPECT_EQ("baz", *(--const_proto_array.end()));
    639 }
    640 
    641 TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
    642   RepeatedPtrField<string>::iterator iter = proto_array_.begin();
    643   RepeatedPtrField<string>::iterator iter2 = iter;
    644   ++iter2;
    645   ++iter2;
    646   EXPECT_TRUE(iter + 2 == iter2);
    647   EXPECT_TRUE(iter == iter2 - 2);
    648   EXPECT_EQ("baz", iter[2]);
    649   EXPECT_EQ("baz", *(iter + 2));
    650   EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
    651 }
    652 
    653 TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
    654   RepeatedPtrField<string>::const_iterator iter = proto_array_.begin();
    655   RepeatedPtrField<string>::const_iterator iter2 = iter + 1;
    656   EXPECT_TRUE(iter == iter);
    657   EXPECT_TRUE(iter != iter2);
    658   EXPECT_TRUE(iter < iter2);
    659   EXPECT_TRUE(iter <= iter2);
    660   EXPECT_TRUE(iter <= iter);
    661   EXPECT_TRUE(iter2 > iter);
    662   EXPECT_TRUE(iter2 >= iter);
    663   EXPECT_TRUE(iter >= iter);
    664 }
    665 
    666 // Uninitialized iterator does not point to any of the RepeatedPtrField.
    667 TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
    668   RepeatedPtrField<string>::iterator iter;
    669   EXPECT_TRUE(iter != proto_array_.begin());
    670   EXPECT_TRUE(iter != proto_array_.begin() + 1);
    671   EXPECT_TRUE(iter != proto_array_.begin() + 2);
    672   EXPECT_TRUE(iter != proto_array_.begin() + 3);
    673   EXPECT_TRUE(iter != proto_array_.end());
    674 }
    675 
    676 TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
    677   proto_array_.Clear();
    678   proto_array_.Add()->assign("a");
    679   proto_array_.Add()->assign("c");
    680   proto_array_.Add()->assign("d");
    681   proto_array_.Add()->assign("n");
    682   proto_array_.Add()->assign("p");
    683   proto_array_.Add()->assign("x");
    684   proto_array_.Add()->assign("y");
    685 
    686   string v = "f";
    687   RepeatedPtrField<string>::const_iterator it =
    688       lower_bound(proto_array_.begin(), proto_array_.end(), v);
    689 
    690   EXPECT_EQ(*it, "n");
    691   EXPECT_TRUE(it == proto_array_.begin() + 3);
    692 }
    693 
    694 TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
    695   RepeatedPtrField<string>::iterator iter = proto_array_.begin();
    696   *iter = "qux";
    697   EXPECT_EQ("qux", proto_array_.Get(0));
    698 }
    699 
    700 // -------------------------------------------------------------------
    701 
    702 class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
    703  protected:
    704   virtual void SetUp() {
    705     proto_array_.Add()->assign("foo");
    706     proto_array_.Add()->assign("bar");
    707     proto_array_.Add()->assign("baz");
    708   }
    709 
    710   RepeatedPtrField<string> proto_array_;
    711 };
    712 
    713 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
    714   RepeatedPtrField<string>::pointer_iterator iter =
    715       proto_array_.pointer_begin();
    716 }
    717 
    718 TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
    719   RepeatedPtrField<string>::pointer_iterator iter =
    720       proto_array_.pointer_begin();
    721   EXPECT_EQ("foo", **iter);
    722   ++iter;
    723   EXPECT_EQ("bar", **(iter++));
    724   EXPECT_EQ("baz", **iter);
    725   ++iter;
    726   EXPECT_TRUE(proto_array_.pointer_end() == iter);
    727   EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
    728 }
    729 
    730 TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
    731   RepeatedPtrField<string>::pointer_iterator iter =
    732       proto_array_.pointer_begin();
    733   RepeatedPtrField<string>::pointer_iterator iter2 = iter;
    734   ++iter2;
    735   ++iter2;
    736   EXPECT_TRUE(iter + 2 == iter2);
    737   EXPECT_TRUE(iter == iter2 - 2);
    738   EXPECT_EQ("baz", *iter[2]);
    739   EXPECT_EQ("baz", **(iter + 2));
    740   EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
    741 }
    742 
    743 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
    744   RepeatedPtrField<string>::pointer_iterator iter =
    745       proto_array_.pointer_begin();
    746   RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1;
    747   EXPECT_TRUE(iter == iter);
    748   EXPECT_TRUE(iter != iter2);
    749   EXPECT_TRUE(iter < iter2);
    750   EXPECT_TRUE(iter <= iter2);
    751   EXPECT_TRUE(iter <= iter);
    752   EXPECT_TRUE(iter2 > iter);
    753   EXPECT_TRUE(iter2 >= iter);
    754   EXPECT_TRUE(iter >= iter);
    755 }
    756 
    757 // Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
    758 // Dereferencing an uninitialized iterator crashes the process.
    759 TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
    760   RepeatedPtrField<string>::pointer_iterator iter;
    761   EXPECT_TRUE(iter != proto_array_.pointer_begin());
    762   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
    763   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
    764   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
    765   EXPECT_TRUE(iter != proto_array_.pointer_end());
    766 }
    767 
    768 
    769 // This comparison functor is required by the tests for RepeatedPtrOverPtrs.
    770 // They operate on strings and need to compare strings as strings in
    771 // any stl algorithm, even though the iterator returns a pointer to a string
    772 // - i.e. *iter has type string*.
    773 struct StringLessThan {
    774   bool operator()(const string* z, const string& y) {
    775     return *z < y;
    776   }
    777   bool operator()(const string* z, const string* y) {
    778     return *z < *y;
    779   }
    780 };
    781 
    782 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
    783   proto_array_.Clear();
    784   proto_array_.Add()->assign("a");
    785   proto_array_.Add()->assign("c");
    786   proto_array_.Add()->assign("d");
    787   proto_array_.Add()->assign("n");
    788   proto_array_.Add()->assign("p");
    789   proto_array_.Add()->assign("x");
    790   proto_array_.Add()->assign("y");
    791 
    792   RepeatedPtrField<string>::pointer_iterator iter =
    793       proto_array_.pointer_begin();
    794   string v = "f";
    795   RepeatedPtrField<string>::pointer_iterator it =
    796       lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
    797                   &v, StringLessThan());
    798 
    799   GOOGLE_CHECK(*it != NULL);
    800 
    801   EXPECT_EQ(**it, "n");
    802   EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
    803 }
    804 
    805 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
    806   RepeatedPtrField<string>::pointer_iterator iter =
    807       proto_array_.pointer_begin();
    808   **iter = "qux";
    809   EXPECT_EQ("qux", proto_array_.Get(0));
    810 
    811   EXPECT_EQ("bar", proto_array_.Get(1));
    812   EXPECT_EQ("baz", proto_array_.Get(2));
    813   ++iter;
    814   delete *iter;
    815   *iter = new string("a");
    816   ++iter;
    817   delete *iter;
    818   *iter = new string("b");
    819   EXPECT_EQ("a", proto_array_.Get(1));
    820   EXPECT_EQ("b", proto_array_.Get(2));
    821 }
    822 
    823 TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
    824   proto_array_.Add()->assign("c");
    825   proto_array_.Add()->assign("d");
    826   proto_array_.Add()->assign("n");
    827   proto_array_.Add()->assign("p");
    828   proto_array_.Add()->assign("a");
    829   proto_array_.Add()->assign("y");
    830   proto_array_.Add()->assign("x");
    831   EXPECT_EQ("foo", proto_array_.Get(0));
    832   EXPECT_EQ("n", proto_array_.Get(5));
    833   EXPECT_EQ("x", proto_array_.Get(9));
    834   sort(proto_array_.pointer_begin(),
    835        proto_array_.pointer_end(),
    836        StringLessThan());
    837   EXPECT_EQ("a", proto_array_.Get(0));
    838   EXPECT_EQ("baz", proto_array_.Get(2));
    839   EXPECT_EQ("y", proto_array_.Get(9));
    840 }
    841 
    842 
    843 // -----------------------------------------------------------------------------
    844 // Unit-tests for the insert iterators
    845 // google::protobuf::RepeatedFieldBackInserter,
    846 // google::protobuf::AllocatedRepeatedPtrFieldBackInserter
    847 // Ported from util/gtl/proto-array-iterators_unittest.
    848 
    849 class RepeatedFieldInsertionIteratorsTest : public testing::Test {
    850  protected:
    851   std::list<double> halves;
    852   std::list<int> fibonacci;
    853   std::vector<string> words;
    854   typedef TestAllTypes::NestedMessage Nested;
    855   Nested nesteds[2];
    856   std::vector<Nested*> nested_ptrs;
    857   TestAllTypes protobuffer;
    858 
    859   virtual void SetUp() {
    860     fibonacci.push_back(1);
    861     fibonacci.push_back(1);
    862     fibonacci.push_back(2);
    863     fibonacci.push_back(3);
    864     fibonacci.push_back(5);
    865     fibonacci.push_back(8);
    866     std::copy(fibonacci.begin(), fibonacci.end(),
    867               RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32()));
    868 
    869     halves.push_back(1.0);
    870     halves.push_back(0.5);
    871     halves.push_back(0.25);
    872     halves.push_back(0.125);
    873     halves.push_back(0.0625);
    874     std::copy(halves.begin(), halves.end(),
    875               RepeatedFieldBackInserter(protobuffer.mutable_repeated_double()));
    876 
    877     words.push_back("Able");
    878     words.push_back("was");
    879     words.push_back("I");
    880     words.push_back("ere");
    881     words.push_back("I");
    882     words.push_back("saw");
    883     words.push_back("Elba");
    884     std::copy(words.begin(), words.end(),
    885               RepeatedFieldBackInserter(protobuffer.mutable_repeated_string()));
    886 
    887     nesteds[0].set_bb(17);
    888     nesteds[1].set_bb(4711);
    889     std::copy(&nesteds[0], &nesteds[2],
    890               RepeatedFieldBackInserter(
    891                   protobuffer.mutable_repeated_nested_message()));
    892 
    893     nested_ptrs.push_back(new Nested);
    894     nested_ptrs.back()->set_bb(170);
    895     nested_ptrs.push_back(new Nested);
    896     nested_ptrs.back()->set_bb(47110);
    897     std::copy(nested_ptrs.begin(), nested_ptrs.end(),
    898               RepeatedFieldBackInserter(
    899                   protobuffer.mutable_repeated_nested_message()));
    900 
    901   }
    902 
    903   virtual void TearDown() {
    904     STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end());
    905   }
    906 };
    907 
    908 TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) {
    909   EXPECT_TRUE(std::equal(fibonacci.begin(),
    910                          fibonacci.end(),
    911                          protobuffer.repeated_int32().begin()));
    912   EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(),
    913                          protobuffer.repeated_int32().end(),
    914                          fibonacci.begin()));
    915 }
    916 
    917 TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
    918   EXPECT_TRUE(std::equal(halves.begin(),
    919                          halves.end(),
    920                          protobuffer.repeated_double().begin()));
    921   EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(),
    922                          protobuffer.repeated_double().end(),
    923                          halves.begin()));
    924 }
    925 
    926 TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
    927   ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
    928   EXPECT_EQ(words.at(0), protobuffer.repeated_string(0));
    929   EXPECT_EQ(words.at(1), protobuffer.repeated_string(1));
    930   EXPECT_EQ(words.at(2), protobuffer.repeated_string(2));
    931   EXPECT_EQ(words.at(3), protobuffer.repeated_string(3));
    932   EXPECT_EQ(words.at(4), protobuffer.repeated_string(4));
    933   EXPECT_EQ(words.at(5), protobuffer.repeated_string(5));
    934   EXPECT_EQ(words.at(6), protobuffer.repeated_string(6));
    935 }
    936 
    937 TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
    938   ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4);
    939   EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17);
    940   EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711);
    941   EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170);
    942   EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110);
    943 }
    944 
    945 TEST_F(RepeatedFieldInsertionIteratorsTest,
    946        AllocatedRepeatedPtrFieldWithStringIntData) {
    947   vector<Nested*> data;
    948   TestAllTypes goldenproto;
    949   for (int i = 0; i < 10; ++i) {
    950     Nested* new_data = new Nested;
    951     new_data->set_bb(i);
    952     data.push_back(new_data);
    953 
    954     new_data = goldenproto.add_repeated_nested_message();
    955     new_data->set_bb(i);
    956   }
    957   TestAllTypes testproto;
    958   copy(data.begin(), data.end(),
    959        AllocatedRepeatedPtrFieldBackInserter(
    960            testproto.mutable_repeated_nested_message()));
    961   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
    962 }
    963 
    964 TEST_F(RepeatedFieldInsertionIteratorsTest,
    965        AllocatedRepeatedPtrFieldWithString) {
    966   vector<string*> data;
    967   TestAllTypes goldenproto;
    968   for (int i = 0; i < 10; ++i) {
    969     string* new_data = new string;
    970     *new_data = "name-" + SimpleItoa(i);
    971     data.push_back(new_data);
    972 
    973     new_data = goldenproto.add_repeated_string();
    974     *new_data = "name-" + SimpleItoa(i);
    975   }
    976   TestAllTypes testproto;
    977   copy(data.begin(), data.end(),
    978        AllocatedRepeatedPtrFieldBackInserter(
    979            testproto.mutable_repeated_string()));
    980   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
    981 }
    982 
    983 }  // namespace
    984 
    985 }  // namespace protobuf
    986 }  // namespace google
    987