1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf.util; 32 33 import com.google.protobuf.FieldMask; 34 import protobuf_unittest.UnittestProto.NestedTestAllTypes; 35 import protobuf_unittest.UnittestProto.TestAllTypes; 36 37 import junit.framework.TestCase; 38 39 /** Unit tests for {@link FieldMaskUtil}. */ 40 public class FieldMaskUtilTest extends TestCase { testIsValid()41 public void testIsValid() throws Exception { 42 assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload")); 43 assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist")); 44 assertTrue(FieldMaskUtil.isValid( 45 NestedTestAllTypes.class, "payload.optional_int32")); 46 assertTrue(FieldMaskUtil.isValid( 47 NestedTestAllTypes.class, "payload.repeated_int32")); 48 assertTrue(FieldMaskUtil.isValid( 49 NestedTestAllTypes.class, "payload.optional_nested_message")); 50 assertTrue(FieldMaskUtil.isValid( 51 NestedTestAllTypes.class, "payload.repeated_nested_message")); 52 assertFalse(FieldMaskUtil.isValid( 53 NestedTestAllTypes.class, "payload.nonexist")); 54 55 assertTrue(FieldMaskUtil.isValid( 56 NestedTestAllTypes.class, FieldMaskUtil.fromString("payload"))); 57 assertFalse(FieldMaskUtil.isValid( 58 NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist"))); 59 assertFalse(FieldMaskUtil.isValid( 60 NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist"))); 61 62 assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload")); 63 assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist")); 64 65 assertTrue(FieldMaskUtil.isValid( 66 NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload"))); 67 assertFalse(FieldMaskUtil.isValid( 68 NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist"))); 69 70 assertTrue(FieldMaskUtil.isValid( 71 NestedTestAllTypes.class, "payload.optional_nested_message.bb")); 72 // Repeated fields cannot have sub-paths. 73 assertFalse(FieldMaskUtil.isValid( 74 NestedTestAllTypes.class, "payload.repeated_nested_message.bb")); 75 // Non-message fields cannot have sub-paths. 76 assertFalse(FieldMaskUtil.isValid( 77 NestedTestAllTypes.class, "payload.optional_int32.bb")); 78 } 79 testToString()80 public void testToString() throws Exception { 81 assertEquals("", FieldMaskUtil.toString(FieldMask.getDefaultInstance())); 82 FieldMask mask = FieldMask.newBuilder().addPaths("foo").build(); 83 assertEquals("foo", FieldMaskUtil.toString(mask)); 84 mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build(); 85 assertEquals("foo,bar", FieldMaskUtil.toString(mask)); 86 87 // Empty field paths are ignored. 88 mask = FieldMask.newBuilder().addPaths("").addPaths("foo").addPaths(""). 89 addPaths("bar").addPaths("").build(); 90 assertEquals("foo,bar", FieldMaskUtil.toString(mask)); 91 } 92 testFromString()93 public void testFromString() throws Exception { 94 FieldMask mask = FieldMaskUtil.fromString(""); 95 assertEquals(0, mask.getPathsCount()); 96 mask = FieldMaskUtil.fromString("foo"); 97 assertEquals(1, mask.getPathsCount()); 98 assertEquals("foo", mask.getPaths(0)); 99 mask = FieldMaskUtil.fromString("foo,bar.baz"); 100 assertEquals(2, mask.getPathsCount()); 101 assertEquals("foo", mask.getPaths(0)); 102 assertEquals("bar.baz", mask.getPaths(1)); 103 104 // Empty field paths are ignore. 105 mask = FieldMaskUtil.fromString(",foo,,bar,"); 106 assertEquals(2, mask.getPathsCount()); 107 assertEquals("foo", mask.getPaths(0)); 108 assertEquals("bar", mask.getPaths(1)); 109 110 // Check whether the field paths are valid if a class parameter is provided. 111 mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, ",payload"); 112 113 try { 114 mask = FieldMaskUtil.fromString( 115 NestedTestAllTypes.class, "payload,nonexist"); 116 fail("Exception is expected."); 117 } catch (IllegalArgumentException e) { 118 // Expected. 119 } 120 } 121 testFromFieldNumbers()122 public void testFromFieldNumbers() throws Exception { 123 FieldMask mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class); 124 assertEquals(0, mask.getPathsCount()); 125 mask = 126 FieldMaskUtil.fromFieldNumbers( 127 TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER); 128 assertEquals(1, mask.getPathsCount()); 129 assertEquals("optional_int32", mask.getPaths(0)); 130 mask = 131 FieldMaskUtil.fromFieldNumbers( 132 TestAllTypes.class, 133 TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 134 TestAllTypes.OPTIONAL_INT64_FIELD_NUMBER); 135 assertEquals(2, mask.getPathsCount()); 136 assertEquals("optional_int32", mask.getPaths(0)); 137 assertEquals("optional_int64", mask.getPaths(1)); 138 139 try { 140 int invalidFieldNumber = 1000; 141 mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class, invalidFieldNumber); 142 fail("Exception is expected."); 143 } catch (IllegalArgumentException expected) { 144 } 145 } 146 testUnion()147 public void testUnion() throws Exception { 148 // Only test a simple case here and expect 149 // {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios. 150 FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); 151 FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); 152 FieldMask result = FieldMaskUtil.union(mask1, mask2); 153 assertEquals("bar,foo", FieldMaskUtil.toString(result)); 154 } 155 testUnion_usingVarArgs()156 public void testUnion_usingVarArgs() throws Exception { 157 FieldMask mask1 = FieldMaskUtil.fromString("foo"); 158 FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz"); 159 FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); 160 FieldMask mask4 = FieldMaskUtil.fromString("bar"); 161 FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4); 162 assertEquals("bar,foo", FieldMaskUtil.toString(result)); 163 } 164 testIntersection()165 public void testIntersection() throws Exception { 166 // Only test a simple case here and expect 167 // {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios. 168 FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); 169 FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); 170 FieldMask result = FieldMaskUtil.intersection(mask1, mask2); 171 assertEquals("bar.baz,bar.quz,foo.bar", FieldMaskUtil.toString(result)); 172 } 173 testMerge()174 public void testMerge() throws Exception { 175 // Only test a simple case here and expect 176 // {@link FieldMaskTreeTest#testMerge} to cover all scenarios. 177 NestedTestAllTypes source = NestedTestAllTypes.newBuilder() 178 .setPayload(TestAllTypes.newBuilder().setOptionalInt32(1234)) 179 .build(); 180 NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder(); 181 FieldMaskUtil.merge(FieldMaskUtil.fromString("payload"), source, builder); 182 assertEquals(1234, builder.getPayload().getOptionalInt32()); 183 } 184 } 185