diff options
author | Max Cai <maxtroy@google.com> | 2013-09-20 18:29:40 +0100 |
---|---|---|
committer | Max Cai <maxtroy@google.com> | 2013-09-23 15:27:13 +0100 |
commit | b337f25628ceb3649df5c4e89b5125e7698a9b47 (patch) | |
tree | dd8dc893365bbe59b77a303e163e10532eaf6017 /java/src/test | |
parent | ee4410d551c43d800e821ffd220cc69535fef19e (diff) | |
download | protobuf-b337f25628ceb3649df5c4e89b5125e7698a9b47.tar.gz protobuf-b337f25628ceb3649df5c4e89b5125e7698a9b47.tar.bz2 protobuf-b337f25628ceb3649df5c4e89b5125e7698a9b47.zip |
Accessor style for optional fields.
This CL implements the 'optional_field_style=accessors' option.
All optional fields will now be 1 Java field and 1 bit in a shared
bitfield behind get/set/has/clear accessor methods. The setter
performs null check for reference types (Strings and byte[]s).
Also decentralized the clear code generation.
Change-Id: I60ac78329e352e76c2f8139fba1f292383080ad3
Diffstat (limited to 'java/src/test')
-rw-r--r-- | java/src/test/java/com/google/protobuf/NanoTest.java | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/java/src/test/java/com/google/protobuf/NanoTest.java b/java/src/test/java/com/google/protobuf/NanoTest.java index b00f2892..fb6cccb2 100644 --- a/java/src/test/java/com/google/protobuf/NanoTest.java +++ b/java/src/test/java/com/google/protobuf/NanoTest.java @@ -40,6 +40,7 @@ import com.google.protobuf.nano.MessageScopeEnumRefNano; import com.google.protobuf.nano.MultipleImportingNonMultipleNano1; import com.google.protobuf.nano.MultipleImportingNonMultipleNano2; import com.google.protobuf.nano.MultipleNameClashNano; +import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors; import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas; import com.google.protobuf.nano.NanoOuterClass; import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano; @@ -48,7 +49,6 @@ import com.google.protobuf.nano.UnittestMultipleNano; import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano; import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano; import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano; -import com.google.protobuf.nano.UnittestStringutf8Nano.StringUtf8; import junit.framework.TestCase; @@ -62,6 +62,7 @@ import java.util.List; * @author ulas@google.com Ulas Kirazci */ public class NanoTest extends TestCase { + @Override public void setUp() throws Exception { } @@ -2243,6 +2244,153 @@ public class NanoTest extends TestCase { assertEquals(0, newMsg.id); } + public void testNanoWithAccessorsBasic() throws Exception { + TestNanoAccessors msg = new TestNanoAccessors(); + + // Makes sure required and repeated fields are still public fields + msg.id = 3; + msg.repeatedBytes = new byte[2][3]; + + // Test accessors + assertEquals(0, msg.getOptionalInt32()); + assertFalse(msg.hasOptionalInt32()); + msg.setOptionalInt32(135); + assertEquals(135, msg.getOptionalInt32()); + assertTrue(msg.hasOptionalInt32()); + msg.clearOptionalInt32(); + assertFalse(msg.hasOptionalInt32()); + msg.setOptionalInt32(0); // default value + assertTrue(msg.hasOptionalInt32()); + + // Test NPE + try { + msg.setOptionalBytes(null); + fail(); + } catch (NullPointerException expected) {} + try { + msg.setOptionalString(null); + fail(); + } catch (NullPointerException expected) {} + try { + msg.setOptionalNestedMessage(null); + fail(); + } catch (NullPointerException expected) {} + + // Test has bit on bytes field with defaults and clear() re-clones the default array + assertFalse(msg.hasDefaultBytes()); + byte[] defaultBytes = msg.getDefaultBytes(); + msg.setDefaultBytes(defaultBytes); + assertTrue(msg.hasDefaultBytes()); + msg.clearDefaultBytes(); + assertFalse(msg.hasDefaultBytes()); + defaultBytes[0]++; // modify original array + assertFalse(Arrays.equals(defaultBytes, msg.getDefaultBytes())); + + // Test has bits that require additional bit fields + assertFalse(msg.hasBitFieldCheck()); + msg.setBitFieldCheck(0); + assertTrue(msg.hasBitFieldCheck()); + assertFalse(msg.hasBeforeBitFieldCheck()); // checks bit field does not leak + assertFalse(msg.hasAfterBitFieldCheck()); + + // Test clear() clears has bits + msg.setOptionalString("hi"); + msg.setDefaultString("there"); + msg.clear(); + assertFalse(msg.hasOptionalString()); + assertFalse(msg.hasDefaultString()); + assertFalse(msg.hasBitFieldCheck()); + } + + public void testNanoWithAccessorsParseFrom() throws Exception { + TestNanoAccessors msg = null; + // Test false on creation, after clear and upon empty parse. + for (int i = 0; i < 3; i++) { + if (i == 0) { + msg = new TestNanoAccessors(); + } else if (i == 1) { + msg.clear(); + } else if (i == 2) { + msg = TestNanoAccessors.parseFrom(new byte[0]); + } + assertFalse(msg.hasOptionalInt32()); + assertFalse(msg.hasOptionalString()); + assertFalse(msg.hasOptionalBytes()); + assertFalse(msg.hasOptionalNestedEnum()); + assertFalse(msg.hasDefaultInt32()); + assertFalse(msg.hasDefaultString()); + assertFalse(msg.hasDefaultBytes()); + assertFalse(msg.hasDefaultFloatNan()); + assertFalse(msg.hasDefaultNestedEnum()); + msg.setOptionalNestedMessage(new TestNanoAccessors.NestedMessage()); + msg.getOptionalNestedMessage().setBb(2); + msg.setOptionalNestedEnum(TestNanoAccessors.BAZ); + msg.setDefaultInt32(msg.getDefaultInt32()); + } + + byte [] result = MessageNano.toByteArray(msg); + int msgSerializedSize = msg.getSerializedSize(); + //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); + assertTrue(msgSerializedSize == 14); + assertEquals(result.length, msgSerializedSize); + + // Has fields true upon parse. + TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result); + assertEquals(2, newMsg.getOptionalNestedMessage().getBb()); + assertTrue(newMsg.getOptionalNestedMessage().hasBb()); + assertEquals(TestNanoAccessors.BAZ, newMsg.getOptionalNestedEnum()); + assertTrue(newMsg.hasOptionalNestedEnum()); + + // Has field true on fields with explicit default values from wire. + assertTrue(newMsg.hasDefaultInt32()); + assertEquals(41, newMsg.getDefaultInt32()); + } + + public void testNanoWithAccessorsSerialize() throws Exception { + TestNanoAccessors msg = new TestNanoAccessors(); + msg.setOptionalInt32(msg.getOptionalInt32()); + msg.setOptionalString(msg.getOptionalString()); + msg.setOptionalBytes(msg.getOptionalBytes()); + TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage(); + nestedMessage.setBb(nestedMessage.getBb()); + msg.setOptionalNestedMessage(nestedMessage); + msg.setOptionalNestedEnum(msg.getOptionalNestedEnum()); + msg.setDefaultInt32(msg.getDefaultInt32()); + msg.setDefaultString(msg.getDefaultString()); + msg.setDefaultBytes(msg.getDefaultBytes()); + msg.setDefaultFloatNan(msg.getDefaultFloatNan()); + msg.setDefaultNestedEnum(msg.getDefaultNestedEnum()); + + byte [] result = MessageNano.toByteArray(msg); + int msgSerializedSize = msg.getSerializedSize(); + assertEquals(result.length, msgSerializedSize); + + // Now deserialize and find that all fields are set and equal to their defaults. + TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result); + assertTrue(newMsg.hasOptionalInt32()); + assertTrue(newMsg.hasOptionalString()); + assertTrue(newMsg.hasOptionalBytes()); + assertTrue(newMsg.hasOptionalNestedMessage()); + assertTrue(newMsg.getOptionalNestedMessage().hasBb()); + assertTrue(newMsg.hasOptionalNestedEnum()); + assertTrue(newMsg.hasDefaultInt32()); + assertTrue(newMsg.hasDefaultString()); + assertTrue(newMsg.hasDefaultBytes()); + assertTrue(newMsg.hasDefaultFloatNan()); + assertTrue(newMsg.hasDefaultNestedEnum()); + assertEquals(0, newMsg.getOptionalInt32()); + assertEquals(0, newMsg.getOptionalString().length()); + assertEquals(0, newMsg.getOptionalBytes().length); + assertEquals(0, newMsg.getOptionalNestedMessage().getBb()); + assertEquals(TestNanoAccessors.FOO, newMsg.getOptionalNestedEnum()); + assertEquals(41, newMsg.getDefaultInt32()); + assertEquals("hello", newMsg.getDefaultString()); + assertEquals("world", new String(newMsg.getDefaultBytes(), "UTF-8")); + assertEquals(TestNanoAccessors.BAR, newMsg.getDefaultNestedEnum()); + assertEquals(Float.NaN, newMsg.getDefaultFloatNan()); + assertEquals(0, newMsg.id); + } + /** * Tests that fields with a default value of NaN are not serialized when * set to NaN. This is a special case as NaN != NaN, so normal equality |