PageRenderTime 235ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/repeated_field_unittest.cc

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