| OLD | NEW |
| (Empty) |
| 1 #region Copyright notice and license | |
| 2 // Protocol Buffers - Google's data interchange format | |
| 3 // Copyright 2008 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 using UnitTest.Issues.TestProtos; | |
| 37 using Google.Protobuf.WellKnownTypes; | |
| 38 | |
| 39 namespace Google.Protobuf | |
| 40 { | |
| 41 /// <summary> | |
| 42 /// Tests for the JSON formatter. Note that in these tests, double quotes ar
e replaced with apostrophes | |
| 43 /// for the sake of readability (embedding \" everywhere is painful). See th
e AssertJson method for details. | |
| 44 /// </summary> | |
| 45 public class JsonFormatterTest | |
| 46 { | |
| 47 [Test] | |
| 48 public void DefaultValues_WhenOmitted() | |
| 49 { | |
| 50 var formatter = new JsonFormatter(new JsonFormatter.Settings(formatD
efaultValues: false)); | |
| 51 | |
| 52 AssertJson("{ }", formatter.Format(new ForeignMessage())); | |
| 53 AssertJson("{ }", formatter.Format(new TestAllTypes())); | |
| 54 AssertJson("{ }", formatter.Format(new TestMap())); | |
| 55 } | |
| 56 | |
| 57 [Test] | |
| 58 public void DefaultValues_WhenIncluded() | |
| 59 { | |
| 60 var formatter = new JsonFormatter(new JsonFormatter.Settings(formatD
efaultValues: true)); | |
| 61 AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage())); | |
| 62 } | |
| 63 | |
| 64 [Test] | |
| 65 public void AllSingleFields() | |
| 66 { | |
| 67 var message = new TestAllTypes | |
| 68 { | |
| 69 SingleBool = true, | |
| 70 SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), | |
| 71 SingleDouble = 23.5, | |
| 72 SingleFixed32 = 23, | |
| 73 SingleFixed64 = 1234567890123, | |
| 74 SingleFloat = 12.25f, | |
| 75 SingleForeignEnum = ForeignEnum.FOREIGN_BAR, | |
| 76 SingleForeignMessage = new ForeignMessage { C = 10 }, | |
| 77 SingleImportEnum = ImportEnum.IMPORT_BAZ, | |
| 78 SingleImportMessage = new ImportMessage { D = 20 }, | |
| 79 SingleInt32 = 100, | |
| 80 SingleInt64 = 3210987654321, | |
| 81 SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO, | |
| 82 SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb
= 35 }, | |
| 83 SinglePublicImportMessage = new PublicImportMessage { E = 54 }, | |
| 84 SingleSfixed32 = -123, | |
| 85 SingleSfixed64 = -12345678901234, | |
| 86 SingleSint32 = -456, | |
| 87 SingleSint64 = -12345678901235, | |
| 88 SingleString = "test\twith\ttabs", | |
| 89 SingleUint32 = uint.MaxValue, | |
| 90 SingleUint64 = ulong.MaxValue, | |
| 91 }; | |
| 92 var actualText = JsonFormatter.Default.Format(message); | |
| 93 | |
| 94 // Fields in numeric order | |
| 95 var expectedText = "{ " + | |
| 96 "'singleInt32': 100, " + | |
| 97 "'singleInt64': '3210987654321', " + | |
| 98 "'singleUint32': 4294967295, " + | |
| 99 "'singleUint64': '18446744073709551615', " + | |
| 100 "'singleSint32': -456, " + | |
| 101 "'singleSint64': '-12345678901235', " + | |
| 102 "'singleFixed32': 23, " + | |
| 103 "'singleFixed64': '1234567890123', " + | |
| 104 "'singleSfixed32': -123, " + | |
| 105 "'singleSfixed64': '-12345678901234', " + | |
| 106 "'singleFloat': 12.25, " + | |
| 107 "'singleDouble': 23.5, " + | |
| 108 "'singleBool': true, " + | |
| 109 "'singleString': 'test\\twith\\ttabs', " + | |
| 110 "'singleBytes': 'AQIDBA==', " + | |
| 111 "'singleNestedMessage': { 'bb': 35 }, " + | |
| 112 "'singleForeignMessage': { 'c': 10 }, " + | |
| 113 "'singleImportMessage': { 'd': 20 }, " + | |
| 114 "'singleNestedEnum': 'FOO', " + | |
| 115 "'singleForeignEnum': 'FOREIGN_BAR', " + | |
| 116 "'singleImportEnum': 'IMPORT_BAZ', " + | |
| 117 "'singlePublicImportMessage': { 'e': 54 }" + | |
| 118 " }"; | |
| 119 AssertJson(expectedText, actualText); | |
| 120 } | |
| 121 | |
| 122 [Test] | |
| 123 public void RepeatedField() | |
| 124 { | |
| 125 AssertJson("{ 'repeatedInt32': [ 1, 2, 3, 4, 5 ] }", | |
| 126 JsonFormatter.Default.Format(new TestAllTypes { RepeatedInt32 =
{ 1, 2, 3, 4, 5 } })); | |
| 127 } | |
| 128 | |
| 129 [Test] | |
| 130 public void MapField_StringString() | |
| 131 { | |
| 132 AssertJson("{ 'mapStringString': { 'with spaces': 'bar', 'a': 'b' }
}", | |
| 133 JsonFormatter.Default.Format(new TestMap { MapStringString = { {
"with spaces", "bar" }, { "a", "b" } } })); | |
| 134 } | |
| 135 | |
| 136 [Test] | |
| 137 public void MapField_Int32Int32() | |
| 138 { | |
| 139 // The keys are quoted, but the values aren't. | |
| 140 AssertJson("{ 'mapInt32Int32': { '0': 1, '2': 3 } }", | |
| 141 JsonFormatter.Default.Format(new TestMap { MapInt32Int32 = { { 0
, 1 }, { 2, 3 } } })); | |
| 142 } | |
| 143 | |
| 144 [Test] | |
| 145 public void MapField_BoolBool() | |
| 146 { | |
| 147 // The keys are quoted, but the values aren't. | |
| 148 AssertJson("{ 'mapBoolBool': { 'false': true, 'true': false } }", | |
| 149 JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { fal
se, true }, { true, false } } })); | |
| 150 } | |
| 151 | |
| 152 [TestCase(1.0, "1")] | |
| 153 [TestCase(double.NaN, "'NaN'")] | |
| 154 [TestCase(double.PositiveInfinity, "'Infinity'")] | |
| 155 [TestCase(double.NegativeInfinity, "'-Infinity'")] | |
| 156 public void DoubleRepresentations(double value, string expectedValueText
) | |
| 157 { | |
| 158 var message = new TestAllTypes { SingleDouble = value }; | |
| 159 string actualText = JsonFormatter.Default.Format(message); | |
| 160 string expectedText = "{ 'singleDouble': " + expectedValueText + " }
"; | |
| 161 AssertJson(expectedText, actualText); | |
| 162 } | |
| 163 | |
| 164 [Test] | |
| 165 public void UnknownEnumValueOmitted_SingleField() | |
| 166 { | |
| 167 var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 1
00 }; | |
| 168 AssertJson("{ }", JsonFormatter.Default.Format(message)); | |
| 169 } | |
| 170 | |
| 171 [Test] | |
| 172 public void UnknownEnumValueOmitted_RepeatedField() | |
| 173 { | |
| 174 var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum
.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } }; | |
| 175 AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 'FOREIGN_FOO'
] }", JsonFormatter.Default.Format(message)); | |
| 176 } | |
| 177 | |
| 178 [Test] | |
| 179 public void UnknownEnumValueOmitted_MapField() | |
| 180 { | |
| 181 // This matches the C++ behaviour. | |
| 182 var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_F
OO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } }; | |
| 183 AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '3': 'MAP_ENUM_
BAR' } }", JsonFormatter.Default.Format(message)); | |
| 184 } | |
| 185 | |
| 186 [Test] | |
| 187 public void UnknownEnumValueOmitted_RepeatedField_AllEntriesUnknown() | |
| 188 { | |
| 189 // *Maybe* we should hold off on writing the "[" until we find that
we've got at least one value to write... | |
| 190 // but this is what happens at the moment, and it doesn't seem too a
wful. | |
| 191 var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnu
m) 200, (ForeignEnum) 100 } }; | |
| 192 AssertJson("{ 'repeatedForeignEnum': [ ] }", JsonFormatter.Default.F
ormat(message)); | |
| 193 } | |
| 194 | |
| 195 [Test] | |
| 196 public void NullValueForMessage() | |
| 197 { | |
| 198 var message = new TestMap { MapInt32ForeignMessage = { { 10, null }
} }; | |
| 199 AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonForma
tter.Default.Format(message)); | |
| 200 } | |
| 201 | |
| 202 [Test] | |
| 203 [TestCase("a\u17b4b", "a\\u17b4b")] // Explicit | |
| 204 [TestCase("a\u0601b", "a\\u0601b")] // Ranged | |
| 205 [TestCase("a\u0605b", "a\u0605b")] // Passthrough (note lack of double b
ackslash...) | |
| 206 public void SimpleNonAscii(string text, string encoded) | |
| 207 { | |
| 208 var message = new TestAllTypes { SingleString = text }; | |
| 209 AssertJson("{ 'singleString': '" + encoded + "' }", JsonFormatter.De
fault.Format(message)); | |
| 210 } | |
| 211 | |
| 212 [Test] | |
| 213 public void SurrogatePairEscaping() | |
| 214 { | |
| 215 var message = new TestAllTypes { SingleString = "a\uD801\uDC01b" }; | |
| 216 AssertJson("{ 'singleString': 'a\\ud801\\udc01b' }", JsonFormatter.D
efault.Format(message)); | |
| 217 } | |
| 218 | |
| 219 [Test] | |
| 220 public void InvalidSurrogatePairsFail() | |
| 221 { | |
| 222 // Note: don't use TestCase for these, as the strings can't be relia
bly represented | |
| 223 // See http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a
-string/ | |
| 224 | |
| 225 // Lone low surrogate | |
| 226 var message = new TestAllTypes { SingleString = "a\uDC01b" }; | |
| 227 Assert.Throws<ArgumentException>(() => JsonFormatter.Default.Format(
message)); | |
| 228 | |
| 229 // Lone high surrogate | |
| 230 message = new TestAllTypes { SingleString = "a\uD801b" }; | |
| 231 Assert.Throws<ArgumentException>(() => JsonFormatter.Default.Format(
message)); | |
| 232 } | |
| 233 | |
| 234 [Test] | |
| 235 [TestCase("foo_bar", "fooBar")] | |
| 236 [TestCase("bananaBanana", "bananaBanana")] | |
| 237 [TestCase("BANANABanana", "bananaBanana")] | |
| 238 public void ToCamelCase(string original, string expected) | |
| 239 { | |
| 240 Assert.AreEqual(expected, JsonFormatter.ToCamelCase(original)); | |
| 241 } | |
| 242 | |
| 243 [Test] | |
| 244 [TestCase(null, "{ }")] | |
| 245 [TestCase("x", "{ 'fooString': 'x' }")] | |
| 246 [TestCase("", "{ 'fooString': '' }")] | |
| 247 [TestCase(null, "{ }")] | |
| 248 public void Oneof(string fooStringValue, string expectedJson) | |
| 249 { | |
| 250 var message = new TestOneof(); | |
| 251 if (fooStringValue != null) | |
| 252 { | |
| 253 message.FooString = fooStringValue; | |
| 254 } | |
| 255 | |
| 256 // We should get the same result both with and without "format defau
lt values". | |
| 257 var formatter = new JsonFormatter(new JsonFormatter.Settings(false))
; | |
| 258 AssertJson(expectedJson, formatter.Format(message)); | |
| 259 formatter = new JsonFormatter(new JsonFormatter.Settings(true)); | |
| 260 AssertJson(expectedJson, formatter.Format(message)); | |
| 261 } | |
| 262 | |
| 263 [Test] | |
| 264 public void WrapperFormatting_Single() | |
| 265 { | |
| 266 // Just a few examples, handling both classes and value types, and | |
| 267 // default vs non-default values | |
| 268 var message = new TestWellKnownTypes | |
| 269 { | |
| 270 Int64Field = 10, | |
| 271 Int32Field = 0, | |
| 272 BytesField = ByteString.FromBase64("ABCD"), | |
| 273 StringField = "" | |
| 274 }; | |
| 275 var expectedJson = "{ 'int64Field': '10', 'int32Field': 0, 'stringFi
eld': '', 'bytesField': 'ABCD' }"; | |
| 276 AssertJson(expectedJson, JsonFormatter.Default.Format(message)); | |
| 277 } | |
| 278 | |
| 279 [Test] | |
| 280 public void WrapperFormatting_IncludeNull() | |
| 281 { | |
| 282 // The actual JSON here is very large because there are lots of fiel
ds. Just test a couple of them. | |
| 283 var message = new TestWellKnownTypes { Int32Field = 10 }; | |
| 284 var formatter = new JsonFormatter(new JsonFormatter.Settings(true)); | |
| 285 var actualJson = formatter.Format(message); | |
| 286 Assert.IsTrue(actualJson.Contains("\"int64Field\": null")); | |
| 287 Assert.IsFalse(actualJson.Contains("\"int32Field\": null")); | |
| 288 } | |
| 289 | |
| 290 [Test] | |
| 291 public void OutputIsInNumericFieldOrder_NoDefaults() | |
| 292 { | |
| 293 var formatter = new JsonFormatter(new JsonFormatter.Settings(false))
; | |
| 294 var message = new TestJsonFieldOrdering { PlainString = "p1", PlainI
nt32 = 2 }; | |
| 295 AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.For
mat(message)); | |
| 296 message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2",
PlainInt32 = 10, PlainString = "plain" }; | |
| 297 AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32'
: 10, 'o1Int32': 5 }", formatter.Format(message)); | |
| 298 message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, Pl
ainInt32 = 10, PlainString = "plain" }; | |
| 299 AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32':
10, 'o2Int32': 0 }", formatter.Format(message)); | |
| 300 } | |
| 301 | |
| 302 [Test] | |
| 303 public void OutputIsInNumericFieldOrder_WithDefaults() | |
| 304 { | |
| 305 var formatter = new JsonFormatter(new JsonFormatter.Settings(true)); | |
| 306 var message = new TestJsonFieldOrdering(); | |
| 307 AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Forma
t(message)); | |
| 308 message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2",
PlainInt32 = 10, PlainString = "plain" }; | |
| 309 AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32'
: 10, 'o1Int32': 5 }", formatter.Format(message)); | |
| 310 message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, Pl
ainInt32 = 10, PlainString = "plain" }; | |
| 311 AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32':
10, 'o2Int32': 0 }", formatter.Format(message)); | |
| 312 } | |
| 313 | |
| 314 [Test] | |
| 315 public void TimestampStandalone() | |
| 316 { | |
| 317 Assert.AreEqual("1970-01-01T00:00:00Z", new Timestamp().ToString()); | |
| 318 Assert.AreEqual("1970-01-01T00:00:00.100Z", new Timestamp { Nanos =
100000000 }.ToString()); | |
| 319 Assert.AreEqual("1970-01-01T00:00:00.120Z", new Timestamp { Nanos =
120000000 }.ToString()); | |
| 320 Assert.AreEqual("1970-01-01T00:00:00.123Z", new Timestamp { Nanos =
123000000 }.ToString()); | |
| 321 Assert.AreEqual("1970-01-01T00:00:00.123400Z", new Timestamp { Nanos
= 123400000 }.ToString()); | |
| 322 Assert.AreEqual("1970-01-01T00:00:00.123450Z", new Timestamp { Nanos
= 123450000 }.ToString()); | |
| 323 Assert.AreEqual("1970-01-01T00:00:00.123456Z", new Timestamp { Nanos
= 123456000 }.ToString()); | |
| 324 Assert.AreEqual("1970-01-01T00:00:00.123456700Z", new Timestamp { Na
nos = 123456700 }.ToString()); | |
| 325 Assert.AreEqual("1970-01-01T00:00:00.123456780Z", new Timestamp { Na
nos = 123456780 }.ToString()); | |
| 326 Assert.AreEqual("1970-01-01T00:00:00.123456789Z", new Timestamp { Na
nos = 123456789 }.ToString()); | |
| 327 | |
| 328 // One before and one after the Unix epoch | |
| 329 Assert.AreEqual("1673-06-19T12:34:56Z", | |
| 330 new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimest
amp().ToString()); | |
| 331 Assert.AreEqual("2015-07-31T10:29:34Z", | |
| 332 new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimest
amp().ToString()); | |
| 333 } | |
| 334 | |
| 335 [Test] | |
| 336 public void TimestampField() | |
| 337 { | |
| 338 var message = new TestWellKnownTypes { TimestampField = new Timestam
p() }; | |
| 339 AssertJson("{ 'timestampField': '1970-01-01T00:00:00Z' }", JsonForma
tter.Default.Format(message)); | |
| 340 } | |
| 341 | |
| 342 [Test] | |
| 343 [TestCase(0, 0, "0s")] | |
| 344 [TestCase(1, 0, "1s")] | |
| 345 [TestCase(-1, 0, "-1s")] | |
| 346 [TestCase(0, 100000000, "0.100s")] | |
| 347 [TestCase(0, 120000000, "0.120s")] | |
| 348 [TestCase(0, 123000000, "0.123s")] | |
| 349 [TestCase(0, 123400000, "0.123400s")] | |
| 350 [TestCase(0, 123450000, "0.123450s")] | |
| 351 [TestCase(0, 123456000, "0.123456s")] | |
| 352 [TestCase(0, 123456700, "0.123456700s")] | |
| 353 [TestCase(0, 123456780, "0.123456780s")] | |
| 354 [TestCase(0, 123456789, "0.123456789s")] | |
| 355 [TestCase(0, -100000000, "-0.100s")] | |
| 356 [TestCase(1, 100000000, "1.100s")] | |
| 357 [TestCase(-1, -100000000, "-1.100s")] | |
| 358 // Non-normalized examples | |
| 359 [TestCase(1, 2123456789, "3.123456789s")] | |
| 360 [TestCase(1, -100000000, "0.900s")] | |
| 361 public void DurationStandalone(long seconds, int nanoseconds, string exp
ected) | |
| 362 { | |
| 363 Assert.AreEqual(expected, new Duration { Seconds = seconds, Nanos =
nanoseconds }.ToString()); | |
| 364 } | |
| 365 | |
| 366 [Test] | |
| 367 public void DurationField() | |
| 368 { | |
| 369 var message = new TestWellKnownTypes { DurationField = new Duration(
) }; | |
| 370 AssertJson("{ 'durationField': '0s' }", JsonFormatter.Default.Format
(message)); | |
| 371 } | |
| 372 | |
| 373 [Test] | |
| 374 public void StructSample() | |
| 375 { | |
| 376 var message = new Struct | |
| 377 { | |
| 378 Fields = | |
| 379 { | |
| 380 { "a", new Value { NullValue = new NullValue() } }, | |
| 381 { "b", new Value { BoolValue = false } }, | |
| 382 { "c", new Value { NumberValue = 10.5 } }, | |
| 383 { "d", new Value { StringValue = "text" } }, | |
| 384 { "e", new Value { ListValue = new ListValue { Values = { ne
w Value { StringValue = "t1" }, new Value { NumberValue = 5 } } } } }, | |
| 385 { "f", new Value { StructValue = new Struct { Fields = { { "
nested", new Value { StringValue = "value" } } } } } } | |
| 386 } | |
| 387 }; | |
| 388 AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [
't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString()); | |
| 389 } | |
| 390 | |
| 391 [Test] | |
| 392 public void FieldMaskStandalone() | |
| 393 { | |
| 394 var fieldMask = new FieldMask { Paths = { "", "single", "with_unders
core", "nested.field.name", "nested..double_dot" } }; | |
| 395 Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..do
ubleDot", fieldMask.ToString()); | |
| 396 | |
| 397 // Invalid, but we shouldn't create broken JSON... | |
| 398 fieldMask = new FieldMask { Paths = { "x\\y" } }; | |
| 399 Assert.AreEqual(@"x\\y", fieldMask.ToString()); | |
| 400 } | |
| 401 | |
| 402 [Test] | |
| 403 public void FieldMaskField() | |
| 404 { | |
| 405 var message = new TestWellKnownTypes { FieldMaskField = new FieldMas
k { Paths = { "user.display_name", "photo" } } }; | |
| 406 AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFor
matter.Default.Format(message)); | |
| 407 } | |
| 408 | |
| 409 /// <summary> | |
| 410 /// Checks that the actual JSON is the same as the expected JSON - but a
fter replacing | |
| 411 /// all apostrophes in the expected JSON with double quotes. This basica
lly makes the tests easier | |
| 412 /// to read. | |
| 413 /// </summary> | |
| 414 private static void AssertJson(string expectedJsonWithApostrophes, strin
g actualJson) | |
| 415 { | |
| 416 var expectedJson = expectedJsonWithApostrophes.Replace("'", "\""); | |
| 417 Assert.AreEqual(expectedJson, actualJson); | |
| 418 } | |
| 419 } | |
| 420 } | |
| OLD | NEW |