| // 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()); |
| } |
| } |