1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 package com.google.protobuf; 9 10 import static com.google.common.truth.Truth.assertThat; 11 import static com.google.common.truth.Truth.assertWithMessage; 12 13 import protobuf_unittest.UnittestProto.TestAllTypes; 14 import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; 15 import java.util.Collections; 16 import java.util.List; 17 import org.junit.Test; 18 import org.junit.runner.RunWith; 19 import org.junit.runners.JUnit4; 20 21 /** 22 * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality. More extensive testing is 23 * provided via other tests that exercise the builder. 24 */ 25 @RunWith(JUnit4.class) 26 public class RepeatedFieldBuilderTest { 27 28 @Test testBasicUse()29 public void testBasicUse() { 30 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 31 RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 32 newRepeatedFieldBuilder(mockParent); 33 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); 34 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 35 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); 36 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); 37 38 List<TestAllTypes> list = builder.build(); 39 assertThat(list).hasSize(2); 40 assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); 41 assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); 42 assertIsUnmodifiable(list); 43 44 // Make sure it doesn't change. 45 List<TestAllTypes> list2 = builder.build(); 46 assertThat(list).isSameInstanceAs(list2); 47 assertThat(mockParent.getInvalidationCount()).isEqualTo(0); 48 } 49 50 @Test testGoingBackAndForth()51 public void testGoingBackAndForth() { 52 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 53 RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 54 newRepeatedFieldBuilder(mockParent); 55 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); 56 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 57 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); 58 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); 59 60 // Convert to list 61 List<TestAllTypes> list = builder.build(); 62 assertThat(list).hasSize(2); 63 assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); 64 assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); 65 assertIsUnmodifiable(list); 66 67 // Update 0th item 68 assertThat(mockParent.getInvalidationCount()).isEqualTo(0); 69 builder.getBuilder(0).setOptionalString("foo"); 70 assertThat(mockParent.getInvalidationCount()).isEqualTo(1); 71 list = builder.build(); 72 assertThat(list).hasSize(2); 73 assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); 74 assertThat(list.get(0).getOptionalString()).isEqualTo("foo"); 75 assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); 76 assertIsUnmodifiable(list); 77 assertThat(mockParent.getInvalidationCount()).isEqualTo(1); 78 } 79 80 @Test testVariousMethods()81 public void testVariousMethods() { 82 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 83 RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 84 newRepeatedFieldBuilder(mockParent); 85 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 86 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build()); 87 builder.addBuilder(0, TestAllTypes.getDefaultInstance()).setOptionalInt32(0); 88 builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3); 89 90 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); 91 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); 92 assertThat(builder.getMessage(2).getOptionalInt32()).isEqualTo(2); 93 assertThat(builder.getMessage(3).getOptionalInt32()).isEqualTo(3); 94 95 assertThat(mockParent.getInvalidationCount()).isEqualTo(0); 96 List<TestAllTypes> messages = builder.build(); 97 assertThat(messages).hasSize(4); 98 assertThat(messages).isSameInstanceAs(builder.build()); // expect same list 99 100 // Remove a message. 101 builder.remove(2); 102 assertThat(mockParent.getInvalidationCount()).isEqualTo(1); 103 assertThat(builder.getCount()).isEqualTo(3); 104 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); 105 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); 106 assertThat(builder.getMessage(2).getOptionalInt32()).isEqualTo(3); 107 108 // Remove a builder. 109 builder.remove(0); 110 assertThat(mockParent.getInvalidationCount()).isEqualTo(1); 111 assertThat(builder.getCount()).isEqualTo(2); 112 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(1); 113 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(3); 114 115 // Test clear. 116 builder.clear(); 117 assertThat(mockParent.getInvalidationCount()).isEqualTo(1); 118 assertThat(builder.getCount()).isEqualTo(0); 119 assertThat(builder.isEmpty()).isTrue(); 120 } 121 122 @Test testLists()123 public void testLists() { 124 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 125 RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 126 newRepeatedFieldBuilder(mockParent); 127 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 128 builder.addMessage(0, TestAllTypes.newBuilder().setOptionalInt32(0).build()); 129 assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); 130 assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); 131 132 // Use list of builders. 133 List<TestAllTypes.Builder> builders = builder.getBuilderList(); 134 assertThat(builders.get(0).getOptionalInt32()).isEqualTo(0); 135 assertThat(builders.get(1).getOptionalInt32()).isEqualTo(1); 136 builders.get(0).setOptionalInt32(10); 137 builders.get(1).setOptionalInt32(11); 138 139 // Use list of protos 140 List<TestAllTypes> protos = builder.getMessageList(); 141 assertThat(protos.get(0).getOptionalInt32()).isEqualTo(10); 142 assertThat(protos.get(1).getOptionalInt32()).isEqualTo(11); 143 144 // Add an item to the builders and verify it's updated in both 145 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build()); 146 assertThat(builders).hasSize(3); 147 assertThat(protos).hasSize(3); 148 } 149 assertIsUnmodifiable(List<?> list)150 private void assertIsUnmodifiable(List<?> list) { 151 if (list == Collections.emptyList()) { 152 // OKAY -- Need to check this b/c EmptyList allows you to call clear. 153 } else { 154 try { 155 list.clear(); 156 assertWithMessage("List wasn't immutable").fail(); 157 } catch (UnsupportedOperationException e) { 158 // good 159 } 160 } 161 } 162 163 private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent)164 newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) { 165 return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( 166 Collections.<TestAllTypes>emptyList(), false, parent, false); 167 } 168 } 169