• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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.
TEST(RepeatedField,Small)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.
TEST(RepeatedField,Large)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.
TEST(RepeatedField,SwapSmallSmall)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 
TEST(RepeatedField,SwapLargeSmall)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 
TEST(RepeatedField,SwapLargeLarge)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.
ReservedSpace(RepeatedField<int> * field)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 
TEST(RepeatedField,ReserveMoreThanDouble)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 
TEST(RepeatedField,ReserveLessThanDouble)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 
TEST(RepeatedField,ReserveLessThanExisting)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 
TEST(RepeatedField,MergeFrom)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 
TEST(RepeatedField,MutableDataIsMutable)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 
TEST(RepeatedField,Truncate)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 
TEST(RepeatedPtrField,Small)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 
TEST(RepeatedPtrField,Large)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 
TEST(RepeatedPtrField,SwapSmallSmall)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 
TEST(RepeatedPtrField,SwapLargeSmall)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 
TEST(RepeatedPtrField,SwapLargeLarge)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 
ReservedSpace(RepeatedPtrField<string> * field)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 
TEST(RepeatedPtrField,ReserveMoreThanDouble)394 TEST(RepeatedPtrField, ReserveMoreThanDouble) {
395   RepeatedPtrField<string> field;
396   field.Reserve(20);
397 
398   EXPECT_EQ(20, ReservedSpace(&field));
399 }
400 
TEST(RepeatedPtrField,ReserveLessThanDouble)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 
TEST(RepeatedPtrField,ReserveLessThanExisting)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 
TEST(RepeatedPtrField,ReserveDoesntLoseAllocated)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.
TEST(RepeatedPtrField,ClearedElements)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().
TEST(RepeatedPtrField,AddAlocated)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 
TEST(RepeatedPtrField,MergeFrom)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 
TEST(RepeatedPtrField,MutableDataIsMutable)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:
SetUp()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 
TEST_F(RepeatedFieldIteratorTest,Convertible)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 
TEST_F(RepeatedFieldIteratorTest,MutableIteration)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 
TEST_F(RepeatedFieldIteratorTest,ConstIteration)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 
TEST_F(RepeatedFieldIteratorTest,Mutation)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:
SetUp()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 
TEST_F(RepeatedPtrFieldIteratorTest,Convertible)613 TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
614   RepeatedPtrField<string>::iterator iter = proto_array_.begin();
615   RepeatedPtrField<string>::const_iterator c_iter = iter;
616 }
617 
TEST_F(RepeatedPtrFieldIteratorTest,MutableIteration)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 
TEST_F(RepeatedPtrFieldIteratorTest,ConstIteration)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 
TEST_F(RepeatedPtrFieldIteratorTest,RandomAccess)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 
TEST_F(RepeatedPtrFieldIteratorTest,Comparable)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.
TEST_F(RepeatedPtrFieldIteratorTest,UninitializedIterator)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 
TEST_F(RepeatedPtrFieldIteratorTest,STLAlgorithms_lower_bound)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 
TEST_F(RepeatedPtrFieldIteratorTest,Mutation)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:
SetUp()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 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ConvertiblePtr)713 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
714   RepeatedPtrField<string>::pointer_iterator iter =
715       proto_array_.pointer_begin();
716 }
717 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,MutablePtrIteration)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 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,RandomPtrAccess)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 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparablePtr)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.
TEST_F(RepeatedPtrFieldPtrsIteratorTest,UninitializedPtrIterator)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 {
operator ()google::protobuf::__anon2af3d45e0111::StringLessThan774   bool operator()(const string* z, const string& y) {
775     return *z < y;
776   }
operator ()google::protobuf::__anon2af3d45e0111::StringLessThan777   bool operator()(const string* z, const string* y) {
778     return *z < *y;
779   }
780 };
781 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrSTLAlgorithms_lower_bound)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 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrMutation)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 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,Sort)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 
SetUp()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 
TearDown()903   virtual void TearDown() {
904     STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end());
905   }
906 };
907 
TEST_F(RepeatedFieldInsertionIteratorsTest,Fibonacci)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 
TEST_F(RepeatedFieldInsertionIteratorsTest,Halves)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 
TEST_F(RepeatedFieldInsertionIteratorsTest,Words)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 
TEST_F(RepeatedFieldInsertionIteratorsTest,Nesteds)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 
TEST_F(RepeatedFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithStringIntData)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 
TEST_F(RepeatedFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithString)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