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