• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2016 Google Inc.  All rights reserved.
4 // https://developers.google.com/protocol-buffers/
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #endregion
32 
33 using System;
34 using Google.Protobuf.TestProtos;
35 using NUnit.Framework;
36 
37 namespace Google.Protobuf.WellKnownTypes
38 {
39     public class FieldMaskTest
40     {
41         [Test]
42         [TestCase("foo__bar")]
43         [TestCase("foo_3_ar")]
44         [TestCase("fooBar")]
ToString_Invalid(string input)45         public void ToString_Invalid(string input)
46         {
47             var mask = new FieldMask { Paths = { input } };
48             var text = mask.ToString();
49             // More specific test below
50             Assert.That(text, Does.Contain("@warning"));
51             Assert.That(text, Does.Contain(input));
52         }
53 
54         [Test]
ToString_Invalid_Precise()55         public void ToString_Invalid_Precise()
56         {
57             var mask = new FieldMask { Paths = { "x", "foo__bar", @"x\y" } };
58             Assert.AreEqual(
59                 "{ \"@warning\": \"Invalid FieldMask\", \"paths\": [ \"x\", \"foo__bar\", \"x\\\\y\" ] }",
60                 mask.ToString());
61         }
62 
63         [Test]
IsValid()64         public void IsValid()
65         {
66             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload"));
67             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>("nonexist"));
68             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload.single_int32"));
69             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload.repeated_int32"));
70             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload.single_nested_message"));
71             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload.repeated_nested_message"));
72             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>("payload.nonexist"));
73 
74             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>(FieldMask.FromString("payload")));
75             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>(FieldMask.FromString("nonexist")));
76             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>(FieldMask.FromString("payload,nonexist")));
77 
78             Assert.IsTrue(FieldMask.IsValid(NestedTestAllTypes.Descriptor, "payload"));
79             Assert.IsFalse(FieldMask.IsValid(NestedTestAllTypes.Descriptor, "nonexist"));
80 
81             Assert.IsTrue(FieldMask.IsValid(NestedTestAllTypes.Descriptor, FieldMask.FromString("payload")));
82             Assert.IsFalse(FieldMask.IsValid(NestedTestAllTypes.Descriptor, FieldMask.FromString("nonexist")));
83 
84             Assert.IsTrue(FieldMask.IsValid<NestedTestAllTypes>("payload.single_nested_message.bb"));
85 
86             // Repeated fields cannot have sub-paths.
87             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>("payload.repeated_nested_message.bb"));
88 
89             // Non-message fields cannot have sub-paths.
90             Assert.IsFalse(FieldMask.IsValid<NestedTestAllTypes>("payload.single_int32.bb"));
91         }
92 
93         [Test]
94         [TestCase(new string[] { }, "\"\"")]
95         [TestCase(new string[] { "foo" }, "\"foo\"")]
96         [TestCase(new string[] { "foo", "bar" }, "\"foo,bar\"")]
97         [TestCase(new string[] { "", "foo", "", "bar", "" }, "\",foo,,bar,\"")]
ToString(string[] input, string expectedOutput)98         public void ToString(string[] input, string expectedOutput)
99         {
100             FieldMask mask = new FieldMask();
101             mask.Paths.AddRange(input);
102             Assert.AreEqual(expectedOutput, mask.ToString());
103         }
104 
105         [Test]
106         [TestCase("", new string[] { })]
107         [TestCase("foo", new string[] { "foo" })]
108         [TestCase("foo,bar.baz", new string[] { "foo", "bar.baz" })]
109         [TestCase(",foo,,bar,", new string[] { "foo", "bar" })]
FromString(string input, string[] expectedOutput)110         public void FromString(string input, string[] expectedOutput)
111         {
112             FieldMask mask = FieldMask.FromString(input);
113             Assert.AreEqual(expectedOutput.Length, mask.Paths.Count);
114             for (int i = 0; i < expectedOutput.Length; i++)
115             {
116                 Assert.AreEqual(expectedOutput[i], mask.Paths[i]);
117             }
118         }
119 
120         [Test]
FromString_Validated()121         public void FromString_Validated()
122         {
123             // Check whether the field paths are valid if a class parameter is provided.
124             Assert.DoesNotThrow(() => FieldMask.FromString<NestedTestAllTypes>(",payload"));
125             Assert.Throws<InvalidProtocolBufferException>(() => FieldMask.FromString<NestedTestAllTypes>("payload,nonexist"));
126         }
127 
128         [Test]
129         [TestCase(new int[] { }, new string[] { })]
130         [TestCase(new int[] { TestAllTypes.SingleInt32FieldNumber }, new string[] { "single_int32" })]
131         [TestCase(new int[] { TestAllTypes.SingleInt32FieldNumber, TestAllTypes.SingleInt64FieldNumber }, new string[] { "single_int32", "single_int64" })]
FromFieldNumbers(int[] input, string[] expectedOutput)132         public void FromFieldNumbers(int[] input, string[] expectedOutput)
133         {
134             FieldMask mask = FieldMask.FromFieldNumbers<TestAllTypes>(input);
135             Assert.AreEqual(expectedOutput.Length, mask.Paths.Count);
136             for (int i = 0; i < expectedOutput.Length; i++)
137             {
138                 Assert.AreEqual(expectedOutput[i], mask.Paths[i]);
139             }
140         }
141 
142         [Test]
FromFieldNumbers_Invalid()143         public void FromFieldNumbers_Invalid()
144         {
145             Assert.Throws<ArgumentNullException>(() =>
146             {
147                 int invalidFieldNumber = 1000;
148                 FieldMask.FromFieldNumbers<TestAllTypes>(invalidFieldNumber);
149             });
150         }
151 
152         [Test]
153         [TestCase(new string[] { }, "\"\"")]
154         [TestCase(new string[] { "foo" }, "\"foo\"")]
155         [TestCase(new string[] { "foo", "bar" }, "\"foo,bar\"")]
156         [TestCase(new string[] { "", "foo", "", "bar", "" }, "\",foo,bar\"")]
Normalize(string[] input, string expectedOutput)157         public void Normalize(string[] input, string expectedOutput)
158         {
159             FieldMask mask = new FieldMask();
160             mask.Paths.AddRange(input);
161             FieldMask result = mask.Normalize();
162             Assert.AreEqual(expectedOutput, result.ToString());
163         }
164 
165         [Test]
Union()166         public void Union()
167         {
168             // Only test a simple case here and expect
169             // {@link FieldMaskTreeTest#AddFieldPath} to cover all scenarios.
170             FieldMask mask1 = FieldMask.FromString("foo,bar.baz,bar.quz");
171             FieldMask mask2 = FieldMask.FromString("foo.bar,bar");
172             FieldMask result = mask1.Union(mask2);
173             Assert.AreEqual(2, result.Paths.Count);
174             Assert.Contains("bar", result.Paths);
175             Assert.Contains("foo", result.Paths);
176             Assert.That(result.Paths, Has.No.Member("bar.baz"));
177             Assert.That(result.Paths, Has.No.Member("bar.quz"));
178             Assert.That(result.Paths, Has.No.Member("foo.bar"));
179         }
180 
181         [Test]
Union_UsingVarArgs()182         public void Union_UsingVarArgs()
183         {
184             FieldMask mask1 = FieldMask.FromString("foo");
185             FieldMask mask2 = FieldMask.FromString("foo.bar,bar.quz");
186             FieldMask mask3 = FieldMask.FromString("bar.quz");
187             FieldMask mask4 = FieldMask.FromString("bar");
188             FieldMask result = mask1.Union(mask2, mask3, mask4);
189             Assert.AreEqual(2, result.Paths.Count);
190             Assert.Contains("bar", result.Paths);
191             Assert.Contains("foo", result.Paths);
192             Assert.That(result.Paths, Has.No.Member("foo.bar"));
193             Assert.That(result.Paths, Has.No.Member("bar.quz"));
194         }
195 
196         [Test]
Intersection()197         public void Intersection()
198         {
199             // Only test a simple case here and expect
200             // {@link FieldMaskTreeTest#IntersectFieldPath} to cover all scenarios.
201             FieldMask mask1 = FieldMask.FromString("foo,bar.baz,bar.quz");
202             FieldMask mask2 = FieldMask.FromString("foo.bar,bar");
203             FieldMask result = mask1.Intersection(mask2);
204             Assert.AreEqual(3, result.Paths.Count);
205             Assert.Contains("foo.bar", result.Paths);
206             Assert.Contains("bar.baz", result.Paths);
207             Assert.Contains("bar.quz", result.Paths);
208             Assert.That(result.Paths, Has.No.Member("foo"));
209             Assert.That(result.Paths, Has.No.Member("bar"));
210         }
211 
212         [Test]
Merge()213         public void Merge()
214         {
215             // Only test a simple case here and expect
216             // {@link FieldMaskTreeTest#Merge} to cover all scenarios.
217             FieldMask fieldMask = FieldMask.FromString("payload");
218             NestedTestAllTypes source = new NestedTestAllTypes
219             {
220                 Payload = new TestAllTypes
221                 {
222                     SingleInt32 = 1234,
223                     SingleFixed64 = 4321
224                 }
225             };
226             NestedTestAllTypes destination = new NestedTestAllTypes();
227             fieldMask.Merge(source, destination);
228             Assert.AreEqual(1234, destination.Payload.SingleInt32);
229             Assert.AreEqual(4321, destination.Payload.SingleFixed64);
230 
231             destination = new NestedTestAllTypes
232             {
233                 Payload = new TestAllTypes
234                 {
235                     SingleInt32 = 4321,
236                     SingleInt64 = 5678
237                 }
238             };
239             fieldMask.Merge(source, destination);
240             Assert.AreEqual(1234, destination.Payload.SingleInt32);
241             Assert.AreEqual(5678, destination.Payload.SingleInt64);
242             Assert.AreEqual(4321, destination.Payload.SingleFixed64);
243         }
244     }
245 }
246