| // 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. |
| |
| package com.google.protobuf; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| |
| import com.google.protobuf.Descriptors.Descriptor; |
| import com.google.protobuf.Descriptors.FieldDescriptor; |
| import com.google.protobuf.test.UnittestImport; |
| import protobuf_unittest.EnumWithNoOuter; |
| import protobuf_unittest.MessageWithNoOuter; |
| import protobuf_unittest.MultipleFilesTestProto; |
| import protobuf_unittest.NestedExtension.MyNestedExtension; |
| import protobuf_unittest.NonNestedExtension; |
| import protobuf_unittest.NonNestedExtension.MessageToBeExtended; |
| import protobuf_unittest.NonNestedExtension.MyNonNestedExtension; |
| import protobuf_unittest.OuterClassNameTest2OuterClass; |
| import protobuf_unittest.OuterClassNameTest3OuterClass; |
| import protobuf_unittest.OuterClassNameTestOuterClass; |
| import protobuf_unittest.ServiceWithNoOuter; |
| import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; |
| import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize; |
| import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; |
| import protobuf_unittest.UnittestProto; |
| import protobuf_unittest.UnittestProto.ForeignEnum; |
| import protobuf_unittest.UnittestProto.ForeignMessage; |
| import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder; |
| import protobuf_unittest.UnittestProto.NestedTestAllTypes; |
| import protobuf_unittest.UnittestProto.TestAllExtensions; |
| import protobuf_unittest.UnittestProto.TestAllTypes; |
| import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; |
| import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; |
| import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; |
| import protobuf_unittest.UnittestProto.TestOneof2; |
| import protobuf_unittest.UnittestProto.TestPackedTypes; |
| import protobuf_unittest.UnittestProto.TestUnpackedTypes; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import org.junit.After; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** |
| * Unit test for generated messages and generated code. See also {@link MessageTest}, which tests |
| * some generated message functionality. |
| */ |
| @SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"}) |
| @RunWith(JUnit4.class) |
| public class GeneratedMessageTest { |
| TestUtil.ReflectionTester reflectionTester = |
| new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); |
| |
| @After |
| public void tearDown() { |
| GeneratedMessageV3.setAlwaysUseFieldBuildersForTesting(false); |
| } |
| |
| @Test |
| public void testGetFieldBuilderForExtensionField() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| Message.Builder fieldBuilder = |
| builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor()); |
| int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| |
| // fieldBuilder still updates the builder after builder build() has been called. |
| expected += 100; |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| } |
| |
| @Test |
| public void testGetFieldBuilderWithExistingMessage() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| builder.setExtension( |
| UnittestProto.optionalNestedMessageExtension, |
| NestedMessage.newBuilder().setBb(123).build()); |
| Message.Builder fieldBuilder = |
| builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor()); |
| int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| |
| // fieldBuilder still updates the builder after builder build() has been called. |
| expected += 100; |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| } |
| |
| @Test |
| public void testGetFieldBuilderWithExistingBuilder() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123); |
| builder.setField( |
| UnittestProto.optionalNestedMessageExtension.getDescriptor(), nestedMessageBuilder); |
| Message.Builder fieldBuilder = |
| builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor()); |
| int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| |
| // Existing nestedMessageBuilder will also update builder. |
| expected += 100; |
| nestedMessageBuilder.setBb(expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| |
| // fieldBuilder still updates the builder. |
| expected += 100; |
| fieldBuilder.setField(field, expected); |
| assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) |
| .isEqualTo(expected); |
| } |
| |
| @Test |
| public void testGetRepeatedFieldBuilderForExtensionField() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| builder.addExtension( |
| UnittestProto.repeatedNestedMessageExtension, |
| NestedMessage.newBuilder().setBb(123).build()); |
| Message.Builder fieldBuilder = |
| builder.getRepeatedFieldBuilder( |
| UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); |
| int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat( |
| builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) |
| .isEqualTo(expected); |
| |
| // fieldBuilder still updates the builder after builder build() has been called. |
| expected += 100; |
| fieldBuilder.setField(field, expected); |
| assertThat( |
| builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) |
| .isEqualTo(expected); |
| } |
| |
| @Test |
| public void testGetRepeatedFieldBuilderForExistingBuilder() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123); |
| builder.addRepeatedField( |
| UnittestProto.repeatedNestedMessageExtension.getDescriptor(), nestedMessageBuilder); |
| Message.Builder fieldBuilder = |
| builder.getRepeatedFieldBuilder( |
| UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); |
| int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat( |
| builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) |
| .isEqualTo(expected); |
| |
| // Existing nestedMessageBuilder will also update builder. |
| expected += 100; |
| nestedMessageBuilder.setBb(expected); |
| assertThat( |
| builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) |
| .isEqualTo(expected); |
| |
| // fieldBuilder still updates the builder. |
| expected += 100; |
| fieldBuilder.setField(field, expected); |
| assertThat( |
| builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) |
| .isEqualTo(expected); |
| } |
| |
| @Test |
| public void testGetExtensionFieldOutOfBound() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| try { |
| builder.getRepeatedField(UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); |
| assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); |
| } catch (IndexOutOfBoundsException expected) { |
| } |
| try { |
| builder.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); |
| assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); |
| } catch (IndexOutOfBoundsException expected) { |
| } |
| TestAllExtensions extensionsMessage = builder.build(); |
| try { |
| extensionsMessage.getRepeatedField( |
| UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); |
| assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); |
| } catch (IndexOutOfBoundsException expected) { |
| } |
| try { |
| extensionsMessage.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); |
| assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); |
| } catch (IndexOutOfBoundsException expected) { |
| } |
| } |
| |
| @Test |
| public void testDefaultInstance() throws Exception { |
| assertThat(TestAllTypes.getDefaultInstance()) |
| .isSameInstanceAs(TestAllTypes.getDefaultInstance().getDefaultInstanceForType()); |
| assertThat(TestAllTypes.getDefaultInstance()) |
| .isSameInstanceAs(TestAllTypes.newBuilder().getDefaultInstanceForType()); |
| } |
| |
| @Test |
| public void testMessageOrBuilder() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.setAllFields(builder); |
| TestAllTypes message = builder.build(); |
| TestUtil.assertAllFieldsSet(message); |
| } |
| |
| @Test |
| public void testUsingBuilderMultipleTimes() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| // primitive field scalar and repeated |
| builder.setOptionalSfixed64(100); |
| builder.addRepeatedInt32(100); |
| // enum field scalar and repeated |
| builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); |
| builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); |
| // proto field scalar and repeated |
| builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1)); |
| builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1)); |
| |
| TestAllTypes value1 = builder.build(); |
| |
| assertThat(value1.getOptionalSfixed64()).isEqualTo(100); |
| assertThat(value1.getRepeatedInt32(0)).isEqualTo(100); |
| assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); |
| assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); |
| assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1); |
| assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1); |
| |
| // Make sure that builder didn't update previously created values |
| builder.setOptionalSfixed64(200); |
| builder.setRepeatedInt32(0, 200); |
| builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO); |
| builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO); |
| builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2)); |
| builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2)); |
| |
| TestAllTypes value2 = builder.build(); |
| |
| // Make sure value1 didn't change. |
| assertThat(value1.getOptionalSfixed64()).isEqualTo(100); |
| assertThat(value1.getRepeatedInt32(0)).isEqualTo(100); |
| assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); |
| assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); |
| assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1); |
| assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1); |
| |
| // Make sure value2 is correct |
| assertThat(value2.getOptionalSfixed64()).isEqualTo(200); |
| assertThat(value2.getRepeatedInt32(0)).isEqualTo(200); |
| assertThat(value2.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO); |
| assertThat(value2.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO); |
| assertThat(value2.getOptionalForeignMessage().getC()).isEqualTo(2); |
| assertThat(value2.getRepeatedForeignMessage(0).getC()).isEqualTo(2); |
| } |
| |
| @Test |
| public void testProtosShareRepeatedArraysIfDidntChange() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| builder.addRepeatedInt32(100); |
| builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); |
| |
| TestAllTypes value1 = builder.build(); |
| TestAllTypes value2 = value1.toBuilder().build(); |
| |
| assertThat(value1.getRepeatedInt32List()).isSameInstanceAs(value2.getRepeatedInt32List()); |
| assertThat(value1.getRepeatedForeignMessageList()) |
| .isSameInstanceAs(value2.getRepeatedForeignMessageList()); |
| } |
| |
| @Test |
| public void testRepeatedArraysAreImmutable() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| builder.addRepeatedInt32(100); |
| builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); |
| builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); |
| assertIsUnmodifiable(builder.getRepeatedInt32List()); |
| assertIsUnmodifiable(builder.getRepeatedImportEnumList()); |
| assertIsUnmodifiable(builder.getRepeatedForeignMessageList()); |
| assertIsUnmodifiable(builder.getRepeatedFloatList()); |
| |
| TestAllTypes value = builder.build(); |
| assertIsUnmodifiable(value.getRepeatedInt32List()); |
| assertIsUnmodifiable(value.getRepeatedImportEnumList()); |
| assertIsUnmodifiable(value.getRepeatedForeignMessageList()); |
| assertIsUnmodifiable(value.getRepeatedFloatList()); |
| } |
| |
| @Test |
| public void testParsedMessagesAreImmutable() throws Exception { |
| TestAllTypes value = TestAllTypes.parser().parseFrom(TestUtil.getAllSet().toByteString()); |
| assertIsUnmodifiable(value.getRepeatedInt32List()); |
| assertIsUnmodifiable(value.getRepeatedInt64List()); |
| assertIsUnmodifiable(value.getRepeatedUint32List()); |
| assertIsUnmodifiable(value.getRepeatedUint64List()); |
| assertIsUnmodifiable(value.getRepeatedSint32List()); |
| assertIsUnmodifiable(value.getRepeatedSint64List()); |
| assertIsUnmodifiable(value.getRepeatedFixed32List()); |
| assertIsUnmodifiable(value.getRepeatedFixed64List()); |
| assertIsUnmodifiable(value.getRepeatedSfixed32List()); |
| assertIsUnmodifiable(value.getRepeatedSfixed64List()); |
| assertIsUnmodifiable(value.getRepeatedFloatList()); |
| assertIsUnmodifiable(value.getRepeatedDoubleList()); |
| assertIsUnmodifiable(value.getRepeatedBoolList()); |
| assertIsUnmodifiable(value.getRepeatedStringList()); |
| assertIsUnmodifiable(value.getRepeatedBytesList()); |
| assertIsUnmodifiable(value.getRepeatedGroupList()); |
| assertIsUnmodifiable(value.getRepeatedNestedMessageList()); |
| assertIsUnmodifiable(value.getRepeatedForeignMessageList()); |
| assertIsUnmodifiable(value.getRepeatedImportMessageList()); |
| assertIsUnmodifiable(value.getRepeatedNestedEnumList()); |
| assertIsUnmodifiable(value.getRepeatedForeignEnumList()); |
| assertIsUnmodifiable(value.getRepeatedImportEnumList()); |
| } |
| |
| private void assertIsUnmodifiable(List<?> list) { |
| if (list == Collections.emptyList()) { |
| // OKAY -- Need to check this b/c EmptyList allows you to call clear. |
| } else { |
| try { |
| list.clear(); |
| assertWithMessage("List wasn't immutable").fail(); |
| } catch (UnsupportedOperationException e) { |
| // good |
| } |
| } |
| } |
| |
| @Test |
| public void testSettersRejectNull() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| try { |
| builder.setOptionalString(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.setOptionalBytes(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.setOptionalNestedMessage((TestAllTypes.NestedMessage.Builder) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.setOptionalNestedEnum(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.addRepeatedString(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.addRepeatedBytes(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage.Builder) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.addRepeatedNestedEnum(null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| } |
| |
| @Test |
| public void testRepeatedSetters() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.setAllFields(builder); |
| TestUtil.modifyRepeatedFields(builder); |
| TestAllTypes message = builder.build(); |
| TestUtil.assertRepeatedFieldsModified(message); |
| } |
| |
| @Test |
| public void testRepeatedSettersRejectNull() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| |
| builder.addRepeatedString("one"); |
| builder.addRepeatedString("two"); |
| try { |
| builder.setRepeatedString(1, null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| builder.addRepeatedBytes(TestUtil.toBytes("one")); |
| builder.addRepeatedBytes(TestUtil.toBytes("two")); |
| try { |
| builder.setRepeatedBytes(1, null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); |
| builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(456).build()); |
| try { |
| builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage.Builder) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO); |
| builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); |
| try { |
| builder.setRepeatedNestedEnum(1, null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| } |
| |
| @Test |
| public void testRepeatedAppend() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| |
| builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4)); |
| builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ)); |
| |
| ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build(); |
| builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage)); |
| |
| TestAllTypes message = builder.build(); |
| assertThat(Arrays.asList(1, 2, 3, 4)).isEqualTo(message.getRepeatedInt32List()); |
| assertThat(Arrays.asList(ForeignEnum.FOREIGN_BAZ)) |
| .isEqualTo(message.getRepeatedForeignEnumList()); |
| assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(1); |
| assertThat(message.getRepeatedForeignMessage(0).getC()).isEqualTo(12); |
| } |
| |
| @Test |
| public void testRepeatedAppendRejectsNull() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| |
| ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build(); |
| try { |
| builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage, (ForeignMessage) null)); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| try { |
| builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ, null)); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| try { |
| builder.addAllRepeatedString(Arrays.asList("one", null)); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| |
| try { |
| builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null)); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| } |
| |
| @Test |
| public void testRepeatedAppendIterateOnlyOnce() throws Exception { |
| // Create a Iterable that can only be iterated once. |
| Iterable<String> stringIterable = |
| new Iterable<String>() { |
| private boolean called = false; |
| |
| @Override |
| public Iterator<String> iterator() { |
| if (called) { |
| throw new IllegalStateException(); |
| } |
| called = true; |
| return Arrays.asList("one", "two", "three").iterator(); |
| } |
| }; |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| builder.addAllRepeatedString(stringIterable); |
| assertThat(builder.getRepeatedStringCount()).isEqualTo(3); |
| assertThat(builder.getRepeatedString(0)).isEqualTo("one"); |
| assertThat(builder.getRepeatedString(1)).isEqualTo("two"); |
| assertThat(builder.getRepeatedString(2)).isEqualTo("three"); |
| |
| try { |
| builder.addAllRepeatedString(stringIterable); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (IllegalStateException e) { |
| // We expect this exception. |
| } |
| } |
| |
| @Test |
| public void testMergeFromOtherRejectsNull() throws Exception { |
| try { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| builder.mergeFrom((TestAllTypes) null); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (NullPointerException e) { |
| // We expect this exception. |
| } |
| } |
| |
| @Test |
| public void testSettingForeignMessageUsingBuilder() throws Exception { |
| TestAllTypes message = |
| TestAllTypes.newBuilder() |
| // Pass builder for foreign message instance. |
| .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123)) |
| .build(); |
| TestAllTypes expectedMessage = |
| TestAllTypes.newBuilder() |
| // Create expected version passing foreign message instance explicitly. |
| .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123).build()) |
| .build(); |
| // TODO(ngd): Upgrade to using real #equals method once implemented |
| assertThat(message.toString()).isEqualTo(expectedMessage.toString()); |
| } |
| |
| @Test |
| public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception { |
| TestAllTypes message = |
| TestAllTypes.newBuilder() |
| // Pass builder for foreign message instance. |
| .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456)) |
| .build(); |
| TestAllTypes expectedMessage = |
| TestAllTypes.newBuilder() |
| // Create expected version passing foreign message instance explicitly. |
| .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456).build()) |
| .build(); |
| assertThat(message.toString()).isEqualTo(expectedMessage.toString()); |
| } |
| |
| @Test |
| public void testDefaults() throws Exception { |
| TestUtil.assertClear(TestAllTypes.getDefaultInstance()); |
| TestUtil.assertClear(TestAllTypes.newBuilder().build()); |
| |
| TestExtremeDefaultValues message = TestExtremeDefaultValues.getDefaultInstance(); |
| assertThat(message.getUtf8String()).isEqualTo("\u1234"); |
| assertThat(message.getInfDouble()).isEqualTo(Double.POSITIVE_INFINITY); |
| assertThat(message.getNegInfDouble()).isEqualTo(Double.NEGATIVE_INFINITY); |
| assertThat(Double.isNaN(message.getNanDouble())).isTrue(); |
| assertThat(message.getInfFloat()).isEqualTo(Float.POSITIVE_INFINITY); |
| assertThat(message.getNegInfFloat()).isEqualTo(Float.NEGATIVE_INFINITY); |
| assertThat(Float.isNaN(message.getNanFloat())).isTrue(); |
| assertThat(message.getCppTrigraph()).isEqualTo("? ? ?? ?? ??? ??/ ??-"); |
| } |
| |
| @Test |
| public void testClear() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.assertClear(builder); |
| TestUtil.setAllFields(builder); |
| builder.clear(); |
| TestUtil.assertClear(builder); |
| } |
| |
| @Test |
| public void testReflectionGetters() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.setAllFields(builder); |
| reflectionTester.assertAllFieldsSetViaReflection(builder); |
| |
| TestAllTypes message = builder.build(); |
| reflectionTester.assertAllFieldsSetViaReflection(message); |
| } |
| |
| @Test |
| public void testReflectionSetters() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.setAllFieldsViaReflection(builder); |
| TestUtil.assertAllFieldsSet(builder); |
| |
| TestAllTypes message = builder.build(); |
| TestUtil.assertAllFieldsSet(message); |
| } |
| |
| @Test |
| public void testReflectionSettersRejectNull() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.assertReflectionSettersRejectNull(builder); |
| } |
| |
| @Test |
| public void testReflectionRepeatedSetters() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.setAllFieldsViaReflection(builder); |
| reflectionTester.modifyRepeatedFieldsViaReflection(builder); |
| TestUtil.assertRepeatedFieldsModified(builder); |
| |
| TestAllTypes message = builder.build(); |
| TestUtil.assertRepeatedFieldsModified(message); |
| } |
| |
| @Test |
| public void testReflectionRepeatedSettersRejectNull() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); |
| } |
| |
| @Test |
| public void testReflectionDefaults() throws Exception { |
| reflectionTester.assertClearViaReflection(TestAllTypes.getDefaultInstance()); |
| reflectionTester.assertClearViaReflection(TestAllTypes.newBuilder().build()); |
| } |
| |
| @Test |
| public void testReflectionGetOneof() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.setAllFieldsViaReflection(builder); |
| Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); |
| Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); |
| assertThat(field).isSameInstanceAs(builder.getOneofFieldDescriptor(oneof)); |
| |
| TestAllTypes message = builder.build(); |
| assertThat(field).isSameInstanceAs(message.getOneofFieldDescriptor(oneof)); |
| } |
| |
| @Test |
| public void testReflectionClearOneof() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| reflectionTester.setAllFieldsViaReflection(builder); |
| Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); |
| Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); |
| |
| assertThat(builder.hasOneof(oneof)).isTrue(); |
| assertThat(builder.hasField(field)).isTrue(); |
| builder.clearOneof(oneof); |
| assertThat(builder.hasOneof(oneof)).isFalse(); |
| assertThat(builder.hasField(field)).isFalse(); |
| } |
| |
| @Test |
| public void testEnumInterface() throws Exception { |
| assertThat(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()) |
| .isInstanceOf(ProtocolMessageEnum.class); |
| } |
| |
| @Test |
| public void testEnumMap() throws Exception { |
| Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap(); |
| |
| for (ForeignEnum value : ForeignEnum.values()) { |
| assertThat(map.findValueByNumber(value.getNumber())).isEqualTo(value); |
| } |
| |
| assertThat(map.findValueByNumber(12345) == null).isTrue(); |
| } |
| |
| @Test |
| public void testParsePackedToUnpacked() throws Exception { |
| TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); |
| TestUnpackedTypes message = builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); |
| TestUtil.assertUnpackedFieldsSet(message); |
| } |
| |
| @Test |
| public void testParseUnpackedToPacked() throws Exception { |
| TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); |
| TestPackedTypes message = builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); |
| TestUtil.assertPackedFieldsSet(message); |
| } |
| |
| // ================================================================= |
| // Extensions. |
| |
| TestUtil.ReflectionTester extensionsReflectionTester = |
| new TestUtil.ReflectionTester( |
| TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry()); |
| |
| @Test |
| public void testExtensionMessageOrBuilder() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| TestUtil.setAllExtensions(builder); |
| TestAllExtensions message = builder.build(); |
| TestUtil.assertAllExtensionsSet(message); |
| } |
| |
| @Test |
| public void testGetBuilderForExtensionField() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| Message.Builder fieldBuilder = |
| builder.newBuilderForField(UnittestProto.optionalNestedMessageExtension.getDescriptor()); |
| final int expected = 7432; |
| FieldDescriptor field = |
| NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); |
| fieldBuilder.setField(field, expected); |
| assertThat(fieldBuilder.build().getField(field)).isEqualTo(expected); |
| } |
| |
| |
| @Test |
| public void testGetBuilderForNonMessageExtensionField() { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| try { |
| // This should throw an exception because the extension field is not a message. |
| builder.newBuilderForField(UnittestProto.optionalInt32Extension.getDescriptor()); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // This exception is expected. |
| } |
| } |
| |
| @Test |
| public void testExtensionRepeatedSetters() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| TestUtil.setAllExtensions(builder); |
| TestUtil.modifyRepeatedExtensions(builder); |
| TestAllExtensions message = builder.build(); |
| TestUtil.assertRepeatedExtensionsModified(message); |
| } |
| |
| @Test |
| public void testExtensionDefaults() throws Exception { |
| TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance()); |
| TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build()); |
| } |
| |
| @Test |
| public void testUnsetRepeatedExtensionGetField() { |
| TestAllExtensions message = TestAllExtensions.getDefaultInstance(); |
| Object value; |
| |
| value = message.getField(UnittestProto.repeatedStringExtension.getDescriptor()); |
| assertThat(value instanceof List).isTrue(); |
| assertThat(((List<?>) value).isEmpty()).isTrue(); |
| assertIsUnmodifiable((List<?>) value); |
| |
| value = message.getField(UnittestProto.repeatedNestedMessageExtension.getDescriptor()); |
| assertThat(value instanceof List).isTrue(); |
| assertThat(((List<?>) value).isEmpty()).isTrue(); |
| assertIsUnmodifiable((List<?>) value); |
| } |
| |
| @Test |
| public void testExtensionReflectionGetters() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| TestUtil.setAllExtensions(builder); |
| extensionsReflectionTester.assertAllFieldsSetViaReflection(builder); |
| |
| TestAllExtensions message = builder.build(); |
| extensionsReflectionTester.assertAllFieldsSetViaReflection(message); |
| } |
| |
| @Test |
| public void testExtensionReflectionSetters() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| extensionsReflectionTester.setAllFieldsViaReflection(builder); |
| TestUtil.assertAllExtensionsSet(builder); |
| |
| TestAllExtensions message = builder.build(); |
| TestUtil.assertAllExtensionsSet(message); |
| } |
| |
| @Test |
| public void testExtensionReflectionSettersRejectNull() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| extensionsReflectionTester.assertReflectionSettersRejectNull(builder); |
| } |
| |
| @Test |
| public void testExtensionReflectionRepeatedSetters() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| extensionsReflectionTester.setAllFieldsViaReflection(builder); |
| extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder); |
| TestUtil.assertRepeatedExtensionsModified(builder); |
| |
| TestAllExtensions message = builder.build(); |
| TestUtil.assertRepeatedExtensionsModified(message); |
| } |
| |
| @Test |
| public void testExtensionReflectionRepeatedSettersRejectNull() throws Exception { |
| TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); |
| extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(builder); |
| } |
| |
| @Test |
| public void testExtensionReflectionDefaults() throws Exception { |
| extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.getDefaultInstance()); |
| extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.newBuilder().build()); |
| } |
| |
| @Test |
| public void testClearExtension() throws Exception { |
| // clearExtension() is not actually used in TestUtil, so try it manually. |
| assertThat( |
| TestAllExtensions.newBuilder() |
| .setExtension(UnittestProto.optionalInt32Extension, 1) |
| .clearExtension(UnittestProto.optionalInt32Extension) |
| .hasExtension(UnittestProto.optionalInt32Extension)) |
| .isFalse(); |
| assertThat( |
| TestAllExtensions.newBuilder() |
| .addExtension(UnittestProto.repeatedInt32Extension, 1) |
| .clearExtension(UnittestProto.repeatedInt32Extension) |
| .getExtensionCount(UnittestProto.repeatedInt32Extension)) |
| .isEqualTo(0); |
| } |
| |
| @Test |
| public void testExtensionCopy() throws Exception { |
| TestAllExtensions original = TestUtil.getAllExtensionsSet(); |
| TestAllExtensions copy = TestAllExtensions.newBuilder(original).build(); |
| TestUtil.assertAllExtensionsSet(copy); |
| } |
| |
| @Test |
| public void testExtensionMergeFrom() throws Exception { |
| TestAllExtensions original = |
| TestAllExtensions.newBuilder() |
| .setExtension(UnittestProto.optionalInt32Extension, 1) |
| .build(); |
| TestAllExtensions merged = TestAllExtensions.newBuilder().mergeFrom(original).build(); |
| assertThat(merged.hasExtension(UnittestProto.optionalInt32Extension)).isTrue(); |
| assertThat((int) merged.getExtension(UnittestProto.optionalInt32Extension)).isEqualTo(1); |
| } |
| |
| // ================================================================= |
| // multiple_files_test |
| |
| // Test that custom options of an file level enum are properly initialized. |
| // This test needs to be put before any other access to MultipleFilesTestProto |
| // or messages defined in multiple_files_test.proto because the class loading |
| // order affects initialization process of custom options. |
| @Test |
| public void testEnumValueOptionsInMultipleFilesMode() throws Exception { |
| assertThat( |
| EnumWithNoOuter.FOO |
| .getValueDescriptor() |
| .getOptions() |
| .getExtension(MultipleFilesTestProto.enumValueOption) |
| .intValue()) |
| .isEqualTo(12345); |
| } |
| |
| @Test |
| public void testMultipleFilesOption() throws Exception { |
| // We mostly just want to check that things compile. |
| MessageWithNoOuter message = |
| MessageWithNoOuter.newBuilder() |
| .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1)) |
| .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1)) |
| .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ) |
| .setForeignEnum(EnumWithNoOuter.BAR) |
| .build(); |
| assertThat(MessageWithNoOuter.parseFrom(message.toByteString())).isEqualTo(message); |
| |
| assertThat(MessageWithNoOuter.getDescriptor().getFile()) |
| .isEqualTo(MultipleFilesTestProto.getDescriptor()); |
| |
| Descriptors.FieldDescriptor field = |
| MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum"); |
| assertThat(message.getField(field)).isEqualTo(EnumWithNoOuter.BAR.getValueDescriptor()); |
| |
| assertThat(ServiceWithNoOuter.getDescriptor().getFile()) |
| .isEqualTo(MultipleFilesTestProto.getDescriptor()); |
| |
| assertThat( |
| TestAllExtensions.getDefaultInstance() |
| .hasExtension(MultipleFilesTestProto.extensionWithOuter)) |
| .isFalse(); |
| } |
| |
| @Test |
| public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize() throws Exception { |
| TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.getDefaultInstance(); |
| assertThat(message.isInitialized()).isTrue(); |
| |
| message = |
| TestOptionalOptimizedForSize.newBuilder() |
| .setO(TestRequiredOptimizedForSize.newBuilder().buildPartial()) |
| .buildPartial(); |
| assertThat(message.isInitialized()).isFalse(); |
| |
| message = |
| TestOptionalOptimizedForSize.newBuilder() |
| .setO(TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()) |
| .buildPartial(); |
| assertThat(message.isInitialized()).isTrue(); |
| } |
| |
| @Test |
| public void testUninitializedExtensionInOptimizedForSize() throws Exception { |
| TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder(); |
| builder.setExtension( |
| TestOptimizedForSize.testExtension2, |
| TestRequiredOptimizedForSize.newBuilder().buildPartial()); |
| assertThat(builder.isInitialized()).isFalse(); |
| assertThat(builder.buildPartial().isInitialized()).isFalse(); |
| |
| builder = TestOptimizedForSize.newBuilder(); |
| builder.setExtension( |
| TestOptimizedForSize.testExtension2, |
| TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial()); |
| assertThat(builder.isInitialized()).isTrue(); |
| assertThat(builder.buildPartial().isInitialized()).isTrue(); |
| } |
| |
| @Test |
| public void testToBuilder() throws Exception { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.setAllFields(builder); |
| TestAllTypes message = builder.build(); |
| TestUtil.assertAllFieldsSet(message); |
| TestUtil.assertAllFieldsSet(message.toBuilder().build()); |
| } |
| |
| @Test |
| public void testFieldConstantValues() throws Exception { |
| assertThat(TestAllTypes.NestedMessage.BB_FIELD_NUMBER).isEqualTo(1); |
| assertThat(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER).isEqualTo(1); |
| assertThat(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER).isEqualTo(16); |
| assertThat(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(18); |
| assertThat(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER).isEqualTo(21); |
| assertThat(TestAllTypes.REPEATED_INT32_FIELD_NUMBER).isEqualTo(31); |
| assertThat(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER).isEqualTo(46); |
| assertThat(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(48); |
| assertThat(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER).isEqualTo(51); |
| } |
| |
| @Test |
| public void testExtensionConstantValues() throws Exception { |
| assertThat(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER).isEqualTo(1000); |
| assertThat(UnittestProto.TestRequired.MULTI_FIELD_NUMBER).isEqualTo(1001); |
| assertThat(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(1); |
| assertThat(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(16); |
| assertThat(UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(18); |
| assertThat(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(21); |
| assertThat(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(31); |
| assertThat(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(46); |
| assertThat(UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(48); |
| assertThat(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(51); |
| } |
| |
| @Test |
| public void testRecursiveMessageDefaultInstance() throws Exception { |
| UnittestProto.TestRecursiveMessage message = |
| UnittestProto.TestRecursiveMessage.getDefaultInstance(); |
| assertThat(message != null).isTrue(); |
| assertThat(message.getA()).isNotNull(); |
| assertThat(message.getA().equals(message)).isTrue(); |
| } |
| |
| @Test |
| public void testSerialize() throws Exception { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestUtil.setAllFields(builder); |
| TestAllTypes expected = builder.build(); |
| ObjectOutputStream out = new ObjectOutputStream(baos); |
| try { |
| out.writeObject(expected); |
| } finally { |
| out.close(); |
| } |
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
| ObjectInputStream in = new ObjectInputStream(bais); |
| TestAllTypes actual = (TestAllTypes) in.readObject(); |
| assertThat(actual).isEqualTo(expected); |
| } |
| |
| @Test |
| public void testSerializePartial() throws Exception { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestAllTypes expected = builder.buildPartial(); |
| ObjectOutputStream out = new ObjectOutputStream(baos); |
| try { |
| out.writeObject(expected); |
| } finally { |
| out.close(); |
| } |
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
| ObjectInputStream in = new ObjectInputStream(bais); |
| TestAllTypes actual = (TestAllTypes) in.readObject(); |
| assertThat(actual).isEqualTo(expected); |
| } |
| |
| @Test |
| public void testDeserializeWithoutClassField() throws Exception { |
| // serialized form for version <=3.6.0 |
| // just includes messageClassName and asBytes |
| |
| // Int32Value.newBuilder().setValue(123).build() |
| byte[] int32ValueBytes = |
| new byte[] { |
| -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, |
| 114, 111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, |
| 115, 115, 97, 103, 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, 101, |
| 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 91, 0, 7, 97, 115, 66, 121, 116, |
| 101, 115, 116, 0, 2, 91, 66, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, |
| 115, 115, 78, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, |
| 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, |
| 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 2, 8, 123, 116, 0, 30, 99, 111, 109, 46, 103, 111, |
| 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, |
| 86, 97, 108, 117, 101 |
| }; |
| |
| ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); |
| ObjectInputStream in = new ObjectInputStream(bais); |
| Int32Value int32Value = (Int32Value) in.readObject(); |
| assertThat(int32Value.getValue()).isEqualTo(123); |
| } |
| |
| @Test |
| public void testDeserializeWithClassField() throws Exception { |
| // serialized form for version > 3.6.0 |
| // includes messageClass, messageClassName (for compatibility), and asBytes |
| |
| // Int32Value.newBuilder().setValue(123).build() |
| byte[] int32ValueBytes = |
| new byte[] { |
| -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, |
| 114, 111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, |
| 115, 115, 97, 103, 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, 101, |
| 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 91, 0, 7, 97, 115, 66, 121, 116, |
| 101, 115, 116, 0, 2, 91, 66, 76, 0, 12, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, |
| 115, 115, 116, 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, |
| 115, 59, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 78, 97, 109, |
| 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, |
| 103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, |
| 112, 0, 0, 0, 2, 8, 123, 118, 114, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, |
| 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, 86, 97, 108, 117, |
| 101, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 66, 0, 21, 109, 101, 109, 111, 105, 122, 101, 100, |
| 73, 115, 73, 110, 105, 116, 105, 97, 108, 105, 122, 101, 100, 73, 0, 6, 118, 97, 108, 117, |
| 101, 95, 120, 114, 0, 38, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, |
| 111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, |
| 115, 97, 103, 101, 86, 51, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 76, 0, 13, 117, 110, 107, 110, |
| 111, 119, 110, 70, 105, 101, 108, 100, 115, 116, 0, 37, 76, 99, 111, 109, 47, 103, 111, |
| 111, 103, 108, 101, 47, 112, 114, 111, 116, 111, 98, 117, 102, 47, 85, 110, 107, 110, 111, |
| 119, 110, 70, 105, 101, 108, 100, 83, 101, 116, 59, 120, 112, 116, 0, 30, 99, 111, 109, |
| 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, |
| 116, 51, 50, 86, 97, 108, 117, 101 |
| }; |
| |
| ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); |
| ObjectInputStream in = new ObjectInputStream(bais); |
| Int32Value int32Value = (Int32Value) in.readObject(); |
| assertThat(int32Value.getValue()).isEqualTo(123); |
| } |
| |
| @Test |
| public void testEnumValues() { |
| assertThat(TestAllTypes.NestedEnum.BAR.getNumber()) |
| .isEqualTo(TestAllTypes.NestedEnum.BAR_VALUE); |
| assertThat(TestAllTypes.NestedEnum.BAZ.getNumber()) |
| .isEqualTo(TestAllTypes.NestedEnum.BAZ_VALUE); |
| assertThat(TestAllTypes.NestedEnum.FOO.getNumber()) |
| .isEqualTo(TestAllTypes.NestedEnum.FOO_VALUE); |
| } |
| |
| @Test |
| public void testNonNestedExtensionInitialization() { |
| assertThat(NonNestedExtension.nonNestedExtension.getMessageDefaultInstance()) |
| .isInstanceOf(MyNonNestedExtension.class); |
| assertThat(NonNestedExtension.nonNestedExtension.getDescriptor().getName()) |
| .isEqualTo("nonNestedExtension"); |
| } |
| |
| @Test |
| public void testNestedExtensionInitialization() { |
| assertThat(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()) |
| .isInstanceOf(MessageToBeExtended.class); |
| assertThat(MyNestedExtension.recursiveExtension.getDescriptor().getName()) |
| .isEqualTo("recursiveExtension"); |
| } |
| |
| @Test |
| public void testInvalidations() throws Exception { |
| GeneratedMessageV3.setAlwaysUseFieldBuildersForTesting(true); |
| TestAllTypes.NestedMessage nestedMessage1 = TestAllTypes.NestedMessage.newBuilder().build(); |
| TestAllTypes.NestedMessage nestedMessage2 = TestAllTypes.NestedMessage.newBuilder().build(); |
| |
| // Set all three flavors (enum, primitive, message and singular/repeated) |
| // and verify no invalidations fired |
| TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); |
| |
| TestAllTypes.Builder builder = |
| (TestAllTypes.Builder) |
| ((AbstractMessage) TestAllTypes.getDefaultInstance()).newBuilderForType(mockParent); |
| builder.setOptionalInt32(1); |
| builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); |
| builder.setOptionalNestedMessage(nestedMessage1); |
| builder.addRepeatedInt32(1); |
| builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); |
| builder.addRepeatedNestedMessage(nestedMessage1); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(0); |
| |
| // Now tell it we want changes and make sure it's only fired once |
| // And do this for each flavor |
| |
| // primitive single |
| builder.buildPartial(); |
| builder.setOptionalInt32(2); |
| builder.setOptionalInt32(3); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(1); |
| |
| // enum single |
| builder.buildPartial(); |
| builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ); |
| builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(2); |
| |
| // message single |
| builder.buildPartial(); |
| builder.setOptionalNestedMessage(nestedMessage2); |
| builder.setOptionalNestedMessage(nestedMessage1); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(3); |
| |
| // primitive repeated |
| builder.buildPartial(); |
| builder.addRepeatedInt32(2); |
| builder.addRepeatedInt32(3); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(4); |
| |
| // enum repeated |
| builder.buildPartial(); |
| builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); |
| builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(5); |
| |
| // message repeated |
| builder.buildPartial(); |
| builder.addRepeatedNestedMessage(nestedMessage2); |
| builder.addRepeatedNestedMessage(nestedMessage1); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(6); |
| } |
| |
| @Test |
| public void testInvalidations_Extensions() throws Exception { |
| TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); |
| |
| TestAllExtensions.Builder builder = |
| (TestAllExtensions.Builder) |
| ((AbstractMessage) TestAllExtensions.getDefaultInstance()) |
| .newBuilderForType(mockParent); |
| |
| builder.addExtension(UnittestProto.repeatedInt32Extension, 1); |
| builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2); |
| builder.clearExtension(UnittestProto.repeatedInt32Extension); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(0); |
| |
| // Now tell it we want changes and make sure it's only fired once |
| builder.buildPartial(); |
| builder.addExtension(UnittestProto.repeatedInt32Extension, 2); |
| builder.addExtension(UnittestProto.repeatedInt32Extension, 3); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(1); |
| |
| builder.buildPartial(); |
| builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4); |
| builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(2); |
| |
| builder.buildPartial(); |
| builder.clearExtension(UnittestProto.repeatedInt32Extension); |
| builder.clearExtension(UnittestProto.repeatedInt32Extension); |
| assertThat(mockParent.getInvalidationCount()).isEqualTo(3); |
| } |
| |
| @Test |
| public void testBaseMessageOrBuilder() { |
| // Mostly just makes sure the base interface exists and has some methods. |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| TestAllTypes message = builder.buildPartial(); |
| TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message; |
| |
| assertThat(messageAsInterface.getDefaultBool()).isEqualTo(messageAsInterface.getDefaultBool()); |
| assertThat(messageAsInterface.getOptionalDouble()) |
| .isEqualTo(messageAsInterface.getOptionalDouble()); |
| } |
| |
| @Test |
| public void testMessageOrBuilderGetters() { |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| |
| // single fields |
| assertThat(ForeignMessage.getDefaultInstance()) |
| .isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder()); |
| ForeignMessage.Builder subBuilder = builder.getOptionalForeignMessageBuilder(); |
| assertThat(subBuilder).isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder()); |
| |
| // repeated fields |
| ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial(); |
| ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial(); |
| ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial(); |
| builder.addRepeatedForeignMessage(m0); |
| builder.addRepeatedForeignMessage(m1); |
| builder.addRepeatedForeignMessage(m2); |
| assertThat(m0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0)); |
| assertThat(m1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1)); |
| assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2)); |
| ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0); |
| ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1); |
| assertThat(b0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0)); |
| assertThat(b1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1)); |
| assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2)); |
| |
| List<? extends ForeignMessageOrBuilder> messageOrBuilderList = |
| builder.getRepeatedForeignMessageOrBuilderList(); |
| assertThat(b0).isSameInstanceAs(messageOrBuilderList.get(0)); |
| assertThat(b1).isSameInstanceAs(messageOrBuilderList.get(1)); |
| assertThat(m2).isSameInstanceAs(messageOrBuilderList.get(2)); |
| } |
| |
| @Test |
| public void testGetFieldBuilder() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| |
| FieldDescriptor fieldDescriptor = descriptor.findFieldByName("optional_nested_message"); |
| FieldDescriptor foreignFieldDescriptor = descriptor.findFieldByName("optional_foreign_message"); |
| FieldDescriptor importFieldDescriptor = descriptor.findFieldByName("optional_import_message"); |
| |
| // Mutate the message with new field builder |
| // Mutate nested message |
| TestAllTypes.Builder builder1 = TestAllTypes.newBuilder(); |
| Message.Builder fieldBuilder1 = |
| builder1 |
| .newBuilderForField(fieldDescriptor) |
| .mergeFrom((Message) builder1.getField(fieldDescriptor)); |
| FieldDescriptor subFieldDescriptor1 = |
| fieldBuilder1.getDescriptorForType().findFieldByName("bb"); |
| fieldBuilder1.setField(subFieldDescriptor1, 1); |
| builder1.setField(fieldDescriptor, fieldBuilder1.build()); |
| |
| // Mutate foreign message |
| Message.Builder foreignFieldBuilder1 = |
| builder1 |
| .newBuilderForField(foreignFieldDescriptor) |
| .mergeFrom((Message) builder1.getField(foreignFieldDescriptor)); |
| FieldDescriptor subForeignFieldDescriptor1 = |
| foreignFieldBuilder1.getDescriptorForType().findFieldByName("c"); |
| foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2); |
| builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build()); |
| |
| // Mutate import message |
| Message.Builder importFieldBuilder1 = |
| builder1 |
| .newBuilderForField(importFieldDescriptor) |
| .mergeFrom((Message) builder1.getField(importFieldDescriptor)); |
| FieldDescriptor subImportFieldDescriptor1 = |
| importFieldBuilder1.getDescriptorForType().findFieldByName("d"); |
| importFieldBuilder1.setField(subImportFieldDescriptor1, 3); |
| builder1.setField(importFieldDescriptor, importFieldBuilder1.build()); |
| |
| Message newMessage1 = builder1.build(); |
| |
| // Mutate the message with existing field builder |
| // Mutate nested message |
| TestAllTypes.Builder builder2 = TestAllTypes.newBuilder(); |
| Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor); |
| FieldDescriptor subFieldDescriptor2 = |
| fieldBuilder2.getDescriptorForType().findFieldByName("bb"); |
| fieldBuilder2.setField(subFieldDescriptor2, 1); |
| builder2.setField(fieldDescriptor, fieldBuilder2.build()); |
| |
| // Mutate foreign message |
| Message.Builder foreignFieldBuilder2 = |
| builder2 |
| .newBuilderForField(foreignFieldDescriptor) |
| .mergeFrom((Message) builder2.getField(foreignFieldDescriptor)); |
| FieldDescriptor subForeignFieldDescriptor2 = |
| foreignFieldBuilder2.getDescriptorForType().findFieldByName("c"); |
| foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2); |
| builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build()); |
| |
| // Mutate import message |
| Message.Builder importFieldBuilder2 = |
| builder2 |
| .newBuilderForField(importFieldDescriptor) |
| .mergeFrom((Message) builder2.getField(importFieldDescriptor)); |
| FieldDescriptor subImportFieldDescriptor2 = |
| importFieldBuilder2.getDescriptorForType().findFieldByName("d"); |
| importFieldBuilder2.setField(subImportFieldDescriptor2, 3); |
| builder2.setField(importFieldDescriptor, importFieldBuilder2.build()); |
| |
| Message newMessage2 = builder2.build(); |
| |
| // These two messages should be equal. |
| assertThat(newMessage1).isEqualTo(newMessage2); |
| } |
| |
| @Test |
| public void testGetFieldBuilderWithInitializedValue() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| FieldDescriptor fieldDescriptor = descriptor.findFieldByName("optional_nested_message"); |
| |
| // Before setting field, builder is initialized by default value. |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| NestedMessage.Builder fieldBuilder = |
| (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); |
| assertThat(fieldBuilder.getBb()).isEqualTo(0); |
| |
| // Setting field value with new field builder instance. |
| builder = TestAllTypes.newBuilder(); |
| NestedMessage.Builder newFieldBuilder = builder.getOptionalNestedMessageBuilder(); |
| newFieldBuilder.setBb(2); |
| // Then get the field builder instance by getFieldBuilder(). |
| fieldBuilder = (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); |
| // It should contain new value. |
| assertThat(fieldBuilder.getBb()).isEqualTo(2); |
| // These two builder should be equal. |
| assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder); |
| } |
| |
| @Test |
| public void testGetFieldBuilderNotSupportedException() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| try { |
| builder.getFieldBuilder(descriptor.findFieldByName("optional_int32")); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getFieldBuilder(descriptor.findFieldByName("optional_nested_enum")); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32")); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_enum")); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_message")); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| } |
| |
| // Test that when the default outer class name conflicts with another type |
| // defined in the proto the compiler will append a suffix to avoid the |
| // conflict. |
| @Test |
| public void testConflictingOuterClassName() { |
| // We just need to make sure we can refer to the outer class with the |
| // expected name. There is nothing else to test. |
| OuterClassNameTestOuterClass.OuterClassNameTest message = |
| OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build(); |
| assertThat(message.getDescriptorForType()) |
| .isSameInstanceAs(OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor()); |
| |
| OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2 message2 = |
| OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2.newBuilder() |
| .build(); |
| assertThat(message2.getSerializedSize()).isEqualTo(0); |
| |
| OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3 enumValue = |
| OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3.DUMMY_VALUE; |
| assertThat(enumValue.getNumber()).isEqualTo(1); |
| } |
| |
| // ================================================================= |
| // oneof generated code test |
| @Test |
| public void testOneofEnumCase() throws Exception { |
| TestOneof2 message = |
| TestOneof2.newBuilder().setFooInt(123).setFooString("foo").setFooCord("bar").build(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| } |
| |
| @Test |
| public void testClearOneof() throws Exception { |
| TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123); |
| assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_INT); |
| builder.clearFoo(); |
| assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_NOT_SET); |
| } |
| |
| @Test |
| public void testSetOneofClearsOthers() throws Exception { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooInt(123).setFooString("foo").buildPartial(); |
| assertThat(message.hasFooString()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = builder.setFooCord("bar").buildPartial(); |
| assertThat(message.hasFooCord()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = builder.setFooStringPiece("baz").buildPartial(); |
| assertThat(message.hasFooStringPiece()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = builder.setFooBytes(TestUtil.toBytes("qux")).buildPartial(); |
| assertThat(message.hasFooBytes()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial(); |
| assertThat(message.hasFooEnum()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = |
| builder |
| .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) |
| .buildPartial(); |
| assertThat(message.hasFooMessage()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| |
| message = builder.setFooInt(123).buildPartial(); |
| assertThat(message.hasFooInt()).isTrue(); |
| TestUtil.assertAtMostOneFieldSetOneof(message); |
| } |
| |
| @Test |
| public void testOneofTypes() throws Exception { |
| // Primitive |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooInt()).isEqualTo(0); |
| assertThat(builder.hasFooInt()).isFalse(); |
| assertThat(builder.setFooInt(123).hasFooInt()).isTrue(); |
| assertThat(builder.getFooInt()).isEqualTo(123); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooInt()).isTrue(); |
| assertThat(123).isEqualTo(message.getFooInt()); |
| |
| assertThat(builder.clearFooInt().hasFooInt()).isFalse(); |
| TestOneof2 message2 = builder.build(); |
| assertThat(message2.hasFooInt()).isFalse(); |
| assertThat(message2.getFooInt()).isEqualTo(0); |
| } |
| |
| // Enum |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO); |
| assertThat(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum()).isTrue(); |
| assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooEnum()).isTrue(); |
| assertThat(message.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); |
| |
| assertThat(builder.clearFooEnum().hasFooEnum()).isFalse(); |
| TestOneof2 message2 = builder.build(); |
| assertThat(message2.hasFooEnum()).isFalse(); |
| assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO); |
| } |
| |
| // String |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooString()).isEmpty(); |
| builder.setFooString("foo"); |
| assertThat(builder.hasFooString()).isTrue(); |
| assertThat(builder.getFooString()).isEqualTo("foo"); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooString()).isTrue(); |
| assertThat(message.getFooString()).isEqualTo("foo"); |
| assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringBytes()); |
| |
| assertThat(builder.clearFooString().hasFooString()).isFalse(); |
| TestOneof2 message2 = builder.buildPartial(); |
| assertThat(message2.hasFooString()).isFalse(); |
| assertThat(message2.getFooString()).isEmpty(); |
| assertThat(message2.getFooStringBytes()).isEqualTo(TestUtil.toBytes("")); |
| |
| // Get method should not change the oneof value. |
| builder.setFooInt(123); |
| assertThat(builder.getFooString()).isEmpty(); |
| assertThat(builder.getFooStringBytes()).isEqualTo(TestUtil.toBytes("")); |
| assertThat(builder.getFooInt()).isEqualTo(123); |
| |
| message = builder.build(); |
| assertThat(message.getFooString()).isEmpty(); |
| assertThat(TestUtil.toBytes("")).isEqualTo(message.getFooStringBytes()); |
| assertThat(message.getFooInt()).isEqualTo(123); |
| } |
| |
| // Cord |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooCord()).isEmpty(); |
| builder.setFooCord("foo"); |
| assertThat(builder.hasFooCord()).isTrue(); |
| assertThat(builder.getFooCord()).isEqualTo("foo"); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooCord()).isTrue(); |
| assertThat(message.getFooCord()).isEqualTo("foo"); |
| assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooCordBytes()); |
| |
| assertThat(builder.clearFooCord().hasFooCord()).isFalse(); |
| TestOneof2 message2 = builder.build(); |
| assertThat(message2.hasFooCord()).isFalse(); |
| assertThat(message2.getFooCord()).isEmpty(); |
| assertThat(message2.getFooCordBytes()).isEqualTo(TestUtil.toBytes("")); |
| } |
| |
| // StringPiece |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooStringPiece()).isEmpty(); |
| builder.setFooStringPiece("foo"); |
| assertThat(builder.hasFooStringPiece()).isTrue(); |
| assertThat(builder.getFooStringPiece()).isEqualTo("foo"); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooStringPiece()).isTrue(); |
| assertThat(message.getFooStringPiece()).isEqualTo("foo"); |
| assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringPieceBytes()); |
| |
| assertThat(builder.clearFooStringPiece().hasFooStringPiece()).isFalse(); |
| TestOneof2 message2 = builder.build(); |
| assertThat(message2.hasFooStringPiece()).isFalse(); |
| assertThat(message2.getFooStringPiece()).isEmpty(); |
| assertThat(message2.getFooStringPieceBytes()).isEqualTo(TestUtil.toBytes("")); |
| } |
| |
| // Message |
| { |
| // set |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(0); |
| builder.setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()); |
| assertThat(builder.hasFooMessage()).isTrue(); |
| assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(234); |
| TestOneof2 message = builder.buildPartial(); |
| assertThat(message.hasFooMessage()).isTrue(); |
| assertThat(message.getFooMessage().getQuxInt()).isEqualTo(234); |
| |
| // clear |
| assertThat(builder.clearFooMessage().hasFooString()).isFalse(); |
| message = builder.build(); |
| assertThat(message.hasFooMessage()).isFalse(); |
| assertThat(message.getFooMessage().getQuxInt()).isEqualTo(0); |
| |
| // nested builder |
| builder = TestOneof2.newBuilder(); |
| assertThat(builder.getFooMessageOrBuilder()) |
| .isSameInstanceAs(TestOneof2.NestedMessage.getDefaultInstance()); |
| assertThat(builder.hasFooMessage()).isFalse(); |
| builder.getFooMessageBuilder().setQuxInt(123); |
| assertThat(builder.hasFooMessage()).isTrue(); |
| assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(123); |
| message = builder.build(); |
| assertThat(message.hasFooMessage()).isTrue(); |
| assertThat(message.getFooMessage().getQuxInt()).isEqualTo(123); |
| } |
| |
| // LazyMessage is tested in LazyMessageLiteTest.java |
| } |
| |
| @Test |
| public void testOneofMerge() throws Exception { |
| // Primitive Type |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooInt(123).build(); |
| TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); |
| assertThat(message2.hasFooInt()).isTrue(); |
| assertThat(message2.getFooInt()).isEqualTo(123); |
| } |
| |
| // String |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooString("foo").build(); |
| TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); |
| assertThat(message2.hasFooString()).isTrue(); |
| assertThat(message2.getFooString()).isEqualTo("foo"); |
| } |
| |
| // Enum |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build(); |
| TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); |
| assertThat(message2.hasFooEnum()).isTrue(); |
| assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); |
| } |
| |
| // Message |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = |
| builder |
| .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) |
| .build(); |
| TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); |
| assertThat(message2.hasFooMessage()).isTrue(); |
| assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); |
| } |
| } |
| |
| @Test |
| public void testOneofSerialization() throws Exception { |
| // Primitive Type |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooInt(123).build(); |
| ByteString serialized = message.toByteString(); |
| TestOneof2 message2 = TestOneof2.parseFrom(serialized); |
| assertThat(message2.hasFooInt()).isTrue(); |
| assertThat(message2.getFooInt()).isEqualTo(123); |
| } |
| |
| // String |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooString("foo").build(); |
| ByteString serialized = message.toByteString(); |
| TestOneof2 message2 = TestOneof2.parseFrom(serialized); |
| assertThat(message2.hasFooString()).isTrue(); |
| assertThat(message2.getFooString()).isEqualTo("foo"); |
| } |
| |
| // Enum |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build(); |
| ByteString serialized = message.toByteString(); |
| TestOneof2 message2 = TestOneof2.parseFrom(serialized); |
| assertThat(message2.hasFooEnum()).isTrue(); |
| assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); |
| } |
| |
| // Message |
| { |
| TestOneof2.Builder builder = TestOneof2.newBuilder(); |
| TestOneof2 message = |
| builder |
| .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) |
| .build(); |
| ByteString serialized = message.toByteString(); |
| TestOneof2 message2 = TestOneof2.parseFrom(serialized); |
| assertThat(message2.hasFooMessage()).isTrue(); |
| assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); |
| } |
| } |
| |
| @Test |
| public void testOneofNestedBuilderOnChangePropagation() { |
| NestedTestAllTypes.Builder parentBuilder = NestedTestAllTypes.newBuilder(); |
| TestAllTypes.Builder builder = parentBuilder.getPayloadBuilder(); |
| builder.getOneofNestedMessageBuilder(); |
| assertThat(builder.hasOneofNestedMessage()).isTrue(); |
| assertThat(parentBuilder.hasPayload()).isTrue(); |
| NestedTestAllTypes message = parentBuilder.build(); |
| assertThat(message.hasPayload()).isTrue(); |
| assertThat(message.getPayload().hasOneofNestedMessage()).isTrue(); |
| } |
| |
| @Test |
| public void testGetRepeatedFieldBuilder() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| |
| FieldDescriptor fieldDescriptor = descriptor.findFieldByName("repeated_nested_message"); |
| FieldDescriptor foreignFieldDescriptor = descriptor.findFieldByName("repeated_foreign_message"); |
| FieldDescriptor importFieldDescriptor = descriptor.findFieldByName("repeated_import_message"); |
| |
| // Mutate the message with new field builder |
| // Mutate nested message |
| TestAllTypes.Builder builder1 = TestAllTypes.newBuilder(); |
| Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor); |
| FieldDescriptor subFieldDescriptor1 = |
| fieldBuilder1.getDescriptorForType().findFieldByName("bb"); |
| fieldBuilder1.setField(subFieldDescriptor1, 1); |
| builder1.addRepeatedField(fieldDescriptor, fieldBuilder1.build()); |
| |
| // Mutate foreign message |
| Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(foreignFieldDescriptor); |
| FieldDescriptor subForeignFieldDescriptor1 = |
| foreignFieldBuilder1.getDescriptorForType().findFieldByName("c"); |
| foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2); |
| builder1.addRepeatedField(foreignFieldDescriptor, foreignFieldBuilder1.build()); |
| |
| // Mutate import message |
| Message.Builder importFieldBuilder1 = builder1.newBuilderForField(importFieldDescriptor); |
| FieldDescriptor subImportFieldDescriptor1 = |
| importFieldBuilder1.getDescriptorForType().findFieldByName("d"); |
| importFieldBuilder1.setField(subImportFieldDescriptor1, 3); |
| builder1.addRepeatedField(importFieldDescriptor, importFieldBuilder1.build()); |
| |
| Message newMessage1 = builder1.build(); |
| |
| // Mutate the message with existing field builder |
| // Mutate nested message |
| TestAllTypes.Builder builder2 = TestAllTypes.newBuilder(); |
| builder2.addRepeatedNestedMessageBuilder(); |
| Message.Builder fieldBuilder2 = builder2.getRepeatedFieldBuilder(fieldDescriptor, 0); |
| FieldDescriptor subFieldDescriptor2 = |
| fieldBuilder2.getDescriptorForType().findFieldByName("bb"); |
| fieldBuilder2.setField(subFieldDescriptor2, 1); |
| |
| // Mutate foreign message |
| Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(foreignFieldDescriptor); |
| FieldDescriptor subForeignFieldDescriptor2 = |
| foreignFieldBuilder2.getDescriptorForType().findFieldByName("c"); |
| foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2); |
| builder2.addRepeatedField(foreignFieldDescriptor, foreignFieldBuilder2.build()); |
| |
| // Mutate import message |
| Message.Builder importFieldBuilder2 = builder2.newBuilderForField(importFieldDescriptor); |
| FieldDescriptor subImportFieldDescriptor2 = |
| importFieldBuilder2.getDescriptorForType().findFieldByName("d"); |
| importFieldBuilder2.setField(subImportFieldDescriptor2, 3); |
| builder2.addRepeatedField(importFieldDescriptor, importFieldBuilder2.build()); |
| |
| Message newMessage2 = builder2.build(); |
| |
| // These two messages should be equal. |
| assertThat(newMessage1).isEqualTo(newMessage2); |
| } |
| |
| @Test |
| public void testGetRepeatedFieldBuilderWithInitializedValue() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| FieldDescriptor fieldDescriptor = descriptor.findFieldByName("repeated_nested_message"); |
| |
| // Before setting field, builder is initialized by default value. |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| builder.addRepeatedNestedMessageBuilder(); |
| NestedMessage.Builder fieldBuilder = |
| (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0); |
| assertThat(fieldBuilder.getBb()).isEqualTo(0); |
| |
| // Setting field value with new field builder instance. |
| builder = TestAllTypes.newBuilder(); |
| NestedMessage.Builder newFieldBuilder = builder.addRepeatedNestedMessageBuilder(); |
| newFieldBuilder.setBb(2); |
| // Then get the field builder instance by getRepeatedFieldBuilder(). |
| fieldBuilder = (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0); |
| // It should contain new value. |
| assertThat(fieldBuilder.getBb()).isEqualTo(2); |
| // These two builder should be equal. |
| assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder); |
| } |
| |
| @Test |
| public void testGetRepeatedFieldBuilderNotSupportedException() { |
| Descriptor descriptor = TestAllTypes.getDescriptor(); |
| TestAllTypes.Builder builder = TestAllTypes.newBuilder(); |
| try { |
| builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"), 0); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_enum"), 0); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| try { |
| builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_message"), 0); |
| assertWithMessage("Exception was not thrown").fail(); |
| } catch (UnsupportedOperationException e) { |
| // We expect this exception. |
| } |
| } |
| } |