1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 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 package com.google.protobuf; 32 33 import protobuf_unittest.UnittestProto.TestAllTypes; 34 import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; 35 import java.util.Collections; 36 import java.util.List; 37 import junit.framework.TestCase; 38 39 /** 40 * Tests for {@link RepeatedFieldBuilderV3}. This tests basic functionality. More extensive testing is 41 * provided via other tests that exercise the builder. 42 * 43 * @author jonp@google.com (Jon Perlow) 44 */ 45 public class RepeatedFieldBuilderV3Test extends TestCase { 46 testBasicUse()47 public void testBasicUse() { 48 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 49 RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 50 newRepeatedFieldBuilderV3(mockParent); 51 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); 52 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 53 assertEquals(0, builder.getMessage(0).getOptionalInt32()); 54 assertEquals(1, builder.getMessage(1).getOptionalInt32()); 55 56 List<TestAllTypes> list = builder.build(); 57 assertEquals(2, list.size()); 58 assertEquals(0, list.get(0).getOptionalInt32()); 59 assertEquals(1, list.get(1).getOptionalInt32()); 60 assertIsUnmodifiable(list); 61 62 // Make sure it doesn't change. 63 List<TestAllTypes> list2 = builder.build(); 64 assertSame(list, list2); 65 assertEquals(0, mockParent.getInvalidationCount()); 66 } 67 testGoingBackAndForth()68 public void testGoingBackAndForth() { 69 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 70 RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 71 newRepeatedFieldBuilderV3(mockParent); 72 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); 73 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 74 assertEquals(0, builder.getMessage(0).getOptionalInt32()); 75 assertEquals(1, builder.getMessage(1).getOptionalInt32()); 76 77 // Convert to list 78 List<TestAllTypes> list = builder.build(); 79 assertEquals(2, list.size()); 80 assertEquals(0, list.get(0).getOptionalInt32()); 81 assertEquals(1, list.get(1).getOptionalInt32()); 82 assertIsUnmodifiable(list); 83 84 // Update 0th item 85 assertEquals(0, mockParent.getInvalidationCount()); 86 builder.getBuilder(0).setOptionalString("foo"); 87 assertEquals(1, mockParent.getInvalidationCount()); 88 list = builder.build(); 89 assertEquals(2, list.size()); 90 assertEquals(0, list.get(0).getOptionalInt32()); 91 assertEquals("foo", list.get(0).getOptionalString()); 92 assertEquals(1, list.get(1).getOptionalInt32()); 93 assertIsUnmodifiable(list); 94 assertEquals(1, mockParent.getInvalidationCount()); 95 } 96 testVariousMethods()97 public void testVariousMethods() { 98 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 99 RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 100 newRepeatedFieldBuilderV3(mockParent); 101 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 102 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build()); 103 builder.addBuilder(0, TestAllTypes.getDefaultInstance()).setOptionalInt32(0); 104 builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3); 105 106 assertEquals(0, builder.getMessage(0).getOptionalInt32()); 107 assertEquals(1, builder.getMessage(1).getOptionalInt32()); 108 assertEquals(2, builder.getMessage(2).getOptionalInt32()); 109 assertEquals(3, builder.getMessage(3).getOptionalInt32()); 110 111 assertEquals(0, mockParent.getInvalidationCount()); 112 List<TestAllTypes> messages = builder.build(); 113 assertEquals(4, messages.size()); 114 assertSame(messages, builder.build()); // expect same list 115 116 // Remove a message. 117 builder.remove(2); 118 assertEquals(1, mockParent.getInvalidationCount()); 119 assertEquals(3, builder.getCount()); 120 assertEquals(0, builder.getMessage(0).getOptionalInt32()); 121 assertEquals(1, builder.getMessage(1).getOptionalInt32()); 122 assertEquals(3, builder.getMessage(2).getOptionalInt32()); 123 124 // Remove a builder. 125 builder.remove(0); 126 assertEquals(1, mockParent.getInvalidationCount()); 127 assertEquals(2, builder.getCount()); 128 assertEquals(1, builder.getMessage(0).getOptionalInt32()); 129 assertEquals(3, builder.getMessage(1).getOptionalInt32()); 130 131 // Test clear. 132 builder.clear(); 133 assertEquals(1, mockParent.getInvalidationCount()); 134 assertEquals(0, builder.getCount()); 135 assertTrue(builder.isEmpty()); 136 } 137 testLists()138 public void testLists() { 139 TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); 140 RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = 141 newRepeatedFieldBuilderV3(mockParent); 142 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); 143 builder.addMessage(0, TestAllTypes.newBuilder().setOptionalInt32(0).build()); 144 assertEquals(0, builder.getMessage(0).getOptionalInt32()); 145 assertEquals(1, builder.getMessage(1).getOptionalInt32()); 146 147 // Use list of builders. 148 List<TestAllTypes.Builder> builders = builder.getBuilderList(); 149 assertEquals(0, builders.get(0).getOptionalInt32()); 150 assertEquals(1, builders.get(1).getOptionalInt32()); 151 builders.get(0).setOptionalInt32(10); 152 builders.get(1).setOptionalInt32(11); 153 154 // Use list of protos 155 List<TestAllTypes> protos = builder.getMessageList(); 156 assertEquals(10, protos.get(0).getOptionalInt32()); 157 assertEquals(11, protos.get(1).getOptionalInt32()); 158 159 // Add an item to the builders and verify it's updated in both 160 builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build()); 161 assertEquals(3, builders.size()); 162 assertEquals(3, protos.size()); 163 } 164 assertIsUnmodifiable(List<?> list)165 private void assertIsUnmodifiable(List<?> list) { 166 if (list == Collections.emptyList()) { 167 // OKAY -- Need to check this b/c EmptyList allows you to call clear. 168 } else { 169 try { 170 list.clear(); 171 fail("List wasn't immutable"); 172 } catch (UnsupportedOperationException e) { 173 // good 174 } 175 } 176 } 177 178 private RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> newRepeatedFieldBuilderV3(GeneratedMessage.BuilderParent parent)179 newRepeatedFieldBuilderV3(GeneratedMessage.BuilderParent parent) { 180 return new RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( 181 Collections.<TestAllTypes>emptyList(), false, parent, false); 182 } 183 } 184