• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.google.common.truth.Truth.assertThat;
34 
35 import com.google.common.collect.ImmutableList;
36 import com.google.protobuf.FieldMask;
37 import protobuf_unittest.UnittestProto.NestedTestAllTypes;
38 import protobuf_unittest.UnittestProto.TestAllTypes;
39 import junit.framework.TestCase;
40 
41 /** Unit tests for {@link FieldMaskUtil}. */
42 public class FieldMaskUtilTest extends TestCase {
testIsValid()43   public void testIsValid() throws Exception {
44     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload"));
45     assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist"));
46     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32"));
47     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_int32"));
48     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message"));
49     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message"));
50     assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.nonexist"));
51 
52     assertTrue(
53         FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("payload")));
54     assertFalse(
55         FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist")));
56     assertFalse(
57         FieldMaskUtil.isValid(
58             NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist")));
59 
60     assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload"));
61     assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist"));
62 
63     assertTrue(
64         FieldMaskUtil.isValid(
65             NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload")));
66     assertFalse(
67         FieldMaskUtil.isValid(
68             NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist")));
69 
70     assertTrue(
71         FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message.bb"));
72     // Repeated fields cannot have sub-paths.
73     assertFalse(
74         FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message.bb"));
75     // Non-message fields cannot have sub-paths.
76     assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32.bb"));
77   }
78 
testToString()79   public void testToString() throws Exception {
80     assertEquals("", FieldMaskUtil.toString(FieldMask.getDefaultInstance()));
81     FieldMask mask = FieldMask.newBuilder().addPaths("foo").build();
82     assertEquals("foo", FieldMaskUtil.toString(mask));
83     mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build();
84     assertEquals("foo,bar", FieldMaskUtil.toString(mask));
85 
86     // Empty field paths are ignored.
87     mask =
88         FieldMask.newBuilder()
89             .addPaths("")
90             .addPaths("foo")
91             .addPaths("")
92             .addPaths("bar")
93             .addPaths("")
94             .build();
95     assertEquals("foo,bar", FieldMaskUtil.toString(mask));
96   }
97 
testFromString()98   public void testFromString() throws Exception {
99     FieldMask mask = FieldMaskUtil.fromString("");
100     assertEquals(0, mask.getPathsCount());
101     mask = FieldMaskUtil.fromString("foo");
102     assertEquals(1, mask.getPathsCount());
103     assertEquals("foo", mask.getPaths(0));
104     mask = FieldMaskUtil.fromString("foo,bar.baz");
105     assertEquals(2, mask.getPathsCount());
106     assertEquals("foo", mask.getPaths(0));
107     assertEquals("bar.baz", mask.getPaths(1));
108 
109     // Empty field paths are ignore.
110     mask = FieldMaskUtil.fromString(",foo,,bar,");
111     assertEquals(2, mask.getPathsCount());
112     assertEquals("foo", mask.getPaths(0));
113     assertEquals("bar", mask.getPaths(1));
114 
115     // Check whether the field paths are valid if a class parameter is provided.
116     mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, ",payload");
117 
118     try {
119       mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, "payload,nonexist");
120       fail("Exception is expected.");
121     } catch (IllegalArgumentException e) {
122       // Expected.
123     }
124   }
125 
testFromFieldNumbers()126   public void testFromFieldNumbers() throws Exception {
127     FieldMask mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class);
128     assertEquals(0, mask.getPathsCount());
129     mask =
130         FieldMaskUtil.fromFieldNumbers(
131             TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER);
132     assertEquals(1, mask.getPathsCount());
133     assertEquals("optional_int32", mask.getPaths(0));
134     mask =
135         FieldMaskUtil.fromFieldNumbers(
136             TestAllTypes.class,
137             TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER,
138             TestAllTypes.OPTIONAL_INT64_FIELD_NUMBER);
139     assertEquals(2, mask.getPathsCount());
140     assertEquals("optional_int32", mask.getPaths(0));
141     assertEquals("optional_int64", mask.getPaths(1));
142 
143     try {
144       int invalidFieldNumber = 1000;
145       mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class, invalidFieldNumber);
146       fail("Exception is expected.");
147     } catch (IllegalArgumentException expected) {
148     }
149   }
150 
testToJsonString()151   public void testToJsonString() throws Exception {
152     FieldMask mask = FieldMask.getDefaultInstance();
153     assertEquals("", FieldMaskUtil.toJsonString(mask));
154     mask = FieldMask.newBuilder().addPaths("foo").build();
155     assertEquals("foo", FieldMaskUtil.toJsonString(mask));
156     mask = FieldMask.newBuilder().addPaths("foo.bar_baz").addPaths("").build();
157     assertEquals("foo.barBaz", FieldMaskUtil.toJsonString(mask));
158     mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar_baz").build();
159     assertEquals("foo,barBaz", FieldMaskUtil.toJsonString(mask));
160   }
161 
testFromJsonString()162   public void testFromJsonString() throws Exception {
163     FieldMask mask = FieldMaskUtil.fromJsonString("");
164     assertEquals(0, mask.getPathsCount());
165     mask = FieldMaskUtil.fromJsonString("foo");
166     assertEquals(1, mask.getPathsCount());
167     assertEquals("foo", mask.getPaths(0));
168     mask = FieldMaskUtil.fromJsonString("foo.barBaz");
169     assertEquals(1, mask.getPathsCount());
170     assertEquals("foo.bar_baz", mask.getPaths(0));
171     mask = FieldMaskUtil.fromJsonString("foo,barBaz");
172     assertEquals(2, mask.getPathsCount());
173     assertEquals("foo", mask.getPaths(0));
174     assertEquals("bar_baz", mask.getPaths(1));
175   }
176 
testFromStringList()177   public void testFromStringList() throws Exception {
178     FieldMask mask =
179         FieldMaskUtil.fromStringList(
180             NestedTestAllTypes.class, ImmutableList.of("payload.repeated_nested_message", "child"));
181     assertThat(mask)
182         .isEqualTo(
183             FieldMask.newBuilder()
184                 .addPaths("payload.repeated_nested_message")
185                 .addPaths("child")
186                 .build());
187 
188     mask =
189         FieldMaskUtil.fromStringList(
190             NestedTestAllTypes.getDescriptor(),
191             ImmutableList.of("payload.repeated_nested_message", "child"));
192     assertThat(mask)
193         .isEqualTo(
194             FieldMask.newBuilder()
195                 .addPaths("payload.repeated_nested_message")
196                 .addPaths("child")
197                 .build());
198 
199     mask =
200         FieldMaskUtil.fromStringList(ImmutableList.of("payload.repeated_nested_message", "child"));
201     assertThat(mask)
202         .isEqualTo(
203             FieldMask.newBuilder()
204                 .addPaths("payload.repeated_nested_message")
205                 .addPaths("child")
206                 .build());
207   }
208 
testUnion()209   public void testUnion() throws Exception {
210     // Only test a simple case here and expect
211     // {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios.
212     FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz");
213     FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar");
214     FieldMask result = FieldMaskUtil.union(mask1, mask2);
215     assertEquals("bar,foo", FieldMaskUtil.toString(result));
216   }
217 
testUnion_usingVarArgs()218   public void testUnion_usingVarArgs() throws Exception {
219     FieldMask mask1 = FieldMaskUtil.fromString("foo");
220     FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz");
221     FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
222     FieldMask mask4 = FieldMaskUtil.fromString("bar");
223     FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4);
224     assertEquals("bar,foo", FieldMaskUtil.toString(result));
225   }
226 
testSubstract()227   public void testSubstract() throws Exception {
228     // Only test a simple case here and expect
229     // {@link FieldMaskTreeTest#testRemoveFieldPath} to cover all scenarios.
230     FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz");
231     FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar");
232     FieldMask result = FieldMaskUtil.subtract(mask1, mask2);
233     assertEquals("foo", FieldMaskUtil.toString(result));
234   }
235 
testSubstract_usingVarArgs()236   public void testSubstract_usingVarArgs() throws Exception {
237     FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz.bar");
238     FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.baz.quz");
239     FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
240     FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz");
241     FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4);
242     assertEquals("bar", FieldMaskUtil.toString(result));
243   }
244 
testIntersection()245   public void testIntersection() throws Exception {
246     // Only test a simple case here and expect
247     // {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios.
248     FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz");
249     FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar");
250     FieldMask result = FieldMaskUtil.intersection(mask1, mask2);
251     assertEquals("bar.baz,bar.quz,foo.bar", FieldMaskUtil.toString(result));
252   }
253 
testMerge()254   public void testMerge() throws Exception {
255     // Only test a simple case here and expect
256     // {@link FieldMaskTreeTest#testMerge} to cover all scenarios.
257     NestedTestAllTypes source =
258         NestedTestAllTypes.newBuilder()
259             .setPayload(TestAllTypes.newBuilder().setOptionalInt32(1234))
260             .build();
261     NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder();
262     FieldMaskUtil.merge(FieldMaskUtil.fromString("payload"), source, builder);
263     assertEquals(1234, builder.getPayload().getOptionalInt32());
264   }
265 }
266