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