diff options
Diffstat (limited to 'src/google/protobuf/repeated_field_unittest.cc')
-rw-r--r-- | src/google/protobuf/repeated_field_unittest.cc | 1566 |
1 files changed, 0 insertions, 1566 deletions
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc deleted file mode 100644 index 39b24b33..00000000 --- a/src/google/protobuf/repeated_field_unittest.cc +++ /dev/null @@ -1,1566 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// TODO(kenton): Improve this unittest to bring it up to the standards of -// other proto2 unittests. - -#include <algorithm> -#include <limits> -#include <list> -#include <vector> - -#include <google/protobuf/repeated_field.h> - -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/stubs/stl_util.h> - -namespace google { -using protobuf_unittest::TestAllTypes; - -namespace protobuf { -namespace { - -// Test operations on a small RepeatedField. -TEST(RepeatedField, Small) { - RepeatedField<int> field; - - EXPECT_TRUE(field.empty()); - EXPECT_EQ(field.size(), 0); - - field.Add(5); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Add(42); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 42); - - field.Set(1, 23); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 23); - - field.RemoveLast(); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Clear(); - - EXPECT_TRUE(field.empty()); - EXPECT_EQ(field.size(), 0); - // Additional bytes are for 'struct Rep' header. - int expected_usage = 4 * sizeof(int) + sizeof(Arena*); - EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage); -} - - -// Test operations on a RepeatedField which is large enough to allocate a -// separate array. -TEST(RepeatedField, Large) { - RepeatedField<int> field; - - for (int i = 0; i < 16; i++) { - field.Add(i * i); - } - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i), i * i); - } - - int expected_usage = 16 * sizeof(int); - EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage); -} - -// Test swapping between various types of RepeatedFields. -TEST(RepeatedField, SwapSmallSmall) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - field1.Add(5); - field1.Add(42); - - EXPECT_FALSE(field1.empty()); - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), 5); - EXPECT_EQ(field1.Get(1), 42); - - EXPECT_TRUE(field2.empty()); - EXPECT_EQ(field2.size(), 0); - - field1.Swap(&field2); - - EXPECT_TRUE(field1.empty()); - EXPECT_EQ(field1.size(), 0); - - EXPECT_FALSE(field2.empty()); - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); -} - -TEST(RepeatedField, SwapLargeSmall) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - for (int i = 0; i < 16; i++) { - field1.Add(i * i); - } - field2.Add(5); - field2.Add(42); - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), 5); - EXPECT_EQ(field1.Get(1), 42); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i), i * i); - } -} - -TEST(RepeatedField, SwapLargeLarge) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - field1.Add(5); - field1.Add(42); - for (int i = 0; i < 16; i++) { - field1.Add(i); - field2.Add(i * i); - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i), i * i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i), i - 2); - } -} - -// Determines how much space was reserved by the given field by adding elements -// to it until it re-allocates its space. -static int ReservedSpace(RepeatedField<int>* field) { - const int* ptr = field->data(); - do { - field->Add(0); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedField, ReserveMoreThanDouble) { - // Reserve more than double the previous space in the field and expect the - // field to reserve exactly the amount specified. - RepeatedField<int> field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanDouble) { - // Reserve less than double the previous space in the field and expect the - // field to grow by double instead. - RepeatedField<int> field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanExisting) { - // Reserve less than the previous space in the field and expect the - // field to not re-allocate at all. - RepeatedField<int> field; - field.Reserve(20); - const int* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, Resize) { - RepeatedField<int> field; - field.Resize(2, 1); - EXPECT_EQ(2, field.size()); - field.Resize(5, 2); - EXPECT_EQ(5, field.size()); - field.Resize(4, 3); - ASSERT_EQ(4, field.size()); - EXPECT_EQ(1, field.Get(0)); - EXPECT_EQ(1, field.Get(1)); - EXPECT_EQ(2, field.Get(2)); - EXPECT_EQ(2, field.Get(3)); - field.Resize(0, 4); - EXPECT_TRUE(field.empty()); -} - -TEST(RepeatedField, MergeFrom) { - RepeatedField<int> source, destination; - source.Add(4); - source.Add(5); - destination.Add(1); - destination.Add(2); - destination.Add(3); - - destination.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - EXPECT_EQ(1, destination.Get(0)); - EXPECT_EQ(2, destination.Get(1)); - EXPECT_EQ(3, destination.Get(2)); - EXPECT_EQ(4, destination.Get(3)); - EXPECT_EQ(5, destination.Get(4)); -} - -#ifdef PROTOBUF_HAS_DEATH_TEST -TEST(RepeatedField, MergeFromSelf) { - RepeatedField<int> me; - me.Add(3); - EXPECT_DEATH(me.MergeFrom(me), ""); -} -#endif // PROTOBUF_HAS_DEATH_TEST - -TEST(RepeatedField, CopyFrom) { - RepeatedField<int> source, destination; - source.Add(4); - source.Add(5); - destination.Add(1); - destination.Add(2); - destination.Add(3); - - destination.CopyFrom(source); - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ(4, destination.Get(0)); - EXPECT_EQ(5, destination.Get(1)); -} - -TEST(RepeatedField, CopyFromSelf) { - RepeatedField<int> me; - me.Add(3); - me.CopyFrom(me); - ASSERT_EQ(1, me.size()); - EXPECT_EQ(3, me.Get(0)); -} - -TEST(RepeatedField, Erase) { - RepeatedField<int> me; - RepeatedField<int>::iterator it = me.erase(me.begin(), me.end()); - EXPECT_TRUE(me.begin() == it); - EXPECT_EQ(0, me.size()); - - me.Add(1); - me.Add(2); - me.Add(3); - it = me.erase(me.begin(), me.end()); - EXPECT_TRUE(me.begin() == it); - EXPECT_EQ(0, me.size()); - - me.Add(4); - me.Add(5); - me.Add(6); - it = me.erase(me.begin() + 2, me.end()); - EXPECT_TRUE(me.begin() + 2 == it); - EXPECT_EQ(2, me.size()); - EXPECT_EQ(4, me.Get(0)); - EXPECT_EQ(5, me.Get(1)); - - me.Add(6); - me.Add(7); - me.Add(8); - it = me.erase(me.begin() + 1, me.begin() + 3); - EXPECT_TRUE(me.begin() + 1 == it); - EXPECT_EQ(3, me.size()); - EXPECT_EQ(4, me.Get(0)); - EXPECT_EQ(7, me.Get(1)); - EXPECT_EQ(8, me.Get(2)); -} - -TEST(RepeatedField, CopyConstruct) { - RepeatedField<int> source; - source.Add(1); - source.Add(2); - - RepeatedField<int> destination(source); - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ(1, destination.Get(0)); - EXPECT_EQ(2, destination.Get(1)); -} - -TEST(RepeatedField, IteratorConstruct) { - vector<int> values; - values.push_back(1); - values.push_back(2); - - RepeatedField<int> field(values.begin(), values.end()); - ASSERT_EQ(values.size(), field.size()); - EXPECT_EQ(values[0], field.Get(0)); - EXPECT_EQ(values[1], field.Get(1)); - - RepeatedField<int> other(field.begin(), field.end()); - ASSERT_EQ(values.size(), other.size()); - EXPECT_EQ(values[0], other.Get(0)); - EXPECT_EQ(values[1], other.Get(1)); -} - -TEST(RepeatedField, CopyAssign) { - RepeatedField<int> source, destination; - source.Add(4); - source.Add(5); - destination.Add(1); - destination.Add(2); - destination.Add(3); - - destination = source; - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ(4, destination.Get(0)); - EXPECT_EQ(5, destination.Get(1)); -} - -TEST(RepeatedField, SelfAssign) { - // Verify that assignment to self does not destroy data. - RepeatedField<int> source, *p; - p = &source; - source.Add(7); - source.Add(8); - - *p = source; - - ASSERT_EQ(2, source.size()); - EXPECT_EQ(7, source.Get(0)); - EXPECT_EQ(8, source.Get(1)); -} - -TEST(RepeatedField, MutableDataIsMutable) { - RepeatedField<int> field; - field.Add(1); - EXPECT_EQ(1, field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - *field.mutable_data() = 2; - EXPECT_EQ(2, field.Get(0)); -} - -TEST(RepeatedField, Truncate) { - RepeatedField<int> field; - - field.Add(12); - field.Add(34); - field.Add(56); - field.Add(78); - EXPECT_EQ(4, field.size()); - - field.Truncate(3); - EXPECT_EQ(3, field.size()); - - field.Add(90); - EXPECT_EQ(4, field.size()); - EXPECT_EQ(90, field.Get(3)); - - // Truncations that don't change the size are allowed, but growing is not - // allowed. - field.Truncate(field.size()); -#ifdef PROTOBUF_HAS_DEATH_TEST - EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size"); -#endif -} - - -TEST(RepeatedField, ExtractSubrange) { - // Exhaustively test every subrange in arrays of all sizes from 0 through 9. - for (int sz = 0; sz < 10; ++sz) { - for (int num = 0; num <= sz; ++num) { - for (int start = 0; start < sz - num; ++start) { - // Create RepeatedField with sz elements having values 0 through sz-1. - RepeatedField<int32> field; - for (int i = 0; i < sz; ++i) - field.Add(i); - EXPECT_EQ(field.size(), sz); - - // Create a catcher array and call ExtractSubrange. - int32 catcher[10]; - for (int i = 0; i < 10; ++i) - catcher[i] = -1; - field.ExtractSubrange(start, num, catcher); - - // Does the resulting array have the right size? - EXPECT_EQ(field.size(), sz - num); - - // Were the removed elements extracted into the catcher array? - for (int i = 0; i < num; ++i) - EXPECT_EQ(catcher[i], start + i); - EXPECT_EQ(catcher[num], -1); - - // Does the resulting array contain the right values? - for (int i = 0; i < start; ++i) - EXPECT_EQ(field.Get(i), i); - for (int i = start; i < field.size(); ++i) - EXPECT_EQ(field.Get(i), i + num); - } - } - } -} - -TEST(RepeatedField, ClearThenReserveMore) { - // Test that Reserve properly destroys the old internal array when it's forced - // to allocate a new one, even when cleared-but-not-deleted objects are - // present. Use a 'string' and > 16 bytes length so that the elements are - // non-POD and allocate -- the leak checker will catch any skipped destructor - // calls here. - RepeatedField<string> field; - for (int i = 0; i < 32; i++) { - field.Add(string("abcdefghijklmnopqrstuvwxyz0123456789")); - } - EXPECT_EQ(32, field.size()); - field.Clear(); - EXPECT_EQ(0, field.size()); - EXPECT_EQ(32, field.Capacity()); - - field.Reserve(1024); - EXPECT_EQ(0, field.size()); - EXPECT_EQ(1024, field.Capacity()); - // Finish test -- |field| should destroy the cleared-but-not-yet-destroyed - // strings. -} - -// =================================================================== -// RepeatedPtrField tests. These pretty much just mirror the RepeatedField -// tests above. - -TEST(RepeatedPtrField, Small) { - RepeatedPtrField<string> field; - - EXPECT_TRUE(field.empty()); - EXPECT_EQ(field.size(), 0); - - field.Add()->assign("foo"); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Add()->assign("bar"); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "bar"); - - field.Mutable(1)->assign("baz"); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "baz"); - - field.RemoveLast(); - - EXPECT_FALSE(field.empty()); - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Clear(); - - EXPECT_TRUE(field.empty()); - EXPECT_EQ(field.size(), 0); -} - -TEST(RepeatedPtrField, Large) { - RepeatedPtrField<string> field; - - for (int i = 0; i < 16; i++) { - *field.Add() += 'a' + i; - } - - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i).size(), 1); - EXPECT_EQ(field.Get(i)[0], 'a' + i); - } - - int min_expected_usage = 16 * sizeof(string); - EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); -} - -TEST(RepeatedPtrField, SwapSmallSmall) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - EXPECT_TRUE(field1.empty()); - EXPECT_EQ(field1.size(), 0); - EXPECT_TRUE(field2.empty()); - EXPECT_EQ(field2.size(), 0); - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - - EXPECT_FALSE(field1.empty()); - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), "foo"); - EXPECT_EQ(field1.Get(1), "bar"); - - EXPECT_TRUE(field2.empty()); - EXPECT_EQ(field2.size(), 0); - - field1.Swap(&field2); - - EXPECT_TRUE(field1.empty()); - EXPECT_EQ(field1.size(), 0); - - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); -} - -TEST(RepeatedPtrField, SwapLargeSmall) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - field2.Add()->assign("foo"); - field2.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'a' + i; - } - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), "foo"); - EXPECT_EQ(field1.Get(1), "bar"); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'a' + i); - } -} - -TEST(RepeatedPtrField, SwapLargeLarge) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'A' + i; - *field2.Add() += 'a' + i; - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i).size(), 1); - EXPECT_EQ(field1.Get(i)[0], 'a' + i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); - } -} - -static int ReservedSpace(RepeatedPtrField<string>* field) { - const string* const* ptr = field->data(); - do { - field->Add(); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedPtrField, ReserveMoreThanDouble) { - RepeatedPtrField<string> field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanDouble) { - RepeatedPtrField<string> field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanExisting) { - RepeatedPtrField<string> field; - field.Reserve(20); - const string* const* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { - // Check that a bug is fixed: An earlier implementation of Reserve() - // failed to copy pointers to allocated-but-cleared objects, possibly - // leading to segfaults. - RepeatedPtrField<string> field; - string* first = field.Add(); - field.RemoveLast(); - - field.Reserve(20); - EXPECT_EQ(first, field.Add()); -} - -// Clearing elements is tricky with RepeatedPtrFields since the memory for -// the elements is retained and reused. -TEST(RepeatedPtrField, ClearedElements) { - RepeatedPtrField<string> field; - - string* original = field.Add(); - *original = "foo"; - - EXPECT_EQ(field.ClearedCount(), 0); - - field.RemoveLast(); - EXPECT_TRUE(original->empty()); - EXPECT_EQ(field.ClearedCount(), 1); - - EXPECT_EQ(field.Add(), original); // Should return same string for reuse. - - EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. - EXPECT_EQ(field.ClearedCount(), 0); - - EXPECT_NE(field.Add(), original); // Should NOT return the same string. - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddAllocated(original); // Give ownership back. - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_EQ(field.Mutable(1), original); - - field.Clear(); - EXPECT_EQ(field.ClearedCount(), 2); - EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddCleared(original); // Give ownership back, but as a cleared object. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_EQ(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); -} - -// Test all code paths in AddAllocated(). -TEST(RepeatedPtrField, AddAlocated) { - RepeatedPtrField<string> field; - while (field.size() < field.Capacity()) { - field.Add()->assign("filler"); - } - - int index = field.size(); - - // First branch: Field is at capacity with no cleared objects. - string* foo = new string("foo"); - field.AddAllocated(foo); - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(foo, &field.Get(index)); - - // Last branch: Field is not at capacity and there are no cleared objects. - string* bar = new string("bar"); - field.AddAllocated(bar); - ++index; - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(bar, &field.Get(index)); - - // Third branch: Field is not at capacity and there are no cleared objects. - field.RemoveLast(); - string* baz = new string("baz"); - field.AddAllocated(baz); - EXPECT_EQ(index + 1, field.size()); - EXPECT_EQ(1, field.ClearedCount()); - EXPECT_EQ(baz, &field.Get(index)); - - // Second branch: Field is at capacity but has some cleared objects. - while (field.size() < field.Capacity()) { - field.Add()->assign("filler2"); - } - field.RemoveLast(); - index = field.size(); - string* qux = new string("qux"); - field.AddAllocated(qux); - EXPECT_EQ(index + 1, field.size()); - // We should have discarded the cleared object. - EXPECT_EQ(0, field.ClearedCount()); - EXPECT_EQ(qux, &field.Get(index)); -} - -TEST(RepeatedPtrField, MergeFrom) { - RepeatedPtrField<string> source, destination; - source.Add()->assign("4"); - source.Add()->assign("5"); - destination.Add()->assign("1"); - destination.Add()->assign("2"); - destination.Add()->assign("3"); - - destination.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - EXPECT_EQ("1", destination.Get(0)); - EXPECT_EQ("2", destination.Get(1)); - EXPECT_EQ("3", destination.Get(2)); - EXPECT_EQ("4", destination.Get(3)); - EXPECT_EQ("5", destination.Get(4)); -} - -#ifdef PROTOBUF_HAS_DEATH_TEST -TEST(RepeatedPtrField, MergeFromSelf) { - RepeatedPtrField<string> me; - me.Add()->assign("1"); - EXPECT_DEATH(me.MergeFrom(me), ""); -} -#endif // PROTOBUF_HAS_DEATH_TEST - -TEST(RepeatedPtrField, CopyFrom) { - RepeatedPtrField<string> source, destination; - source.Add()->assign("4"); - source.Add()->assign("5"); - destination.Add()->assign("1"); - destination.Add()->assign("2"); - destination.Add()->assign("3"); - - destination.CopyFrom(source); - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ("4", destination.Get(0)); - EXPECT_EQ("5", destination.Get(1)); -} - -TEST(RepeatedPtrField, CopyFromSelf) { - RepeatedPtrField<string> me; - me.Add()->assign("1"); - me.CopyFrom(me); - ASSERT_EQ(1, me.size()); - EXPECT_EQ("1", me.Get(0)); -} - -TEST(RepeatedPtrField, Erase) { - RepeatedPtrField<string> me; - RepeatedPtrField<string>::iterator it = me.erase(me.begin(), me.end()); - EXPECT_TRUE(me.begin() == it); - EXPECT_EQ(0, me.size()); - - *me.Add() = "1"; - *me.Add() = "2"; - *me.Add() = "3"; - it = me.erase(me.begin(), me.end()); - EXPECT_TRUE(me.begin() == it); - EXPECT_EQ(0, me.size()); - - *me.Add() = "4"; - *me.Add() = "5"; - *me.Add() = "6"; - it = me.erase(me.begin() + 2, me.end()); - EXPECT_TRUE(me.begin() + 2 == it); - EXPECT_EQ(2, me.size()); - EXPECT_EQ("4", me.Get(0)); - EXPECT_EQ("5", me.Get(1)); - - *me.Add() = "6"; - *me.Add() = "7"; - *me.Add() = "8"; - it = me.erase(me.begin() + 1, me.begin() + 3); - EXPECT_TRUE(me.begin() + 1 == it); - EXPECT_EQ(3, me.size()); - EXPECT_EQ("4", me.Get(0)); - EXPECT_EQ("7", me.Get(1)); - EXPECT_EQ("8", me.Get(2)); -} - -TEST(RepeatedPtrField, CopyConstruct) { - RepeatedPtrField<string> source; - source.Add()->assign("1"); - source.Add()->assign("2"); - - RepeatedPtrField<string> destination(source); - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ("1", destination.Get(0)); - EXPECT_EQ("2", destination.Get(1)); -} - -TEST(RepeatedPtrField, IteratorConstruct_String) { - vector<string> values; - values.push_back("1"); - values.push_back("2"); - - RepeatedPtrField<string> field(values.begin(), values.end()); - ASSERT_EQ(values.size(), field.size()); - EXPECT_EQ(values[0], field.Get(0)); - EXPECT_EQ(values[1], field.Get(1)); - - RepeatedPtrField<string> other(field.begin(), field.end()); - ASSERT_EQ(values.size(), other.size()); - EXPECT_EQ(values[0], other.Get(0)); - EXPECT_EQ(values[1], other.Get(1)); -} - -TEST(RepeatedPtrField, IteratorConstruct_Proto) { - typedef TestAllTypes::NestedMessage Nested; - vector<Nested> values; - values.push_back(Nested()); - values.back().set_bb(1); - values.push_back(Nested()); - values.back().set_bb(2); - - RepeatedPtrField<Nested> field(values.begin(), values.end()); - ASSERT_EQ(values.size(), field.size()); - EXPECT_EQ(values[0].bb(), field.Get(0).bb()); - EXPECT_EQ(values[1].bb(), field.Get(1).bb()); - - RepeatedPtrField<Nested> other(field.begin(), field.end()); - ASSERT_EQ(values.size(), other.size()); - EXPECT_EQ(values[0].bb(), other.Get(0).bb()); - EXPECT_EQ(values[1].bb(), other.Get(1).bb()); -} - -TEST(RepeatedPtrField, CopyAssign) { - RepeatedPtrField<string> source, destination; - source.Add()->assign("4"); - source.Add()->assign("5"); - destination.Add()->assign("1"); - destination.Add()->assign("2"); - destination.Add()->assign("3"); - - destination = source; - - ASSERT_EQ(2, destination.size()); - EXPECT_EQ("4", destination.Get(0)); - EXPECT_EQ("5", destination.Get(1)); -} - -TEST(RepeatedPtrField, SelfAssign) { - // Verify that assignment to self does not destroy data. - RepeatedPtrField<string> source, *p; - p = &source; - source.Add()->assign("7"); - source.Add()->assign("8"); - - *p = source; - - ASSERT_EQ(2, source.size()); - EXPECT_EQ("7", source.Get(0)); - EXPECT_EQ("8", source.Get(1)); -} - -TEST(RepeatedPtrField, MutableDataIsMutable) { - RepeatedPtrField<string> field; - *field.Add() = "1"; - EXPECT_EQ("1", field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - string** data = field.mutable_data(); - **data = "2"; - EXPECT_EQ("2", field.Get(0)); -} - -TEST(RepeatedPtrField, ExtractSubrange) { - // Exhaustively test every subrange in arrays of all sizes from 0 through 9 - // with 0 through 3 cleared elements at the end. - for (int sz = 0; sz < 10; ++sz) { - for (int num = 0; num <= sz; ++num) { - for (int start = 0; start < sz - num; ++start) { - for (int extra = 0; extra < 4; ++extra) { - vector<string*> subject; - - // Create an array with "sz" elements and "extra" cleared elements. - RepeatedPtrField<string> field; - for (int i = 0; i < sz + extra; ++i) { - subject.push_back(new string()); - field.AddAllocated(subject[i]); - } - EXPECT_EQ(field.size(), sz + extra); - for (int i = 0; i < extra; ++i) - field.RemoveLast(); - EXPECT_EQ(field.size(), sz); - EXPECT_EQ(field.ClearedCount(), extra); - - // Create a catcher array and call ExtractSubrange. - string* catcher[10]; - for (int i = 0; i < 10; ++i) - catcher[i] = NULL; - field.ExtractSubrange(start, num, catcher); - - // Does the resulting array have the right size? - EXPECT_EQ(field.size(), sz - num); - - // Were the removed elements extracted into the catcher array? - for (int i = 0; i < num; ++i) - EXPECT_EQ(catcher[i], subject[start + i]); - EXPECT_EQ(NULL, catcher[num]); - - // Does the resulting array contain the right values? - for (int i = 0; i < start; ++i) - EXPECT_EQ(field.Mutable(i), subject[i]); - for (int i = start; i < field.size(); ++i) - EXPECT_EQ(field.Mutable(i), subject[i + num]); - - // Reinstate the cleared elements. - EXPECT_EQ(field.ClearedCount(), extra); - for (int i = 0; i < extra; ++i) - field.Add(); - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_EQ(field.size(), sz - num + extra); - - // Make sure the extra elements are all there (in some order). - for (int i = sz; i < sz + extra; ++i) { - int count = 0; - for (int j = sz; j < sz + extra; ++j) { - if (field.Mutable(j - num) == subject[i]) - count += 1; - } - EXPECT_EQ(count, 1); - } - - // Release the caught elements. - for (int i = 0; i < num; ++i) - delete catcher[i]; - } - } - } - } -} - -TEST(RepeatedPtrField, DeleteSubrange) { - // DeleteSubrange is a trivial extension of ExtendSubrange. -} - -// =================================================================== - -// Iterator tests stolen from net/proto/proto-array_unittest. -class RepeatedFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - for (int i = 0; i < 3; ++i) { - proto_array_.Add(i); - } - } - - RepeatedField<int> proto_array_; -}; - -TEST_F(RepeatedFieldIteratorTest, Convertible) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - RepeatedField<int>::const_iterator c_iter = iter; - RepeatedField<int>::value_type value = *c_iter; - EXPECT_EQ(0, value); -} - -TEST_F(RepeatedFieldIteratorTest, MutableIteration) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, ConstIteration) { - const RepeatedField<int>& const_proto_array = proto_array_; - RepeatedField<int>::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, Mutation) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - *iter = 7; - EXPECT_EQ(7, proto_array_.Get(0)); -} - -// ------------------------------------------------------------------- - -class RepeatedPtrFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - proto_array_.Add()->assign("foo"); - proto_array_.Add()->assign("bar"); - proto_array_.Add()->assign("baz"); - } - - RepeatedPtrField<string> proto_array_; -}; - -TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::const_iterator c_iter = iter; - RepeatedPtrField<string>::value_type value = *c_iter; - EXPECT_EQ("foo", value); -} - -TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ("baz", *(--proto_array_.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { - const RepeatedPtrField<string>& const_proto_array = proto_array_; - RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(const_proto_array.end() == iter); - EXPECT_EQ("baz", *(--const_proto_array.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) { - RepeatedPtrField<string>::reverse_iterator iter = proto_array_.rbegin(); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_TRUE(proto_array_.rend() == iter); - EXPECT_EQ("foo", *(--proto_array_.rend())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) { - const RepeatedPtrField<string>& const_proto_array = proto_array_; - RepeatedPtrField<string>::const_reverse_iterator iter - = const_proto_array.rbegin(); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_TRUE(const_proto_array.rend() == iter); - EXPECT_EQ("foo", *(--const_proto_array.rend())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", iter[2]); - EXPECT_EQ("baz", *(iter + 2)); - EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { - RepeatedPtrField<string>::const_iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::const_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -// Uninitialized iterator does not point to any of the RepeatedPtrField. -TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { - RepeatedPtrField<string>::iterator iter; - EXPECT_TRUE(iter != proto_array_.begin()); - EXPECT_TRUE(iter != proto_array_.begin() + 1); - EXPECT_TRUE(iter != proto_array_.begin() + 2); - EXPECT_TRUE(iter != proto_array_.begin() + 3); - EXPECT_TRUE(iter != proto_array_.end()); -} - -TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { - proto_array_.Clear(); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("x"); - proto_array_.Add()->assign("y"); - - string v = "f"; - RepeatedPtrField<string>::const_iterator it = - std::lower_bound(proto_array_.begin(), proto_array_.end(), v); - - EXPECT_EQ(*it, "n"); - EXPECT_TRUE(it == proto_array_.begin() + 3); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - *iter = "qux"; - EXPECT_EQ("qux", proto_array_.Get(0)); -} - -// ------------------------------------------------------------------- - -class RepeatedPtrFieldPtrsIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - proto_array_.Add()->assign("foo"); - proto_array_.Add()->assign("bar"); - proto_array_.Add()->assign("baz"); - const_proto_array_ = &proto_array_; - } - - RepeatedPtrField<string> proto_array_; - const RepeatedPtrField<string>* const_proto_array_; -}; - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) { - RepeatedPtrField<string>::pointer_iterator iter = - proto_array_.pointer_begin(); - static_cast<void>(iter); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) { - RepeatedPtrField<string>::const_pointer_iterator iter = - const_proto_array_->pointer_begin(); - static_cast<void>(iter); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) { - RepeatedPtrField<string>::pointer_iterator iter = - proto_array_.pointer_begin(); - EXPECT_EQ("foo", **iter); - ++iter; - EXPECT_EQ("bar", **(iter++)); - EXPECT_EQ("baz", **iter); - ++iter; - EXPECT_TRUE(proto_array_.pointer_end() == iter); - EXPECT_EQ("baz", **(--proto_array_.pointer_end())); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) { - RepeatedPtrField<string>::const_pointer_iterator iter = - const_proto_array_->pointer_begin(); - EXPECT_EQ("foo", **iter); - ++iter; - EXPECT_EQ("bar", **(iter++)); - EXPECT_EQ("baz", **iter); - ++iter; - EXPECT_TRUE(const_proto_array_->pointer_end() == iter); - EXPECT_EQ("baz", **(--const_proto_array_->pointer_end())); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) { - RepeatedPtrField<string>::pointer_iterator iter = - proto_array_.pointer_begin(); - RepeatedPtrField<string>::pointer_iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", *iter[2]); - EXPECT_EQ("baz", **(iter + 2)); - EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) { - RepeatedPtrField<string>::const_pointer_iterator iter = - const_proto_array_->pointer_begin(); - RepeatedPtrField<string>::const_pointer_iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", *iter[2]); - EXPECT_EQ("baz", **(iter + 2)); - EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin()); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) { - RepeatedPtrField<string>::pointer_iterator iter = - proto_array_.pointer_begin(); - RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) { - RepeatedPtrField<string>::const_pointer_iterator iter = - const_proto_array_->pointer_begin(); - RepeatedPtrField<string>::const_pointer_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs. -// Dereferencing an uninitialized iterator crashes the process. -TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) { - RepeatedPtrField<string>::pointer_iterator iter; - EXPECT_TRUE(iter != proto_array_.pointer_begin()); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2); - EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3); - EXPECT_TRUE(iter != proto_array_.pointer_end()); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) { - RepeatedPtrField<string>::const_pointer_iterator iter; - EXPECT_TRUE(iter != const_proto_array_->pointer_begin()); - EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1); - EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2); - EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3); - EXPECT_TRUE(iter != const_proto_array_->pointer_end()); -} - -// This comparison functor is required by the tests for RepeatedPtrOverPtrs. -// They operate on strings and need to compare strings as strings in -// any stl algorithm, even though the iterator returns a pointer to a string -// - i.e. *iter has type string*. -struct StringLessThan { - bool operator()(const string* z, const string& y) { - return *z < y; - } - bool operator()(const string* z, const string* y) const { return *z < *y; } -}; - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) { - proto_array_.Clear(); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("x"); - proto_array_.Add()->assign("y"); - - { - string v = "f"; - RepeatedPtrField<string>::pointer_iterator it = - std::lower_bound(proto_array_.pointer_begin(), - proto_array_.pointer_end(), &v, StringLessThan()); - - GOOGLE_CHECK(*it != NULL); - - EXPECT_EQ(**it, "n"); - EXPECT_TRUE(it == proto_array_.pointer_begin() + 3); - } - { - string v = "f"; - RepeatedPtrField<string>::const_pointer_iterator it = std::lower_bound( - const_proto_array_->pointer_begin(), const_proto_array_->pointer_end(), - &v, StringLessThan()); - - GOOGLE_CHECK(*it != NULL); - - EXPECT_EQ(**it, "n"); - EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3); - } -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) { - RepeatedPtrField<string>::pointer_iterator iter = - proto_array_.pointer_begin(); - **iter = "qux"; - EXPECT_EQ("qux", proto_array_.Get(0)); - - EXPECT_EQ("bar", proto_array_.Get(1)); - EXPECT_EQ("baz", proto_array_.Get(2)); - ++iter; - delete *iter; - *iter = new string("a"); - ++iter; - delete *iter; - *iter = new string("b"); - EXPECT_EQ("a", proto_array_.Get(1)); - EXPECT_EQ("b", proto_array_.Get(2)); -} - -TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) { - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("y"); - proto_array_.Add()->assign("x"); - EXPECT_EQ("foo", proto_array_.Get(0)); - EXPECT_EQ("n", proto_array_.Get(5)); - EXPECT_EQ("x", proto_array_.Get(9)); - std::sort(proto_array_.pointer_begin(), proto_array_.pointer_end(), - StringLessThan()); - EXPECT_EQ("a", proto_array_.Get(0)); - EXPECT_EQ("baz", proto_array_.Get(2)); - EXPECT_EQ("y", proto_array_.Get(9)); -} - - -// ----------------------------------------------------------------------------- -// Unit-tests for the insert iterators -// google::protobuf::RepeatedFieldBackInserter, -// google::protobuf::AllocatedRepeatedPtrFieldBackInserter -// Ported from util/gtl/proto-array-iterators_unittest. - -class RepeatedFieldInsertionIteratorsTest : public testing::Test { - protected: - std::list<double> halves; - std::list<int> fibonacci; - std::vector<string> words; - typedef TestAllTypes::NestedMessage Nested; - Nested nesteds[2]; - std::vector<Nested*> nested_ptrs; - TestAllTypes protobuffer; - - virtual void SetUp() { - fibonacci.push_back(1); - fibonacci.push_back(1); - fibonacci.push_back(2); - fibonacci.push_back(3); - fibonacci.push_back(5); - fibonacci.push_back(8); - std::copy(fibonacci.begin(), fibonacci.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32())); - - halves.push_back(1.0); - halves.push_back(0.5); - halves.push_back(0.25); - halves.push_back(0.125); - halves.push_back(0.0625); - std::copy(halves.begin(), halves.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_double())); - - words.push_back("Able"); - words.push_back("was"); - words.push_back("I"); - words.push_back("ere"); - words.push_back("I"); - words.push_back("saw"); - words.push_back("Elba"); - std::copy(words.begin(), words.end(), - RepeatedFieldBackInserter(protobuffer.mutable_repeated_string())); - - nesteds[0].set_bb(17); - nesteds[1].set_bb(4711); - std::copy(&nesteds[0], &nesteds[2], - RepeatedFieldBackInserter( - protobuffer.mutable_repeated_nested_message())); - - nested_ptrs.push_back(new Nested); - nested_ptrs.back()->set_bb(170); - nested_ptrs.push_back(new Nested); - nested_ptrs.back()->set_bb(47110); - std::copy(nested_ptrs.begin(), nested_ptrs.end(), - RepeatedFieldBackInserter( - protobuffer.mutable_repeated_nested_message())); - } - - virtual void TearDown() { - STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end()); - } -}; - -TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) { - EXPECT_TRUE(std::equal(fibonacci.begin(), - fibonacci.end(), - protobuffer.repeated_int32().begin())); - EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(), - protobuffer.repeated_int32().end(), - fibonacci.begin())); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) { - EXPECT_TRUE(std::equal(halves.begin(), - halves.end(), - protobuffer.repeated_double().begin())); - EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(), - protobuffer.repeated_double().end(), - halves.begin())); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Words) { - ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); - for (int i = 0; i < words.size(); ++i) - EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) { - words.clear(); - words.push_back("sing"); - words.push_back("a"); - words.push_back("song"); - words.push_back("of"); - words.push_back("six"); - words.push_back("pence"); - protobuffer.mutable_repeated_string()->Clear(); - std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter( - protobuffer.mutable_repeated_string())); - ASSERT_EQ(words.size(), protobuffer.repeated_string_size()); - for (int i = 0; i < words.size(); ++i) - EXPECT_EQ(words.at(i), protobuffer.repeated_string(i)); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) { - ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4); - EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17); - EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711); - EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170); - EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - AllocatedRepeatedPtrFieldWithStringIntData) { - vector<Nested*> data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - Nested* new_data = new Nested; - new_data->set_bb(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_nested_message(); - new_data->set_bb(i); - } - TestAllTypes testproto; - std::copy(data.begin(), data.end(), - AllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_nested_message())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - AllocatedRepeatedPtrFieldWithString) { - vector<string*> data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - string* new_data = new string; - *new_data = "name-" + SimpleItoa(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_string(); - *new_data = "name-" + SimpleItoa(i); - } - TestAllTypes testproto; - std::copy(data.begin(), data.end(), AllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_string())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData) { - vector<Nested*> data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - Nested* new_data = new Nested; - new_data->set_bb(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_nested_message(); - new_data->set_bb(i); - } - TestAllTypes testproto; - std::copy(data.begin(), data.end(), - UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_nested_message())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -TEST_F(RepeatedFieldInsertionIteratorsTest, - UnsafeArenaAllocatedRepeatedPtrFieldWithString) { - vector<string*> data; - TestAllTypes goldenproto; - for (int i = 0; i < 10; ++i) { - string* new_data = new string; - *new_data = "name-" + SimpleItoa(i); - data.push_back(new_data); - - new_data = goldenproto.add_repeated_string(); - *new_data = "name-" + SimpleItoa(i); - } - TestAllTypes testproto; - std::copy(data.begin(), data.end(), - UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( - testproto.mutable_repeated_string())); - EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); -} - -} // namespace - -} // namespace protobuf -} // namespace google |