diff options
Diffstat (limited to 'third_party/protobuf/3.2.0/java/util/src/test/java')
4 files changed, 0 insertions, 2386 deletions
diff --git a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java deleted file mode 100644 index 3ee0fc6e6a..0000000000 --- a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java +++ /dev/null @@ -1,261 +0,0 @@ -// 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.util; - -import protobuf_unittest.UnittestProto.NestedTestAllTypes; -import protobuf_unittest.UnittestProto.TestAllTypes; -import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; - -import junit.framework.TestCase; - -public class FieldMaskTreeTest extends TestCase { - public void testAddFieldPath() throws Exception { - FieldMaskTree tree = new FieldMaskTree(); - assertEquals("", tree.toString()); - tree.addFieldPath(""); - assertEquals("", tree.toString()); - // New branch. - tree.addFieldPath("foo"); - assertEquals("foo", tree.toString()); - // Redundant path. - tree.addFieldPath("foo"); - assertEquals("foo", tree.toString()); - // New branch. - tree.addFieldPath("bar.baz"); - assertEquals("bar.baz,foo", tree.toString()); - // Redundant sub-path. - tree.addFieldPath("foo.bar"); - assertEquals("bar.baz,foo", tree.toString()); - // New branch from a non-root node. - tree.addFieldPath("bar.quz"); - assertEquals("bar.baz,bar.quz,foo", tree.toString()); - // A path that matches several existing sub-paths. - tree.addFieldPath("bar"); - assertEquals("bar,foo", tree.toString()); - } - - public void testMergeFromFieldMask() throws Exception { - FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); - assertEquals("bar.baz,bar.quz,foo", tree.toString()); - tree.mergeFromFieldMask(FieldMaskUtil.fromString("foo.bar,bar")); - assertEquals("bar,foo", tree.toString()); - } - - public void testIntersectFieldPath() throws Exception { - FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); - FieldMaskTree result = new FieldMaskTree(); - // Empty path. - tree.intersectFieldPath("", result); - assertEquals("", result.toString()); - // Non-exist path. - tree.intersectFieldPath("quz", result); - assertEquals("", result.toString()); - // Sub-path of an existing leaf. - tree.intersectFieldPath("foo.bar", result); - assertEquals("foo.bar", result.toString()); - // Match an existing leaf node. - tree.intersectFieldPath("foo", result); - assertEquals("foo", result.toString()); - // Non-exist path. - tree.intersectFieldPath("bar.foo", result); - assertEquals("foo", result.toString()); - // Match a non-leaf node. - tree.intersectFieldPath("bar", result); - assertEquals("bar.baz,bar.quz,foo", result.toString()); - } - - public void testMerge() throws Exception { - TestAllTypes value = - TestAllTypes.newBuilder() - .setOptionalInt32(1234) - .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678)) - .addRepeatedInt32(4321) - .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765)) - .build(); - NestedTestAllTypes source = - NestedTestAllTypes.newBuilder() - .setPayload(value) - .setChild(NestedTestAllTypes.newBuilder().setPayload(value)) - .build(); - // Now we have a message source with the following structure: - // [root] -+- payload -+- optional_int32 - // | +- optional_nested_message - // | +- repeated_int32 - // | +- repeated_nested_message - // | - // +- child --- payload -+- optional_int32 - // +- optional_nested_message - // +- repeated_int32 - // +- repeated_nested_message - - FieldMaskUtil.MergeOptions options = new FieldMaskUtil.MergeOptions(); - - // Test merging each individual field. - NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree().addFieldPath("payload.optional_int32").merge(source, builder, options); - NestedTestAllTypes.Builder expected = NestedTestAllTypes.newBuilder(); - expected.getPayloadBuilder().setOptionalInt32(1234); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("payload.optional_nested_message") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected.getPayloadBuilder().setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678)); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected.getPayloadBuilder().addRepeatedInt32(4321); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("payload.repeated_nested_message") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected.getPayloadBuilder().addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765)); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("child.payload.optional_int32") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected.getChildBuilder().getPayloadBuilder().setOptionalInt32(1234); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("child.payload.optional_nested_message") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected - .getChildBuilder() - .getPayloadBuilder() - .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678)); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("child.payload.repeated_int32") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected.getChildBuilder().getPayloadBuilder().addRepeatedInt32(4321); - assertEquals(expected.build(), builder.build()); - - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("child.payload.repeated_nested_message") - .merge(source, builder, options); - expected = NestedTestAllTypes.newBuilder(); - expected - .getChildBuilder() - .getPayloadBuilder() - .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765)); - assertEquals(expected.build(), builder.build()); - - // Test merging all fields. - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree() - .addFieldPath("child") - .addFieldPath("payload") - .merge(source, builder, options); - assertEquals(source, builder.build()); - - // Test repeated options. - builder = NestedTestAllTypes.newBuilder(); - builder.getPayloadBuilder().addRepeatedInt32(1000); - new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options); - // Default behavior is to append repeated fields. - assertEquals(2, builder.getPayload().getRepeatedInt32Count()); - assertEquals(1000, builder.getPayload().getRepeatedInt32(0)); - assertEquals(4321, builder.getPayload().getRepeatedInt32(1)); - // Change to replace repeated fields. - options.setReplaceRepeatedFields(true); - new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options); - assertEquals(1, builder.getPayload().getRepeatedInt32Count()); - assertEquals(4321, builder.getPayload().getRepeatedInt32(0)); - - // Test message options. - builder = NestedTestAllTypes.newBuilder(); - builder.getPayloadBuilder().setOptionalInt32(1000); - builder.getPayloadBuilder().setOptionalUint32(2000); - new FieldMaskTree().addFieldPath("payload").merge(source, builder, options); - // Default behavior is to merge message fields. - assertEquals(1234, builder.getPayload().getOptionalInt32()); - assertEquals(2000, builder.getPayload().getOptionalUint32()); - - // Test merging unset message fields. - NestedTestAllTypes clearedSource = source.toBuilder().clearPayload().build(); - builder = NestedTestAllTypes.newBuilder(); - new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options); - assertEquals(false, builder.hasPayload()); - - // Change to replace message fields. - options.setReplaceMessageFields(true); - builder = NestedTestAllTypes.newBuilder(); - builder.getPayloadBuilder().setOptionalInt32(1000); - builder.getPayloadBuilder().setOptionalUint32(2000); - new FieldMaskTree().addFieldPath("payload").merge(source, builder, options); - assertEquals(1234, builder.getPayload().getOptionalInt32()); - assertEquals(0, builder.getPayload().getOptionalUint32()); - - // Test merging unset message fields. - builder = NestedTestAllTypes.newBuilder(); - builder.getPayloadBuilder().setOptionalInt32(1000); - builder.getPayloadBuilder().setOptionalUint32(2000); - new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options); - assertEquals(false, builder.hasPayload()); - - // Test merging unset primitive fields. - builder = source.toBuilder(); - builder.getPayloadBuilder().clearOptionalInt32(); - NestedTestAllTypes sourceWithPayloadInt32Unset = builder.build(); - builder = source.toBuilder(); - new FieldMaskTree() - .addFieldPath("payload.optional_int32") - .merge(sourceWithPayloadInt32Unset, builder, options); - assertEquals(true, builder.getPayload().hasOptionalInt32()); - assertEquals(0, builder.getPayload().getOptionalInt32()); - - // Change to clear unset primitive fields. - options.setReplacePrimitiveFields(true); - builder = source.toBuilder(); - new FieldMaskTree() - .addFieldPath("payload.optional_int32") - .merge(sourceWithPayloadInt32Unset, builder, options); - assertEquals(true, builder.hasPayload()); - assertEquals(false, builder.getPayload().hasOptionalInt32()); - } -} diff --git a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java deleted file mode 100644 index 1a99857053..0000000000 --- a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java +++ /dev/null @@ -1,213 +0,0 @@ -// 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.util; - -import com.google.protobuf.FieldMask; -import protobuf_unittest.UnittestProto.NestedTestAllTypes; -import protobuf_unittest.UnittestProto.TestAllTypes; - -import junit.framework.TestCase; - -/** Unit tests for {@link FieldMaskUtil}. */ -public class FieldMaskUtilTest extends TestCase { - public void testIsValid() throws Exception { - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_int32")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.nonexist")); - - assertTrue( - FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("payload"))); - assertFalse( - FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist"))); - assertFalse( - FieldMaskUtil.isValid( - NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist"))); - - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist")); - - assertTrue( - FieldMaskUtil.isValid( - NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload"))); - assertFalse( - FieldMaskUtil.isValid( - NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist"))); - - assertTrue( - FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message.bb")); - // Repeated fields cannot have sub-paths. - assertFalse( - FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message.bb")); - // Non-message fields cannot have sub-paths. - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32.bb")); - } - - public void testToString() throws Exception { - assertEquals("", FieldMaskUtil.toString(FieldMask.getDefaultInstance())); - FieldMask mask = FieldMask.newBuilder().addPaths("foo").build(); - assertEquals("foo", FieldMaskUtil.toString(mask)); - mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build(); - assertEquals("foo,bar", FieldMaskUtil.toString(mask)); - - // Empty field paths are ignored. - mask = - FieldMask.newBuilder() - .addPaths("") - .addPaths("foo") - .addPaths("") - .addPaths("bar") - .addPaths("") - .build(); - assertEquals("foo,bar", FieldMaskUtil.toString(mask)); - } - - public void testFromString() throws Exception { - FieldMask mask = FieldMaskUtil.fromString(""); - assertEquals(0, mask.getPathsCount()); - mask = FieldMaskUtil.fromString("foo"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - mask = FieldMaskUtil.fromString("foo,bar.baz"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar.baz", mask.getPaths(1)); - - // Empty field paths are ignore. - mask = FieldMaskUtil.fromString(",foo,,bar,"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar", mask.getPaths(1)); - - // Check whether the field paths are valid if a class parameter is provided. - mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, ",payload"); - - try { - mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, "payload,nonexist"); - fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - } - - public void testFromFieldNumbers() throws Exception { - FieldMask mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class); - assertEquals(0, mask.getPathsCount()); - mask = - FieldMaskUtil.fromFieldNumbers( - TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER); - assertEquals(1, mask.getPathsCount()); - assertEquals("optional_int32", mask.getPaths(0)); - mask = - FieldMaskUtil.fromFieldNumbers( - TestAllTypes.class, - TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, - TestAllTypes.OPTIONAL_INT64_FIELD_NUMBER); - assertEquals(2, mask.getPathsCount()); - assertEquals("optional_int32", mask.getPaths(0)); - assertEquals("optional_int64", mask.getPaths(1)); - - try { - int invalidFieldNumber = 1000; - mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class, invalidFieldNumber); - fail("Exception is expected."); - } catch (IllegalArgumentException expected) { - } - } - - public void testToJsonString() throws Exception { - FieldMask mask = FieldMask.getDefaultInstance(); - assertEquals("", FieldMaskUtil.toJsonString(mask)); - mask = FieldMask.newBuilder().addPaths("foo").build(); - assertEquals("foo", FieldMaskUtil.toJsonString(mask)); - mask = FieldMask.newBuilder().addPaths("foo.bar_baz").addPaths("").build(); - assertEquals("foo.barBaz", FieldMaskUtil.toJsonString(mask)); - mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar_baz").build(); - assertEquals("foo,barBaz", FieldMaskUtil.toJsonString(mask)); - } - - public void testFromJsonString() throws Exception { - FieldMask mask = FieldMaskUtil.fromJsonString(""); - assertEquals(0, mask.getPathsCount()); - mask = FieldMaskUtil.fromJsonString("foo"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - mask = FieldMaskUtil.fromJsonString("foo.barBaz"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo.bar_baz", mask.getPaths(0)); - mask = FieldMaskUtil.fromJsonString("foo,barBaz"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar_baz", mask.getPaths(1)); - } - - public void testUnion() throws Exception { - // Only test a simple case here and expect - // {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios. - FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); - FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); - FieldMask result = FieldMaskUtil.union(mask1, mask2); - assertEquals("bar,foo", FieldMaskUtil.toString(result)); - } - - public void testUnion_usingVarArgs() throws Exception { - FieldMask mask1 = FieldMaskUtil.fromString("foo"); - FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz"); - FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); - FieldMask mask4 = FieldMaskUtil.fromString("bar"); - FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4); - assertEquals("bar,foo", FieldMaskUtil.toString(result)); - } - - public void testIntersection() throws Exception { - // Only test a simple case here and expect - // {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios. - FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); - FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); - FieldMask result = FieldMaskUtil.intersection(mask1, mask2); - assertEquals("bar.baz,bar.quz,foo.bar", FieldMaskUtil.toString(result)); - } - - public void testMerge() throws Exception { - // Only test a simple case here and expect - // {@link FieldMaskTreeTest#testMerge} to cover all scenarios. - NestedTestAllTypes source = - NestedTestAllTypes.newBuilder() - .setPayload(TestAllTypes.newBuilder().setOptionalInt32(1234)) - .build(); - NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder(); - FieldMaskUtil.merge(FieldMaskUtil.fromString("payload"), source, builder); - assertEquals(1234, builder.getPayload().getOptionalInt32()); - } -} diff --git a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java deleted file mode 100644 index dafd9bb55a..0000000000 --- a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ /dev/null @@ -1,1414 +0,0 @@ -// 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.util; - -import com.google.protobuf.Any; -import com.google.protobuf.BoolValue; -import com.google.protobuf.ByteString; -import com.google.protobuf.BytesValue; -import com.google.protobuf.DoubleValue; -import com.google.protobuf.FloatValue; -import com.google.protobuf.Int32Value; -import com.google.protobuf.Int64Value; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.ListValue; -import com.google.protobuf.Message; -import com.google.protobuf.NullValue; -import com.google.protobuf.StringValue; -import com.google.protobuf.Struct; -import com.google.protobuf.UInt32Value; -import com.google.protobuf.UInt64Value; -import com.google.protobuf.Value; -import com.google.protobuf.util.JsonFormat.TypeRegistry; -import com.google.protobuf.util.JsonTestProto.TestAllTypes; -import com.google.protobuf.util.JsonTestProto.TestAllTypes.NestedEnum; -import com.google.protobuf.util.JsonTestProto.TestAllTypes.NestedMessage; -import com.google.protobuf.util.JsonTestProto.TestAny; -import com.google.protobuf.util.JsonTestProto.TestCustomJsonName; -import com.google.protobuf.util.JsonTestProto.TestDuration; -import com.google.protobuf.util.JsonTestProto.TestFieldMask; -import com.google.protobuf.util.JsonTestProto.TestMap; -import com.google.protobuf.util.JsonTestProto.TestOneof; -import com.google.protobuf.util.JsonTestProto.TestRecursive; -import com.google.protobuf.util.JsonTestProto.TestStruct; -import com.google.protobuf.util.JsonTestProto.TestTimestamp; -import com.google.protobuf.util.JsonTestProto.TestWrappers; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.HashMap; -import java.util.Map; -import junit.framework.TestCase; - -public class JsonFormatTest extends TestCase { - private void setAllFields(TestAllTypes.Builder builder) { - builder.setOptionalInt32(1234); - builder.setOptionalInt64(1234567890123456789L); - builder.setOptionalUint32(5678); - builder.setOptionalUint64(2345678901234567890L); - builder.setOptionalSint32(9012); - builder.setOptionalSint64(3456789012345678901L); - builder.setOptionalFixed32(3456); - builder.setOptionalFixed64(4567890123456789012L); - builder.setOptionalSfixed32(7890); - builder.setOptionalSfixed64(5678901234567890123L); - builder.setOptionalFloat(1.5f); - builder.setOptionalDouble(1.25); - builder.setOptionalBool(true); - builder.setOptionalString("Hello world!"); - builder.setOptionalBytes(ByteString.copyFrom(new byte[] {0, 1, 2})); - builder.setOptionalNestedEnum(NestedEnum.BAR); - builder.getOptionalNestedMessageBuilder().setValue(100); - - builder.addRepeatedInt32(1234); - builder.addRepeatedInt64(1234567890123456789L); - builder.addRepeatedUint32(5678); - builder.addRepeatedUint64(2345678901234567890L); - builder.addRepeatedSint32(9012); - builder.addRepeatedSint64(3456789012345678901L); - builder.addRepeatedFixed32(3456); - builder.addRepeatedFixed64(4567890123456789012L); - builder.addRepeatedSfixed32(7890); - builder.addRepeatedSfixed64(5678901234567890123L); - builder.addRepeatedFloat(1.5f); - builder.addRepeatedDouble(1.25); - builder.addRepeatedBool(true); - builder.addRepeatedString("Hello world!"); - builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {0, 1, 2})); - builder.addRepeatedNestedEnum(NestedEnum.BAR); - builder.addRepeatedNestedMessageBuilder().setValue(100); - - builder.addRepeatedInt32(234); - builder.addRepeatedInt64(234567890123456789L); - builder.addRepeatedUint32(678); - builder.addRepeatedUint64(345678901234567890L); - builder.addRepeatedSint32(012); - builder.addRepeatedSint64(456789012345678901L); - builder.addRepeatedFixed32(456); - builder.addRepeatedFixed64(567890123456789012L); - builder.addRepeatedSfixed32(890); - builder.addRepeatedSfixed64(678901234567890123L); - builder.addRepeatedFloat(11.5f); - builder.addRepeatedDouble(11.25); - builder.addRepeatedBool(true); - builder.addRepeatedString("ello world!"); - builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {1, 2})); - builder.addRepeatedNestedEnum(NestedEnum.BAZ); - builder.addRepeatedNestedMessageBuilder().setValue(200); - } - - private void assertRoundTripEquals(Message message) throws Exception { - assertRoundTripEquals(message, TypeRegistry.getEmptyTypeRegistry()); - } - - private void assertRoundTripEquals(Message message, TypeRegistry registry) throws Exception { - JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(registry); - Message.Builder builder = message.newBuilderForType(); - parser.merge(printer.print(message), builder); - Message parsedMessage = builder.build(); - assertEquals(message.toString(), parsedMessage.toString()); - } - - private String toJsonString(Message message) throws IOException { - return JsonFormat.printer().print(message); - } - private String toCompactJsonString(Message message) throws IOException { - return JsonFormat.printer().omittingInsignificantWhitespace().print(message); - } - - private void mergeFromJson(String json, Message.Builder builder) throws IOException { - JsonFormat.parser().merge(json, builder); - } - - public void testAllFields() throws Exception { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - setAllFields(builder); - TestAllTypes message = builder.build(); - - assertEquals( - "{\n" - + " \"optionalInt32\": 1234,\n" - + " \"optionalInt64\": \"1234567890123456789\",\n" - + " \"optionalUint32\": 5678,\n" - + " \"optionalUint64\": \"2345678901234567890\",\n" - + " \"optionalSint32\": 9012,\n" - + " \"optionalSint64\": \"3456789012345678901\",\n" - + " \"optionalFixed32\": 3456,\n" - + " \"optionalFixed64\": \"4567890123456789012\",\n" - + " \"optionalSfixed32\": 7890,\n" - + " \"optionalSfixed64\": \"5678901234567890123\",\n" - + " \"optionalFloat\": 1.5,\n" - + " \"optionalDouble\": 1.25,\n" - + " \"optionalBool\": true,\n" - + " \"optionalString\": \"Hello world!\",\n" - + " \"optionalBytes\": \"AAEC\",\n" - + " \"optionalNestedMessage\": {\n" - + " \"value\": 100\n" - + " },\n" - + " \"optionalNestedEnum\": \"BAR\",\n" - + " \"repeatedInt32\": [1234, 234],\n" - + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n" - + " \"repeatedUint32\": [5678, 678],\n" - + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n" - + " \"repeatedSint32\": [9012, 10],\n" - + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n" - + " \"repeatedFixed32\": [3456, 456],\n" - + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n" - + " \"repeatedSfixed32\": [7890, 890],\n" - + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n" - + " \"repeatedFloat\": [1.5, 11.5],\n" - + " \"repeatedDouble\": [1.25, 11.25],\n" - + " \"repeatedBool\": [true, true],\n" - + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n" - + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n" - + " \"repeatedNestedMessage\": [{\n" - + " \"value\": 100\n" - + " }, {\n" - + " \"value\": 200\n" - + " }],\n" - + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n" - + "}", - toJsonString(message)); - - assertRoundTripEquals(message); - } - - public void testUnknownEnumValues() throws Exception { - TestAllTypes message = - TestAllTypes.newBuilder() - .setOptionalNestedEnumValue(12345) - .addRepeatedNestedEnumValue(12345) - .addRepeatedNestedEnumValue(0) - .build(); - assertEquals( - "{\n" - + " \"optionalNestedEnum\": 12345,\n" - + " \"repeatedNestedEnum\": [12345, \"FOO\"]\n" - + "}", - toJsonString(message)); - assertRoundTripEquals(message); - - TestMap.Builder mapBuilder = TestMap.newBuilder(); - mapBuilder.putInt32ToEnumMapValue(1, 0); - Map<Integer, Integer> mapWithInvalidValues = new HashMap<Integer, Integer>(); - mapWithInvalidValues.put(2, 12345); - mapBuilder.putAllInt32ToEnumMapValue(mapWithInvalidValues); - TestMap mapMessage = mapBuilder.build(); - assertEquals( - "{\n" - + " \"int32ToEnumMap\": {\n" - + " \"1\": \"FOO\",\n" - + " \"2\": 12345\n" - + " }\n" - + "}", - toJsonString(mapMessage)); - assertRoundTripEquals(mapMessage); - } - - public void testSpecialFloatValues() throws Exception { - TestAllTypes message = - TestAllTypes.newBuilder() - .addRepeatedFloat(Float.NaN) - .addRepeatedFloat(Float.POSITIVE_INFINITY) - .addRepeatedFloat(Float.NEGATIVE_INFINITY) - .addRepeatedDouble(Double.NaN) - .addRepeatedDouble(Double.POSITIVE_INFINITY) - .addRepeatedDouble(Double.NEGATIVE_INFINITY) - .build(); - assertEquals( - "{\n" - + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n" - + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n" - + "}", - toJsonString(message)); - - assertRoundTripEquals(message); - } - - public void testParserAcceptStringForNumbericField() throws Exception { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"optionalInt32\": \"1234\",\n" - + " \"optionalUint32\": \"5678\",\n" - + " \"optionalSint32\": \"9012\",\n" - + " \"optionalFixed32\": \"3456\",\n" - + " \"optionalSfixed32\": \"7890\",\n" - + " \"optionalFloat\": \"1.5\",\n" - + " \"optionalDouble\": \"1.25\",\n" - + " \"optionalBool\": \"true\"\n" - + "}", - builder); - TestAllTypes message = builder.build(); - assertEquals(1234, message.getOptionalInt32()); - assertEquals(5678, message.getOptionalUint32()); - assertEquals(9012, message.getOptionalSint32()); - assertEquals(3456, message.getOptionalFixed32()); - assertEquals(7890, message.getOptionalSfixed32()); - assertEquals(1.5f, message.getOptionalFloat()); - assertEquals(1.25, message.getOptionalDouble()); - assertEquals(true, message.getOptionalBool()); - } - - public void testParserAcceptFloatingPointValueForIntegerField() throws Exception { - // Test that numeric values like "1.000", "1e5" will also be accepted. - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"repeatedInt32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n" - + " \"repeatedUint32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n" - + " \"repeatedInt64\": [1.000, 1e5, \"1.000\", \"1e5\"],\n" - + " \"repeatedUint64\": [1.000, 1e5, \"1.000\", \"1e5\"]\n" - + "}", - builder); - int[] expectedValues = new int[] {1, 100000, 1, 100000}; - assertEquals(4, builder.getRepeatedInt32Count()); - assertEquals(4, builder.getRepeatedUint32Count()); - assertEquals(4, builder.getRepeatedInt64Count()); - assertEquals(4, builder.getRepeatedUint64Count()); - for (int i = 0; i < 4; ++i) { - assertEquals(expectedValues[i], builder.getRepeatedInt32(i)); - assertEquals(expectedValues[i], builder.getRepeatedUint32(i)); - assertEquals(expectedValues[i], builder.getRepeatedInt64(i)); - assertEquals(expectedValues[i], builder.getRepeatedUint64(i)); - } - - // Non-integers will still be rejected. - assertRejects("optionalInt32", "1.5"); - assertRejects("optionalUint32", "1.5"); - assertRejects("optionalInt64", "1.5"); - assertRejects("optionalUint64", "1.5"); - } - - private void assertRejects(String name, String value) { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - try { - // Numeric form is rejected. - mergeFromJson("{\"" + name + "\":" + value + "}", builder); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - try { - // String form is also rejected. - mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - } - - private void assertAccepts(String name, String value) throws IOException { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - // Both numeric form and string form are accepted. - mergeFromJson("{\"" + name + "\":" + value + "}", builder); - builder.clear(); - mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder); - } - - public void testParserRejectOutOfRangeNumericValues() throws Exception { - assertAccepts("optionalInt32", String.valueOf(Integer.MAX_VALUE)); - assertAccepts("optionalInt32", String.valueOf(Integer.MIN_VALUE)); - assertRejects("optionalInt32", String.valueOf(Integer.MAX_VALUE + 1L)); - assertRejects("optionalInt32", String.valueOf(Integer.MIN_VALUE - 1L)); - - assertAccepts("optionalUint32", String.valueOf(Integer.MAX_VALUE + 1L)); - assertRejects("optionalUint32", "123456789012345"); - assertRejects("optionalUint32", "-1"); - - BigInteger one = new BigInteger("1"); - BigInteger maxLong = new BigInteger(String.valueOf(Long.MAX_VALUE)); - BigInteger minLong = new BigInteger(String.valueOf(Long.MIN_VALUE)); - assertAccepts("optionalInt64", maxLong.toString()); - assertAccepts("optionalInt64", minLong.toString()); - assertRejects("optionalInt64", maxLong.add(one).toString()); - assertRejects("optionalInt64", minLong.subtract(one).toString()); - - assertAccepts("optionalUint64", maxLong.add(one).toString()); - assertRejects("optionalUint64", "1234567890123456789012345"); - assertRejects("optionalUint64", "-1"); - - assertAccepts("optionalBool", "true"); - assertRejects("optionalBool", "1"); - assertRejects("optionalBool", "0"); - - assertAccepts("optionalFloat", String.valueOf(Float.MAX_VALUE)); - assertAccepts("optionalFloat", String.valueOf(-Float.MAX_VALUE)); - assertRejects("optionalFloat", String.valueOf(Double.MAX_VALUE)); - assertRejects("optionalFloat", String.valueOf(-Double.MAX_VALUE)); - - BigDecimal moreThanOne = new BigDecimal("1.000001"); - BigDecimal maxDouble = new BigDecimal(Double.MAX_VALUE); - BigDecimal minDouble = new BigDecimal(-Double.MAX_VALUE); - assertAccepts("optionalDouble", maxDouble.toString()); - assertAccepts("optionalDouble", minDouble.toString()); - assertRejects("optionalDouble", maxDouble.multiply(moreThanOne).toString()); - assertRejects("optionalDouble", minDouble.multiply(moreThanOne).toString()); - } - - public void testParserAcceptNull() throws Exception { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"optionalInt32\": null,\n" - + " \"optionalInt64\": null,\n" - + " \"optionalUint32\": null,\n" - + " \"optionalUint64\": null,\n" - + " \"optionalSint32\": null,\n" - + " \"optionalSint64\": null,\n" - + " \"optionalFixed32\": null,\n" - + " \"optionalFixed64\": null,\n" - + " \"optionalSfixed32\": null,\n" - + " \"optionalSfixed64\": null,\n" - + " \"optionalFloat\": null,\n" - + " \"optionalDouble\": null,\n" - + " \"optionalBool\": null,\n" - + " \"optionalString\": null,\n" - + " \"optionalBytes\": null,\n" - + " \"optionalNestedMessage\": null,\n" - + " \"optionalNestedEnum\": null,\n" - + " \"repeatedInt32\": null,\n" - + " \"repeatedInt64\": null,\n" - + " \"repeatedUint32\": null,\n" - + " \"repeatedUint64\": null,\n" - + " \"repeatedSint32\": null,\n" - + " \"repeatedSint64\": null,\n" - + " \"repeatedFixed32\": null,\n" - + " \"repeatedFixed64\": null,\n" - + " \"repeatedSfixed32\": null,\n" - + " \"repeatedSfixed64\": null,\n" - + " \"repeatedFloat\": null,\n" - + " \"repeatedDouble\": null,\n" - + " \"repeatedBool\": null,\n" - + " \"repeatedString\": null,\n" - + " \"repeatedBytes\": null,\n" - + " \"repeatedNestedMessage\": null,\n" - + " \"repeatedNestedEnum\": null\n" - + "}", - builder); - TestAllTypes message = builder.build(); - assertEquals(TestAllTypes.getDefaultInstance(), message); - - // Repeated field elements cannot be null. - try { - builder = TestAllTypes.newBuilder(); - mergeFromJson("{\n" + " \"repeatedInt32\": [null, null],\n" + "}", builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - - try { - builder = TestAllTypes.newBuilder(); - mergeFromJson("{\n" + " \"repeatedNestedMessage\": [null, null],\n" + "}", builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - } - - public void testNullInOneof() throws Exception { - TestOneof.Builder builder = TestOneof.newBuilder(); - mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", builder); - TestOneof message = builder.build(); - assertEquals(TestOneof.OneofFieldCase.ONEOF_NULL_VALUE, message.getOneofFieldCase()); - assertEquals(NullValue.NULL_VALUE, message.getOneofNullValue()); - } - - public void testParserRejectDuplicatedFields() throws Exception { - // TODO(xiaofeng): The parser we are currently using (GSON) will accept and keep the last - // one if multiple entries have the same name. This is not the desired behavior but it can - // only be fixed by using our own parser. Here we only test the cases where the names are - // different but still referring to the same field. - - // Duplicated optional fields. - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"optionalNestedMessage\": {},\n" - + " \"optional_nested_message\": {}\n" - + "}", - builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - - // Duplicated repeated fields. - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"repeatedNestedMessage\": [null, null],\n" - + " \"repeated_nested_message\": [null, null]\n" - + "}", - builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - - // Duplicated oneof fields. - try { - TestOneof.Builder builder = TestOneof.newBuilder(); - mergeFromJson("{\n" + " \"oneofInt32\": 1,\n" + " \"oneof_int32\": 2\n" + "}", builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - } - - public void testMapFields() throws Exception { - TestMap.Builder builder = TestMap.newBuilder(); - builder.putInt32ToInt32Map(1, 10); - builder.putInt64ToInt32Map(1234567890123456789L, 10); - builder.putUint32ToInt32Map(2, 20); - builder.putUint64ToInt32Map(2234567890123456789L, 20); - builder.putSint32ToInt32Map(3, 30); - builder.putSint64ToInt32Map(3234567890123456789L, 30); - builder.putFixed32ToInt32Map(4, 40); - builder.putFixed64ToInt32Map(4234567890123456789L, 40); - builder.putSfixed32ToInt32Map(5, 50); - builder.putSfixed64ToInt32Map(5234567890123456789L, 50); - builder.putBoolToInt32Map(false, 6); - builder.putStringToInt32Map("Hello", 10); - - builder.putInt32ToInt64Map(1, 1234567890123456789L); - builder.putInt32ToUint32Map(2, 20); - builder.putInt32ToUint64Map(2, 2234567890123456789L); - builder.putInt32ToSint32Map(3, 30); - builder.putInt32ToSint64Map(3, 3234567890123456789L); - builder.putInt32ToFixed32Map(4, 40); - builder.putInt32ToFixed64Map(4, 4234567890123456789L); - builder.putInt32ToSfixed32Map(5, 50); - builder.putInt32ToSfixed64Map(5, 5234567890123456789L); - builder.putInt32ToFloatMap(6, 1.5f); - builder.putInt32ToDoubleMap(6, 1.25); - builder.putInt32ToBoolMap(7, false); - builder.putInt32ToStringMap(7, "World"); - builder.putInt32ToBytesMap(8, ByteString.copyFrom(new byte[] {1, 2, 3})); - builder.putInt32ToMessageMap(8, NestedMessage.newBuilder().setValue(1234).build()); - builder.putInt32ToEnumMap(9, NestedEnum.BAR); - TestMap message = builder.build(); - - assertEquals( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " \"1\": 10\n" - + " },\n" - + " \"int64ToInt32Map\": {\n" - + " \"1234567890123456789\": 10\n" - + " },\n" - + " \"uint32ToInt32Map\": {\n" - + " \"2\": 20\n" - + " },\n" - + " \"uint64ToInt32Map\": {\n" - + " \"2234567890123456789\": 20\n" - + " },\n" - + " \"sint32ToInt32Map\": {\n" - + " \"3\": 30\n" - + " },\n" - + " \"sint64ToInt32Map\": {\n" - + " \"3234567890123456789\": 30\n" - + " },\n" - + " \"fixed32ToInt32Map\": {\n" - + " \"4\": 40\n" - + " },\n" - + " \"fixed64ToInt32Map\": {\n" - + " \"4234567890123456789\": 40\n" - + " },\n" - + " \"sfixed32ToInt32Map\": {\n" - + " \"5\": 50\n" - + " },\n" - + " \"sfixed64ToInt32Map\": {\n" - + " \"5234567890123456789\": 50\n" - + " },\n" - + " \"boolToInt32Map\": {\n" - + " \"false\": 6\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " \"Hello\": 10\n" - + " },\n" - + " \"int32ToInt64Map\": {\n" - + " \"1\": \"1234567890123456789\"\n" - + " },\n" - + " \"int32ToUint32Map\": {\n" - + " \"2\": 20\n" - + " },\n" - + " \"int32ToUint64Map\": {\n" - + " \"2\": \"2234567890123456789\"\n" - + " },\n" - + " \"int32ToSint32Map\": {\n" - + " \"3\": 30\n" - + " },\n" - + " \"int32ToSint64Map\": {\n" - + " \"3\": \"3234567890123456789\"\n" - + " },\n" - + " \"int32ToFixed32Map\": {\n" - + " \"4\": 40\n" - + " },\n" - + " \"int32ToFixed64Map\": {\n" - + " \"4\": \"4234567890123456789\"\n" - + " },\n" - + " \"int32ToSfixed32Map\": {\n" - + " \"5\": 50\n" - + " },\n" - + " \"int32ToSfixed64Map\": {\n" - + " \"5\": \"5234567890123456789\"\n" - + " },\n" - + " \"int32ToFloatMap\": {\n" - + " \"6\": 1.5\n" - + " },\n" - + " \"int32ToDoubleMap\": {\n" - + " \"6\": 1.25\n" - + " },\n" - + " \"int32ToBoolMap\": {\n" - + " \"7\": false\n" - + " },\n" - + " \"int32ToStringMap\": {\n" - + " \"7\": \"World\"\n" - + " },\n" - + " \"int32ToBytesMap\": {\n" - + " \"8\": \"AQID\"\n" - + " },\n" - + " \"int32ToMessageMap\": {\n" - + " \"8\": {\n" - + " \"value\": 1234\n" - + " }\n" - + " },\n" - + " \"int32ToEnumMap\": {\n" - + " \"9\": \"BAR\"\n" - + " }\n" - + "}", - toJsonString(message)); - assertRoundTripEquals(message); - - // Test multiple entries. - builder = TestMap.newBuilder(); - builder.putInt32ToInt32Map(1, 2); - builder.putInt32ToInt32Map(3, 4); - message = builder.build(); - - assertEquals( - "{\n" + " \"int32ToInt32Map\": {\n" + " \"1\": 2,\n" + " \"3\": 4\n" + " }\n" + "}", - toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testMapNullValueIsRejected() throws Exception { - try { - TestMap.Builder builder = TestMap.newBuilder(); - mergeFromJson( - "{\n" - + " \"int32ToInt32Map\": {null: 1},\n" - + " \"int32ToMessageMap\": {null: 2}\n" - + "}", - builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - - try { - TestMap.Builder builder = TestMap.newBuilder(); - mergeFromJson( - "{\n" - + " \"int32ToInt32Map\": {\"1\": null},\n" - + " \"int32ToMessageMap\": {\"2\": null}\n" - + "}", - builder); - fail(); - } catch (InvalidProtocolBufferException e) { - // Exception expected. - } - } - - public void testParserAcceptNonQuotedObjectKey() throws Exception { - TestMap.Builder builder = TestMap.newBuilder(); - mergeFromJson( - "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder); - TestMap message = builder.build(); - assertEquals(2, message.getInt32ToInt32Map().get(1).intValue()); - assertEquals(3, message.getStringToInt32Map().get("hello").intValue()); - } - - public void testWrappers() throws Exception { - TestWrappers.Builder builder = TestWrappers.newBuilder(); - builder.getBoolValueBuilder().setValue(false); - builder.getInt32ValueBuilder().setValue(0); - builder.getInt64ValueBuilder().setValue(0); - builder.getUint32ValueBuilder().setValue(0); - builder.getUint64ValueBuilder().setValue(0); - builder.getFloatValueBuilder().setValue(0.0f); - builder.getDoubleValueBuilder().setValue(0.0); - builder.getStringValueBuilder().setValue(""); - builder.getBytesValueBuilder().setValue(ByteString.EMPTY); - TestWrappers message = builder.build(); - - assertEquals( - "{\n" - + " \"int32Value\": 0,\n" - + " \"uint32Value\": 0,\n" - + " \"int64Value\": \"0\",\n" - + " \"uint64Value\": \"0\",\n" - + " \"floatValue\": 0.0,\n" - + " \"doubleValue\": 0.0,\n" - + " \"boolValue\": false,\n" - + " \"stringValue\": \"\",\n" - + " \"bytesValue\": \"\"\n" - + "}", - toJsonString(message)); - assertRoundTripEquals(message); - - builder = TestWrappers.newBuilder(); - builder.getBoolValueBuilder().setValue(true); - builder.getInt32ValueBuilder().setValue(1); - builder.getInt64ValueBuilder().setValue(2); - builder.getUint32ValueBuilder().setValue(3); - builder.getUint64ValueBuilder().setValue(4); - builder.getFloatValueBuilder().setValue(5.0f); - builder.getDoubleValueBuilder().setValue(6.0); - builder.getStringValueBuilder().setValue("7"); - builder.getBytesValueBuilder().setValue(ByteString.copyFrom(new byte[] {8})); - message = builder.build(); - - assertEquals( - "{\n" - + " \"int32Value\": 1,\n" - + " \"uint32Value\": 3,\n" - + " \"int64Value\": \"2\",\n" - + " \"uint64Value\": \"4\",\n" - + " \"floatValue\": 5.0,\n" - + " \"doubleValue\": 6.0,\n" - + " \"boolValue\": true,\n" - + " \"stringValue\": \"7\",\n" - + " \"bytesValue\": \"CA==\"\n" - + "}", - toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testTimestamp() throws Exception { - TestTimestamp message = - TestTimestamp.newBuilder() - .setTimestampValue(Timestamps.parse("1970-01-01T00:00:00Z")) - .build(); - - assertEquals( - "{\n" + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n" + "}", toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testDuration() throws Exception { - TestDuration message = - TestDuration.newBuilder().setDurationValue(Durations.parse("12345s")).build(); - - assertEquals("{\n" + " \"durationValue\": \"12345s\"\n" + "}", toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testFieldMask() throws Exception { - TestFieldMask message = - TestFieldMask.newBuilder() - .setFieldMaskValue(FieldMaskUtil.fromString("foo.bar,baz,foo_bar.baz")) - .build(); - - assertEquals( - "{\n" + " \"fieldMaskValue\": \"foo.bar,baz,fooBar.baz\"\n" + "}", toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testStruct() throws Exception { - // Build a struct with all possible values. - TestStruct.Builder builder = TestStruct.newBuilder(); - Struct.Builder structBuilder = builder.getStructValueBuilder(); - structBuilder.putFields("null_value", Value.newBuilder().setNullValueValue(0).build()); - structBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1.25).build()); - structBuilder.putFields("string_value", Value.newBuilder().setStringValue("hello").build()); - Struct.Builder subStructBuilder = Struct.newBuilder(); - subStructBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1234).build()); - structBuilder.putFields( - "struct_value", Value.newBuilder().setStructValue(subStructBuilder.build()).build()); - ListValue.Builder listBuilder = ListValue.newBuilder(); - listBuilder.addValues(Value.newBuilder().setNumberValue(1.125).build()); - listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build()); - structBuilder.putFields( - "list_value", Value.newBuilder().setListValue(listBuilder.build()).build()); - TestStruct message = builder.build(); - - assertEquals( - "{\n" - + " \"structValue\": {\n" - + " \"null_value\": null,\n" - + " \"number_value\": 1.25,\n" - + " \"string_value\": \"hello\",\n" - + " \"struct_value\": {\n" - + " \"number_value\": 1234.0\n" - + " },\n" - + " \"list_value\": [1.125, null]\n" - + " }\n" - + "}", - toJsonString(message)); - assertRoundTripEquals(message); - - builder = TestStruct.newBuilder(); - builder.setValue(Value.newBuilder().setNullValueValue(0).build()); - message = builder.build(); - assertEquals("{\n" + " \"value\": null\n" + "}", toJsonString(message)); - assertRoundTripEquals(message); - - builder = TestStruct.newBuilder(); - listBuilder = builder.getListValueBuilder(); - listBuilder.addValues(Value.newBuilder().setNumberValue(31831.125).build()); - listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build()); - message = builder.build(); - assertEquals("{\n" + " \"listValue\": [31831.125, null]\n" + "}", toJsonString(message)); - assertRoundTripEquals(message); - } - - public void testAnyFields() throws Exception { - TestAllTypes content = TestAllTypes.newBuilder().setOptionalInt32(1234).build(); - TestAny message = TestAny.newBuilder().setAnyValue(Any.pack(content)).build(); - - // A TypeRegistry must be provided in order to convert Any types. - try { - toJsonString(message); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - - JsonFormat.TypeRegistry registry = - JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); - JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - - assertEquals( - "{\n" - + " \"anyValue\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(message)); - assertRoundTripEquals(message, registry); - - TestAny messageWithDefaultAnyValue = - TestAny.newBuilder().setAnyValue(Any.getDefaultInstance()).build(); - assertEquals( - "{\n" - + " \"anyValue\": {}\n" - + "}", - printer.print(messageWithDefaultAnyValue)); - assertRoundTripEquals(messageWithDefaultAnyValue, registry); - - // Well-known types have a special formatting when embedded in Any. - // - // 1. Any in Any. - Any anyMessage = Any.pack(Any.pack(content)); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 2. Wrappers in Any. - anyMessage = Any.pack(Int32Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" - + " \"value\": 12345\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(UInt32Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n" - + " \"value\": 12345\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(Int64Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" - + " \"value\": \"12345\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(UInt64Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n" - + " \"value\": \"12345\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(FloatValue.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n" - + " \"value\": 12345.0\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(DoubleValue.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n" - + " \"value\": 12345.0\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(BoolValue.newBuilder().setValue(true).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n" - + " \"value\": true\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(StringValue.newBuilder().setValue("Hello").build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n" - + " \"value\": \"Hello\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - anyMessage = - Any.pack(BytesValue.newBuilder().setValue(ByteString.copyFrom(new byte[] {1, 2})).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n" - + " \"value\": \"AQI=\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 3. Timestamp in Any. - anyMessage = Any.pack(Timestamps.parse("1969-12-31T23:59:59Z")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" - + " \"value\": \"1969-12-31T23:59:59Z\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 4. Duration in Any - anyMessage = Any.pack(Durations.parse("12345.10s")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" - + " \"value\": \"12345.100s\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 5. FieldMask in Any - anyMessage = Any.pack(FieldMaskUtil.fromString("foo.bar,baz")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" - + " \"value\": \"foo.bar,baz\"\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 6. Struct in Any - Struct.Builder structBuilder = Struct.newBuilder(); - structBuilder.putFields("number", Value.newBuilder().setNumberValue(1.125).build()); - anyMessage = Any.pack(structBuilder.build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" - + " \"value\": {\n" - + " \"number\": 1.125\n" - + " }\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 7. Value (number type) in Any - Value.Builder valueBuilder = Value.newBuilder(); - valueBuilder.setNumberValue(1); - anyMessage = Any.pack(valueBuilder.build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.0\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - - // 8. Value (null type) in Any - anyMessage = Any.pack(Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": null\n" - + "}", - printer.print(anyMessage)); - assertRoundTripEquals(anyMessage, registry); - } - - public void testAnyInMaps() throws Exception { - JsonFormat.TypeRegistry registry = - JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); - JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - - TestAny.Builder testAny = TestAny.newBuilder(); - testAny.putAnyMap("int32_wrapper", Any.pack(Int32Value.newBuilder().setValue(123).build())); - testAny.putAnyMap("int64_wrapper", Any.pack(Int64Value.newBuilder().setValue(456).build())); - testAny.putAnyMap("timestamp", Any.pack(Timestamps.parse("1969-12-31T23:59:59Z"))); - testAny.putAnyMap("duration", Any.pack(Durations.parse("12345.1s"))); - testAny.putAnyMap("field_mask", Any.pack(FieldMaskUtil.fromString("foo.bar,baz"))); - Value numberValue = Value.newBuilder().setNumberValue(1.125).build(); - Struct.Builder struct = Struct.newBuilder(); - struct.putFields("number", numberValue); - testAny.putAnyMap("struct", Any.pack(struct.build())); - Value nullValue = Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build(); - testAny.putAnyMap( - "list_value", - Any.pack(ListValue.newBuilder().addValues(numberValue).addValues(nullValue).build())); - testAny.putAnyMap("number_value", Any.pack(numberValue)); - testAny.putAnyMap("any_value_number", Any.pack(Any.pack(numberValue))); - testAny.putAnyMap("any_value_default", Any.pack(Any.getDefaultInstance())); - testAny.putAnyMap("default", Any.getDefaultInstance()); - - assertEquals( - "{\n" - + " \"anyMap\": {\n" - + " \"int32_wrapper\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" - + " \"value\": 123\n" - + " },\n" - + " \"int64_wrapper\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" - + " \"value\": \"456\"\n" - + " },\n" - + " \"timestamp\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" - + " \"value\": \"1969-12-31T23:59:59Z\"\n" - + " },\n" - + " \"duration\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" - + " \"value\": \"12345.100s\"\n" - + " },\n" - + " \"field_mask\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" - + " \"value\": \"foo.bar,baz\"\n" - + " },\n" - + " \"struct\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" - + " \"value\": {\n" - + " \"number\": 1.125\n" - + " }\n" - + " },\n" - + " \"list_value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.ListValue\",\n" - + " \"value\": [1.125, null]\n" - + " },\n" - + " \"number_value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.125\n" - + " },\n" - + " \"any_value_number\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.125\n" - + " }\n" - + " },\n" - + " \"any_value_default\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {}\n" - + " },\n" - + " \"default\": {}\n" - + " }\n" - + "}", - printer.print(testAny.build())); - assertRoundTripEquals(testAny.build(), registry); - } - - public void testParserMissingTypeUrl() throws Exception { - try { - Any.Builder builder = Any.newBuilder(); - mergeFromJson("{\n" + " \"optionalInt32\": 1234\n" + "}", builder); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - } - - public void testParserUnexpectedTypeUrl() throws Exception { - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson( - "{\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 12345\n" - + "}", - builder); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - } - - public void testParserRejectTrailingComma() throws Exception { - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson("{\n" + " \"optionalInt32\": 12345,\n" + "}", builder); - fail("Exception is expected."); - } catch (IOException e) { - // Expected. - } - - // TODO(xiaofeng): GSON allows trailing comma in arrays even after I set - // the JsonReader to non-lenient mode. If we want to enforce strict JSON - // compliance, we might want to switch to a different JSON parser or - // implement one by ourselves. - // try { - // TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - // JsonFormat.merge( - // "{\n" - // + " \"repeatedInt32\": [12345,]\n" - // + "}", builder); - // fail("Exception is expected."); - // } catch (IOException e) { - // // Expected. - // } - } - - public void testParserRejectInvalidBase64() throws Exception { - assertRejects("optionalBytes", "!@#$"); - } - - public void testParserAcceptBase64Variants() throws Exception { - assertAccepts("optionalBytes", "AQI"); - } - - public void testParserRejectInvalidEnumValue() throws Exception { - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - mergeFromJson("{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}", builder); - fail("Exception is expected."); - } catch (InvalidProtocolBufferException e) { - // Expected. - } - } - - public void testParserUnknownFields() throws Exception { - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; - JsonFormat.parser().merge(json, builder); - fail("Exception is expected."); - } catch (InvalidProtocolBufferException e) { - // Expected. - } - } - - public void testParserIgnoringUnknownFields() throws Exception { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; - JsonFormat.parser().ignoringUnknownFields().merge(json, builder); - } - - public void testCustomJsonName() throws Exception { - TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build(); - assertEquals("{\n" + " \"@value\": 12345\n" + "}", JsonFormat.printer().print(message)); - assertRoundTripEquals(message); - } - - public void testDefaultGsonDoesNotHtmlEscape() throws Exception { - TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("=").build(); - assertEquals( - "{\n" + " \"optionalString\": \"=\"" + "\n}", JsonFormat.printer().print(message)); - } - - public void testIncludingDefaultValueFields() throws Exception { - TestAllTypes message = TestAllTypes.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(message)); - assertEquals( - "{\n" - + " \"optionalInt32\": 0,\n" - + " \"optionalInt64\": \"0\",\n" - + " \"optionalUint32\": 0,\n" - + " \"optionalUint64\": \"0\",\n" - + " \"optionalSint32\": 0,\n" - + " \"optionalSint64\": \"0\",\n" - + " \"optionalFixed32\": 0,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"optionalSfixed32\": 0,\n" - + " \"optionalSfixed64\": \"0\",\n" - + " \"optionalFloat\": 0.0,\n" - + " \"optionalDouble\": 0.0,\n" - + " \"optionalBool\": false,\n" - + " \"optionalString\": \"\",\n" - + " \"optionalBytes\": \"\",\n" - + " \"optionalNestedEnum\": \"FOO\",\n" - + " \"repeatedInt32\": [],\n" - + " \"repeatedInt64\": [],\n" - + " \"repeatedUint32\": [],\n" - + " \"repeatedUint64\": [],\n" - + " \"repeatedSint32\": [],\n" - + " \"repeatedSint64\": [],\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": [],\n" - + " \"repeatedSfixed32\": [],\n" - + " \"repeatedSfixed64\": [],\n" - + " \"repeatedFloat\": [],\n" - + " \"repeatedDouble\": [],\n" - + " \"repeatedBool\": [],\n" - + " \"repeatedString\": [],\n" - + " \"repeatedBytes\": [],\n" - + " \"repeatedNestedMessage\": [],\n" - + " \"repeatedNestedEnum\": []\n" - + "}", - JsonFormat.printer().includingDefaultValueFields().print(message)); - - TestMap mapMessage = TestMap.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(mapMessage)); - assertEquals( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " },\n" - + " \"int64ToInt32Map\": {\n" - + " },\n" - + " \"uint32ToInt32Map\": {\n" - + " },\n" - + " \"uint64ToInt32Map\": {\n" - + " },\n" - + " \"sint32ToInt32Map\": {\n" - + " },\n" - + " \"sint64ToInt32Map\": {\n" - + " },\n" - + " \"fixed32ToInt32Map\": {\n" - + " },\n" - + " \"fixed64ToInt32Map\": {\n" - + " },\n" - + " \"sfixed32ToInt32Map\": {\n" - + " },\n" - + " \"sfixed64ToInt32Map\": {\n" - + " },\n" - + " \"boolToInt32Map\": {\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " },\n" - + " \"int32ToInt64Map\": {\n" - + " },\n" - + " \"int32ToUint32Map\": {\n" - + " },\n" - + " \"int32ToUint64Map\": {\n" - + " },\n" - + " \"int32ToSint32Map\": {\n" - + " },\n" - + " \"int32ToSint64Map\": {\n" - + " },\n" - + " \"int32ToFixed32Map\": {\n" - + " },\n" - + " \"int32ToFixed64Map\": {\n" - + " },\n" - + " \"int32ToSfixed32Map\": {\n" - + " },\n" - + " \"int32ToSfixed64Map\": {\n" - + " },\n" - + " \"int32ToFloatMap\": {\n" - + " },\n" - + " \"int32ToDoubleMap\": {\n" - + " },\n" - + " \"int32ToBoolMap\": {\n" - + " },\n" - + " \"int32ToStringMap\": {\n" - + " },\n" - + " \"int32ToBytesMap\": {\n" - + " },\n" - + " \"int32ToMessageMap\": {\n" - + " },\n" - + " \"int32ToEnumMap\": {\n" - + " }\n" - + "}", - JsonFormat.printer().includingDefaultValueFields().print(mapMessage)); - - TestOneof oneofMessage = TestOneof.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); - - oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build(); - assertEquals("{\n \"oneofInt32\": 42\n}", - JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n \"oneofInt32\": 42\n}", - JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); - - TestOneof.Builder oneofBuilder = TestOneof.newBuilder(); - mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder); - oneofMessage = oneofBuilder.build(); - assertEquals("{\n \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n \"oneofNullValue\": null\n}", - JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); - } - - public void testPreservingProtoFieldNames() throws Exception { - TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build(); - assertEquals("{\n" + " \"optionalInt32\": 12345\n" + "}", JsonFormat.printer().print(message)); - assertEquals( - "{\n" + " \"optional_int32\": 12345\n" + "}", - JsonFormat.printer().preservingProtoFieldNames().print(message)); - - // The json_name field option is ignored when configured to use original proto field names. - TestCustomJsonName messageWithCustomJsonName = - TestCustomJsonName.newBuilder().setValue(12345).build(); - assertEquals( - "{\n" + " \"value\": 12345\n" + "}", - JsonFormat.printer().preservingProtoFieldNames().print(messageWithCustomJsonName)); - - // Parsers accept both original proto field names and lowerCamelCase names. - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - JsonFormat.parser().merge("{\"optionalInt32\": 12345}", builder); - assertEquals(12345, builder.getOptionalInt32()); - builder.clear(); - JsonFormat.parser().merge("{\"optional_int32\": 54321}", builder); - assertEquals(54321, builder.getOptionalInt32()); - } - - public void testOmittingInsignificantWhiteSpace() throws Exception { - TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build(); - assertEquals( - "{" + "\"optionalInt32\":12345" + "}", - JsonFormat.printer().omittingInsignificantWhitespace().print(message)); - TestAllTypes message1 = TestAllTypes.getDefaultInstance(); - assertEquals("{}", JsonFormat.printer().omittingInsignificantWhitespace().print(message1)); - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - setAllFields(builder); - TestAllTypes message2 = builder.build(); - assertEquals( - "{" - + "\"optionalInt32\":1234," - + "\"optionalInt64\":\"1234567890123456789\"," - + "\"optionalUint32\":5678," - + "\"optionalUint64\":\"2345678901234567890\"," - + "\"optionalSint32\":9012," - + "\"optionalSint64\":\"3456789012345678901\"," - + "\"optionalFixed32\":3456," - + "\"optionalFixed64\":\"4567890123456789012\"," - + "\"optionalSfixed32\":7890," - + "\"optionalSfixed64\":\"5678901234567890123\"," - + "\"optionalFloat\":1.5," - + "\"optionalDouble\":1.25," - + "\"optionalBool\":true," - + "\"optionalString\":\"Hello world!\"," - + "\"optionalBytes\":\"AAEC\"," - + "\"optionalNestedMessage\":{" - + "\"value\":100" - + "}," - + "\"optionalNestedEnum\":\"BAR\"," - + "\"repeatedInt32\":[1234,234]," - + "\"repeatedInt64\":[\"1234567890123456789\",\"234567890123456789\"]," - + "\"repeatedUint32\":[5678,678]," - + "\"repeatedUint64\":[\"2345678901234567890\",\"345678901234567890\"]," - + "\"repeatedSint32\":[9012,10]," - + "\"repeatedSint64\":[\"3456789012345678901\",\"456789012345678901\"]," - + "\"repeatedFixed32\":[3456,456]," - + "\"repeatedFixed64\":[\"4567890123456789012\",\"567890123456789012\"]," - + "\"repeatedSfixed32\":[7890,890]," - + "\"repeatedSfixed64\":[\"5678901234567890123\",\"678901234567890123\"]," - + "\"repeatedFloat\":[1.5,11.5]," - + "\"repeatedDouble\":[1.25,11.25]," - + "\"repeatedBool\":[true,true]," - + "\"repeatedString\":[\"Hello world!\",\"ello world!\"]," - + "\"repeatedBytes\":[\"AAEC\",\"AQI=\"]," - + "\"repeatedNestedMessage\":[{" - + "\"value\":100" - + "},{" - + "\"value\":200" - + "}]," - + "\"repeatedNestedEnum\":[\"BAR\",\"BAZ\"]" - + "}", - toCompactJsonString(message2)); - } - - // Regression test for b/29892357 - public void testEmptyWrapperTypesInAny() throws Exception { - JsonFormat.TypeRegistry registry = - JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); - JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(registry); - - Any.Builder builder = Any.newBuilder(); - parser.merge( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n" - + " \"value\": false\n" - + "}\n", - builder); - Any any = builder.build(); - assertEquals(0, any.getValue().size()); - } - - public void testRecursionLimit() throws Exception { - String input = - "{\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"value\": 1234\n" - + " }\n" - + " }\n" - + " }\n" - + " }\n" - + "}\n"; - - JsonFormat.Parser parser = JsonFormat.parser(); - TestRecursive.Builder builder = TestRecursive.newBuilder(); - parser.merge(input, builder); - TestRecursive message = builder.build(); - assertEquals(1234, message.getNested().getNested().getNested().getNested().getValue()); - - parser = JsonFormat.parser().usingRecursionLimit(3); - builder = TestRecursive.newBuilder(); - try { - parser.merge(input, builder); - fail("Exception is expected."); - } catch (InvalidProtocolBufferException e) { - // Expected. - } - } -} diff --git a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java b/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java deleted file mode 100644 index 5af83d88e6..0000000000 --- a/third_party/protobuf/3.2.0/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java +++ /dev/null @@ -1,498 +0,0 @@ -// 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.util; - -import com.google.protobuf.Duration; -import com.google.protobuf.Timestamp; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import junit.framework.TestCase; -import org.junit.Assert; - -/** Unit tests for {@link TimeUtil}. */ -public class TimeUtilTest extends TestCase { - public void testTimestampStringFormat() throws Exception { - Timestamp start = TimeUtil.parseTimestamp("0001-01-01T00:00:00Z"); - Timestamp end = TimeUtil.parseTimestamp("9999-12-31T23:59:59.999999999Z"); - assertEquals(TimeUtil.TIMESTAMP_SECONDS_MIN, start.getSeconds()); - assertEquals(0, start.getNanos()); - assertEquals(TimeUtil.TIMESTAMP_SECONDS_MAX, end.getSeconds()); - assertEquals(999999999, end.getNanos()); - assertEquals("0001-01-01T00:00:00Z", TimeUtil.toString(start)); - assertEquals("9999-12-31T23:59:59.999999999Z", TimeUtil.toString(end)); - - Timestamp value = TimeUtil.parseTimestamp("1970-01-01T00:00:00Z"); - assertEquals(0, value.getSeconds()); - assertEquals(0, value.getNanos()); - - // Test negative timestamps. - value = TimeUtil.parseTimestamp("1969-12-31T23:59:59.999Z"); - assertEquals(-1, value.getSeconds()); - // Nano part is in the range of [0, 999999999] for Timestamp. - assertEquals(999000000, value.getNanos()); - - // Test that 3, 6, or 9 digits are used for the fractional part. - value = Timestamp.newBuilder().setNanos(10).build(); - assertEquals("1970-01-01T00:00:00.000000010Z", TimeUtil.toString(value)); - value = Timestamp.newBuilder().setNanos(10000).build(); - assertEquals("1970-01-01T00:00:00.000010Z", TimeUtil.toString(value)); - value = Timestamp.newBuilder().setNanos(10000000).build(); - assertEquals("1970-01-01T00:00:00.010Z", TimeUtil.toString(value)); - - // Test that parsing accepts timezone offsets. - value = TimeUtil.parseTimestamp("1970-01-01T00:00:00.010+08:00"); - assertEquals("1969-12-31T16:00:00.010Z", TimeUtil.toString(value)); - value = TimeUtil.parseTimestamp("1970-01-01T00:00:00.010-08:00"); - assertEquals("1970-01-01T08:00:00.010Z", TimeUtil.toString(value)); - } - - private volatile boolean stopParsingThreads = false; - private volatile String errorMessage = ""; - - private class ParseTimestampThread extends Thread { - private final String[] strings; - private final Timestamp[] values; - - public ParseTimestampThread(String[] strings, Timestamp[] values) { - this.strings = strings; - this.values = values; - } - - @Override - public void run() { - int index = 0; - while (!stopParsingThreads) { - Timestamp result; - try { - result = TimeUtil.parseTimestamp(strings[index]); - } catch (ParseException e) { - errorMessage = "Failed to parse timestamp: " + strings[index]; - break; - } - if (result.getSeconds() != values[index].getSeconds() - || result.getNanos() != values[index].getNanos()) { - errorMessage = - "Actual result: " + result.toString() + ", expected: " + values[index].toString(); - break; - } - index = (index + 1) % strings.length; - } - } - } - - public void testTimestampConcurrentParsing() throws Exception { - String[] timestampStrings = - new String[] { - "0001-01-01T00:00:00Z", - "9999-12-31T23:59:59.999999999Z", - "1970-01-01T00:00:00Z", - "1969-12-31T23:59:59.999Z", - }; - Timestamp[] timestampValues = new Timestamp[timestampStrings.length]; - for (int i = 0; i < timestampStrings.length; i++) { - timestampValues[i] = TimeUtil.parseTimestamp(timestampStrings[i]); - } - - final int THREAD_COUNT = 16; - final int RUNNING_TIME = 5000; // in milliseconds. - final List<Thread> threads = new ArrayList<Thread>(); - - stopParsingThreads = false; - errorMessage = ""; - for (int i = 0; i < THREAD_COUNT; i++) { - Thread thread = new ParseTimestampThread(timestampStrings, timestampValues); - thread.start(); - threads.add(thread); - } - Thread.sleep(RUNNING_TIME); - stopParsingThreads = true; - for (Thread thread : threads) { - thread.join(); - } - Assert.assertEquals("", errorMessage); - } - - public void testTimetampInvalidFormat() throws Exception { - try { - // Value too small. - Timestamp value = - Timestamp.newBuilder().setSeconds(TimeUtil.TIMESTAMP_SECONDS_MIN - 1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Value too large. - Timestamp value = - Timestamp.newBuilder().setSeconds(TimeUtil.TIMESTAMP_SECONDS_MAX + 1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Invalid nanos value. - Timestamp value = Timestamp.newBuilder().setNanos(-1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Invalid nanos value. - Timestamp value = Timestamp.newBuilder().setNanos(1000000000).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Value to small. - TimeUtil.parseTimestamp("0000-01-01T00:00:00Z"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Value to large. - TimeUtil.parseTimestamp("10000-01-01T00:00:00Z"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Missing 'T'. - TimeUtil.parseTimestamp("1970-01-01 00:00:00Z"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Missing 'Z'. - TimeUtil.parseTimestamp("1970-01-01T00:00:00"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Invalid offset. - TimeUtil.parseTimestamp("1970-01-01T00:00:00+0000"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Trailing text. - TimeUtil.parseTimestamp("1970-01-01T00:00:00Z0"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Invalid nanosecond value. - TimeUtil.parseTimestamp("1970-01-01T00:00:00.ABCZ"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - } - - public void testDurationStringFormat() throws Exception { - Timestamp start = TimeUtil.parseTimestamp("0001-01-01T00:00:00Z"); - Timestamp end = TimeUtil.parseTimestamp("9999-12-31T23:59:59.999999999Z"); - Duration duration = TimeUtil.distance(start, end); - assertEquals("315537897599.999999999s", TimeUtil.toString(duration)); - duration = TimeUtil.distance(end, start); - assertEquals("-315537897599.999999999s", TimeUtil.toString(duration)); - - // Generated output should contain 3, 6, or 9 fractional digits. - duration = Duration.newBuilder().setSeconds(1).build(); - assertEquals("1s", TimeUtil.toString(duration)); - duration = Duration.newBuilder().setNanos(10000000).build(); - assertEquals("0.010s", TimeUtil.toString(duration)); - duration = Duration.newBuilder().setNanos(10000).build(); - assertEquals("0.000010s", TimeUtil.toString(duration)); - duration = Duration.newBuilder().setNanos(10).build(); - assertEquals("0.000000010s", TimeUtil.toString(duration)); - - // Parsing accepts an fractional digits as long as they fit into nano - // precision. - duration = TimeUtil.parseDuration("0.1s"); - assertEquals(100000000, duration.getNanos()); - duration = TimeUtil.parseDuration("0.0001s"); - assertEquals(100000, duration.getNanos()); - duration = TimeUtil.parseDuration("0.0000001s"); - assertEquals(100, duration.getNanos()); - - // Duration must support range from -315,576,000,000s to +315576000000s - // which includes negative values. - duration = TimeUtil.parseDuration("315576000000.999999999s"); - assertEquals(315576000000L, duration.getSeconds()); - assertEquals(999999999, duration.getNanos()); - duration = TimeUtil.parseDuration("-315576000000.999999999s"); - assertEquals(-315576000000L, duration.getSeconds()); - assertEquals(-999999999, duration.getNanos()); - } - - public void testDurationInvalidFormat() throws Exception { - try { - // Value too small. - Duration value = Duration.newBuilder().setSeconds(TimeUtil.DURATION_SECONDS_MIN - 1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Value too large. - Duration value = Duration.newBuilder().setSeconds(TimeUtil.DURATION_SECONDS_MAX + 1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Invalid nanos value. - Duration value = Duration.newBuilder().setSeconds(1).setNanos(-1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Invalid nanos value. - Duration value = Duration.newBuilder().setSeconds(-1).setNanos(1).build(); - TimeUtil.toString(value); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - try { - // Value too small. - TimeUtil.parseDuration("-315576000001s"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Value too large. - TimeUtil.parseDuration("315576000001s"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Empty. - TimeUtil.parseDuration(""); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Missing "s". - TimeUtil.parseDuration("0"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Invalid trailing data. - TimeUtil.parseDuration("0s0"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - - try { - // Invalid prefix. - TimeUtil.parseDuration("--1s"); - Assert.fail("Exception is expected."); - } catch (ParseException e) { - // Expected. - } - } - - public void testTimestampConversion() throws Exception { - Timestamp timestamp = TimeUtil.parseTimestamp("1970-01-01T00:00:01.111111111Z"); - assertEquals(1111111111, TimeUtil.toNanos(timestamp)); - assertEquals(1111111, TimeUtil.toMicros(timestamp)); - assertEquals(1111, TimeUtil.toMillis(timestamp)); - timestamp = TimeUtil.createTimestampFromNanos(1111111111); - assertEquals("1970-01-01T00:00:01.111111111Z", TimeUtil.toString(timestamp)); - timestamp = TimeUtil.createTimestampFromMicros(1111111); - assertEquals("1970-01-01T00:00:01.111111Z", TimeUtil.toString(timestamp)); - timestamp = TimeUtil.createTimestampFromMillis(1111); - assertEquals("1970-01-01T00:00:01.111Z", TimeUtil.toString(timestamp)); - - timestamp = TimeUtil.parseTimestamp("1969-12-31T23:59:59.111111111Z"); - assertEquals(-888888889, TimeUtil.toNanos(timestamp)); - assertEquals(-888889, TimeUtil.toMicros(timestamp)); - assertEquals(-889, TimeUtil.toMillis(timestamp)); - timestamp = TimeUtil.createTimestampFromNanos(-888888889); - assertEquals("1969-12-31T23:59:59.111111111Z", TimeUtil.toString(timestamp)); - timestamp = TimeUtil.createTimestampFromMicros(-888889); - assertEquals("1969-12-31T23:59:59.111111Z", TimeUtil.toString(timestamp)); - timestamp = TimeUtil.createTimestampFromMillis(-889); - assertEquals("1969-12-31T23:59:59.111Z", TimeUtil.toString(timestamp)); - } - - public void testDurationConversion() throws Exception { - Duration duration = TimeUtil.parseDuration("1.111111111s"); - assertEquals(1111111111, TimeUtil.toNanos(duration)); - assertEquals(1111111, TimeUtil.toMicros(duration)); - assertEquals(1111, TimeUtil.toMillis(duration)); - duration = TimeUtil.createDurationFromNanos(1111111111); - assertEquals("1.111111111s", TimeUtil.toString(duration)); - duration = TimeUtil.createDurationFromMicros(1111111); - assertEquals("1.111111s", TimeUtil.toString(duration)); - duration = TimeUtil.createDurationFromMillis(1111); - assertEquals("1.111s", TimeUtil.toString(duration)); - - duration = TimeUtil.parseDuration("-1.111111111s"); - assertEquals(-1111111111, TimeUtil.toNanos(duration)); - assertEquals(-1111111, TimeUtil.toMicros(duration)); - assertEquals(-1111, TimeUtil.toMillis(duration)); - duration = TimeUtil.createDurationFromNanos(-1111111111); - assertEquals("-1.111111111s", TimeUtil.toString(duration)); - duration = TimeUtil.createDurationFromMicros(-1111111); - assertEquals("-1.111111s", TimeUtil.toString(duration)); - duration = TimeUtil.createDurationFromMillis(-1111); - assertEquals("-1.111s", TimeUtil.toString(duration)); - } - - public void testTimeOperations() throws Exception { - Timestamp start = TimeUtil.parseTimestamp("0001-01-01T00:00:00Z"); - Timestamp end = TimeUtil.parseTimestamp("9999-12-31T23:59:59.999999999Z"); - - Duration duration = TimeUtil.distance(start, end); - assertEquals("315537897599.999999999s", TimeUtil.toString(duration)); - Timestamp value = TimeUtil.add(start, duration); - assertEquals(end, value); - value = TimeUtil.subtract(end, duration); - assertEquals(start, value); - - duration = TimeUtil.distance(end, start); - assertEquals("-315537897599.999999999s", TimeUtil.toString(duration)); - value = TimeUtil.add(end, duration); - assertEquals(start, value); - value = TimeUtil.subtract(start, duration); - assertEquals(end, value); - - // Result is larger than Long.MAX_VALUE. - try { - duration = TimeUtil.parseDuration("315537897599.999999999s"); - duration = TimeUtil.multiply(duration, 315537897599.999999999); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - // Result is lesser than Long.MIN_VALUE. - try { - duration = TimeUtil.parseDuration("315537897599.999999999s"); - duration = TimeUtil.multiply(duration, -315537897599.999999999); - Assert.fail("Exception is expected."); - } catch (IllegalArgumentException e) { - // Expected. - } - - duration = TimeUtil.parseDuration("-1.125s"); - duration = TimeUtil.divide(duration, 2.0); - assertEquals("-0.562500s", TimeUtil.toString(duration)); - duration = TimeUtil.multiply(duration, 2.0); - assertEquals("-1.125s", TimeUtil.toString(duration)); - - duration = TimeUtil.add(duration, duration); - assertEquals("-2.250s", TimeUtil.toString(duration)); - - duration = TimeUtil.subtract(duration, TimeUtil.parseDuration("-1s")); - assertEquals("-1.250s", TimeUtil.toString(duration)); - - // Multiplications (with results larger than Long.MAX_VALUE in nanoseconds). - duration = TimeUtil.parseDuration("0.999999999s"); - assertEquals( - "315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L))); - duration = TimeUtil.parseDuration("-0.999999999s"); - assertEquals( - "-315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L))); - assertEquals( - "315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, -315576000000L))); - - // Divisions (with values larger than Long.MAX_VALUE in nanoseconds). - Duration d1 = TimeUtil.parseDuration("315576000000s"); - Duration d2 = TimeUtil.subtract(d1, TimeUtil.createDurationFromNanos(1)); - assertEquals(1, TimeUtil.divide(d1, d2)); - assertEquals(0, TimeUtil.divide(d2, d1)); - assertEquals("0.000000001s", TimeUtil.toString(TimeUtil.remainder(d1, d2))); - assertEquals("315575999999.999999999s", TimeUtil.toString(TimeUtil.remainder(d2, d1))); - - // Divisions involving negative values. - // - // (-5) / 2 = -2, remainder = -1 - d1 = TimeUtil.parseDuration("-5s"); - d2 = TimeUtil.parseDuration("2s"); - assertEquals(-2, TimeUtil.divide(d1, d2)); - assertEquals(-2, TimeUtil.divide(d1, 2).getSeconds()); - assertEquals(-1, TimeUtil.remainder(d1, d2).getSeconds()); - // (-5) / (-2) = 2, remainder = -1 - d1 = TimeUtil.parseDuration("-5s"); - d2 = TimeUtil.parseDuration("-2s"); - assertEquals(2, TimeUtil.divide(d1, d2)); - assertEquals(2, TimeUtil.divide(d1, -2).getSeconds()); - assertEquals(-1, TimeUtil.remainder(d1, d2).getSeconds()); - // 5 / (-2) = -2, remainder = 1 - d1 = TimeUtil.parseDuration("5s"); - d2 = TimeUtil.parseDuration("-2s"); - assertEquals(-2, TimeUtil.divide(d1, d2)); - assertEquals(-2, TimeUtil.divide(d1, -2).getSeconds()); - assertEquals(1, TimeUtil.remainder(d1, d2).getSeconds()); - } -} |