Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: third_party/protobuf/csharp/src/Google.Protobuf.Test/JsonParserTest.cs

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 Google.Protobuf.Reflection;
34 using Google.Protobuf.TestProtos;
35 using Google.Protobuf.WellKnownTypes;
36 using NUnit.Framework;
37 using System;
38
39 namespace Google.Protobuf
40 {
41 /// <summary>
42 /// Unit tests for JSON parsing. Some tests are ignored at the moment as the desired behaviour
43 /// isn't fully known, either in terms of which exceptions should be thrown or whether they should
44 /// count as valid values.
45 /// </summary>
46 public class JsonParserTest
47 {
48 // Sanity smoke test
49 [Test]
50 public void AllTypesRoundtrip()
51 {
52 AssertRoundtrip(SampleMessages.CreateFullTestAllTypes());
53 }
54
55 [Test]
56 public void Maps()
57 {
58 AssertRoundtrip(new TestMap { MapStringString = { { "with spaces", " bar" }, { "a", "b" } } });
59 AssertRoundtrip(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } });
60 AssertRoundtrip(new TestMap { MapBoolBool = { { false, true }, { tru e, false } } });
61 }
62
63 [Test]
64 [TestCase(" 1 ")]
65 [TestCase("+1")]
66 [TestCase("1,000")]
67 [TestCase("1.5")]
68 public void IntegerMapKeysAreStrict(string keyText)
69 {
70 // Test that integer parsing is strict. We assume that if this is co rrect for int32,
71 // it's correct for other numeric key types.
72 var json = "{ \"mapInt32Int32\": { \"" + keyText + "\" : \"1\" } }";
73 Assert.Throws<InvalidProtocolBufferException>(() => JsonParser.Defau lt.Parse<TestMap>(json));
74 }
75
76 [Test]
77 public void SourceContextRoundtrip()
78 {
79 AssertRoundtrip(new SourceContext { FileName = "foo.proto" });
80 }
81
82 [Test]
83 public void SingularWrappers_DefaultNonNullValues()
84 {
85 var message = new TestWellKnownTypes
86 {
87 StringField = "",
88 BytesField = ByteString.Empty,
89 BoolField = false,
90 FloatField = 0f,
91 DoubleField = 0d,
92 Int32Field = 0,
93 Int64Field = 0,
94 Uint32Field = 0,
95 Uint64Field = 0
96 };
97 AssertRoundtrip(message);
98 }
99
100 [Test]
101 public void SingularWrappers_NonDefaultValues()
102 {
103 var message = new TestWellKnownTypes
104 {
105 StringField = "x",
106 BytesField = ByteString.CopyFrom(1, 2, 3),
107 BoolField = true,
108 FloatField = 12.5f,
109 DoubleField = 12.25d,
110 Int32Field = 1,
111 Int64Field = 2,
112 Uint32Field = 3,
113 Uint64Field = 4
114 };
115 AssertRoundtrip(message);
116 }
117
118 [Test]
119 public void SingularWrappers_ExplicitNulls()
120 {
121 var message = new TestWellKnownTypes();
122 var json = new JsonFormatter(new JsonFormatter.Settings(true)).Forma t(message);
123 var parsed = JsonParser.Default.Parse<TestWellKnownTypes>(json);
124 Assert.AreEqual(message, parsed);
125 }
126
127 [Test]
128 [TestCase(typeof(Int32Value), "32", 32)]
129 [TestCase(typeof(Int64Value), "32", 32L)]
130 [TestCase(typeof(UInt32Value), "32", 32U)]
131 [TestCase(typeof(UInt64Value), "32", 32UL)]
132 [TestCase(typeof(StringValue), "\"foo\"", "foo")]
133 [TestCase(typeof(FloatValue), "1.5", 1.5f)]
134 [TestCase(typeof(DoubleValue), "1.5", 1.5d)]
135 public void Wrappers_Standalone(System.Type wrapperType, string json, ob ject expectedValue)
136 {
137 IMessage parsed = (IMessage) Activator.CreateInstance(wrapperType);
138 IMessage expected = (IMessage) Activator.CreateInstance(wrapperType) ;
139 JsonParser.Default.Merge(parsed, "null");
140 Assert.AreEqual(expected, parsed);
141
142 JsonParser.Default.Merge(parsed, json);
143 expected.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumbe r].Accessor.SetValue(expected, expectedValue);
144 Assert.AreEqual(expected, parsed);
145 }
146
147 [Test]
148 public void BytesWrapper_Standalone()
149 {
150 ByteString data = ByteString.CopyFrom(1, 2, 3);
151 // Can't do this with attributes...
152 var parsed = JsonParser.Default.Parse<BytesValue>("\"" + data.ToBase 64() + "\"");
153 var expected = new BytesValue { Value = data };
154 Assert.AreEqual(expected, parsed);
155 }
156
157 [Test]
158 public void RepeatedWrappers()
159 {
160 var message = new RepeatedWellKnownTypes
161 {
162 BoolField = { true, false },
163 BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom (4, 5, 6), ByteString.Empty },
164 DoubleField = { 12.5, -1.5, 0d },
165 FloatField = { 123.25f, -20f, 0f },
166 Int32Field = { int.MaxValue, int.MinValue, 0 },
167 Int64Field = { long.MaxValue, long.MinValue, 0L },
168 StringField = { "First", "Second", "" },
169 Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
170 Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
171 };
172 AssertRoundtrip(message);
173 }
174
175 [Test]
176 public void IndividualWrapperTypes()
177 {
178 Assert.AreEqual(new StringValue { Value = "foo" }, StringValue.Parse r.ParseJson("\"foo\""));
179 Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.Pars eJson("1"));
180 // Can parse strings directly too
181 Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.Pars eJson("\"1\""));
182 }
183
184 private static void AssertRoundtrip<T>(T message) where T : IMessage<T>, new()
185 {
186 var clone = message.Clone();
187 var json = message.ToString();
188 var parsed = JsonParser.Default.Parse<T>(json);
189 Assert.AreEqual(clone, parsed);
190 }
191
192 [Test]
193 [TestCase("0", 0)]
194 [TestCase("-0", 0)] // Not entirely clear whether we intend to allow thi s...
195 [TestCase("1", 1)]
196 [TestCase("-1", -1)]
197 [TestCase("2147483647", 2147483647)]
198 [TestCase("-2147483648", -2147483648)]
199 public void StringToInt32_Valid(string jsonValue, int expectedParsedValu e)
200 {
201 string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
202 var parsed = TestAllTypes.Parser.ParseJson(json);
203 Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
204 }
205
206 [Test]
207 [TestCase("+0")]
208 [TestCase("00")]
209 [TestCase("-00")]
210 [TestCase("--1")]
211 [TestCase("+1")]
212 [TestCase("1.5")]
213 [TestCase("1e10")]
214 [TestCase("2147483648")]
215 [TestCase("-2147483649")]
216 public void StringToInt32_Invalid(string jsonValue)
217 {
218 string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
219 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
220 }
221
222 [Test]
223 [TestCase("0", 0U)]
224 [TestCase("1", 1U)]
225 [TestCase("4294967295", 4294967295U)]
226 public void StringToUInt32_Valid(string jsonValue, uint expectedParsedVa lue)
227 {
228 string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
229 var parsed = TestAllTypes.Parser.ParseJson(json);
230 Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
231 }
232
233 // Assume that anything non-bounds-related is covered in the Int32 case
234 [Test]
235 [TestCase("-1")]
236 [TestCase("4294967296")]
237 public void StringToUInt32_Invalid(string jsonValue)
238 {
239 string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
240 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
241 }
242
243 [Test]
244 [TestCase("0", 0L)]
245 [TestCase("1", 1L)]
246 [TestCase("-1", -1L)]
247 [TestCase("9223372036854775807", 9223372036854775807)]
248 [TestCase("-9223372036854775808", -9223372036854775808)]
249 public void StringToInt64_Valid(string jsonValue, long expectedParsedVal ue)
250 {
251 string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
252 var parsed = TestAllTypes.Parser.ParseJson(json);
253 Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
254 }
255
256 // Assume that anything non-bounds-related is covered in the Int32 case
257 [Test]
258 [TestCase("-9223372036854775809")]
259 [TestCase("9223372036854775808")]
260 public void StringToInt64_Invalid(string jsonValue)
261 {
262 string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
263 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
264 }
265
266 [Test]
267 [TestCase("0", 0UL)]
268 [TestCase("1", 1UL)]
269 [TestCase("18446744073709551615", 18446744073709551615)]
270 public void StringToUInt64_Valid(string jsonValue, ulong expectedParsedV alue)
271 {
272 string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
273 var parsed = TestAllTypes.Parser.ParseJson(json);
274 Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
275 }
276
277 // Assume that anything non-bounds-related is covered in the Int32 case
278 [Test]
279 [TestCase("-1")]
280 [TestCase("18446744073709551616")]
281 public void StringToUInt64_Invalid(string jsonValue)
282 {
283 string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
284 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
285 }
286
287 [Test]
288 [TestCase("0", 0d)]
289 [TestCase("1", 1d)]
290 [TestCase("1.000000", 1d)]
291 [TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
292 [TestCase("-1", -1d)]
293 [TestCase("1e1", 10d)]
294 [TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
295 [TestCase("1E1", 10d)] // Either case is fine
296 [TestCase("-1e1", -10d)]
297 [TestCase("1.5e1", 15d)]
298 [TestCase("-1.5e1", -15d)]
299 [TestCase("15e-1", 1.5d)]
300 [TestCase("-15e-1", -1.5d)]
301 [TestCase("1.79769e308", 1.79769e308)]
302 [TestCase("-1.79769e308", -1.79769e308)]
303 [TestCase("Infinity", double.PositiveInfinity)]
304 [TestCase("-Infinity", double.NegativeInfinity)]
305 [TestCase("NaN", double.NaN)]
306 public void StringToDouble_Valid(string jsonValue, double expectedParsed Value)
307 {
308 string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
309 var parsed = TestAllTypes.Parser.ParseJson(json);
310 Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
311 }
312
313 [Test]
314 [TestCase("1.7977e308")]
315 [TestCase("-1.7977e308")]
316 [TestCase("1e309")]
317 [TestCase("1,0")]
318 [TestCase("1.0.0")]
319 [TestCase("+1")]
320 [TestCase("00")]
321 [TestCase("--1")]
322 [TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity c hecking...
323 public void StringToDouble_Invalid(string jsonValue)
324 {
325 string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
326 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
327 }
328
329 [Test]
330 [TestCase("0", 0f)]
331 [TestCase("1", 1f)]
332 [TestCase("1.000000", 1f)]
333 [TestCase("-1", -1f)]
334 [TestCase("3.402823e38", 3.402823e38f)]
335 [TestCase("-3.402823e38", -3.402823e38f)]
336 [TestCase("1.5e1", 15f)]
337 [TestCase("15e-1", 1.5f)]
338 public void StringToFloat_Valid(string jsonValue, float expectedParsedVa lue)
339 {
340 string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
341 var parsed = TestAllTypes.Parser.ParseJson(json);
342 Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
343 }
344
345 [Test]
346 [TestCase("3.402824e38")]
347 [TestCase("-3.402824e38")]
348 [TestCase("1,0")]
349 [TestCase("1.0.0")]
350 [TestCase("+1")]
351 [TestCase("00")]
352 [TestCase("--1")]
353 public void StringToFloat_Invalid(string jsonValue)
354 {
355 string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
356 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
357 }
358
359 [Test]
360 [TestCase("0", 0)]
361 [TestCase("-0", 0)] // Not entirely clear whether we intend to allow thi s...
362 [TestCase("1", 1)]
363 [TestCase("-1", -1)]
364 [TestCase("2147483647", 2147483647)]
365 [TestCase("-2147483648", -2147483648)]
366 public void NumberToInt32_Valid(string jsonValue, int expectedParsedValu e)
367 {
368 string json = "{ \"singleInt32\": " + jsonValue + "}";
369 var parsed = TestAllTypes.Parser.ParseJson(json);
370 Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
371 }
372
373 [Test]
374 [TestCase("+0", typeof(InvalidJsonException))]
375 [TestCase("00", typeof(InvalidJsonException))]
376 [TestCase("-00", typeof(InvalidJsonException))]
377 [TestCase("--1", typeof(InvalidJsonException))]
378 [TestCase("+1", typeof(InvalidJsonException))]
379 [TestCase("1.5", typeof(InvalidProtocolBufferException), Ignore = true, Reason = "Desired behaviour unclear")]
380 [TestCase("1e10", typeof(InvalidProtocolBufferException))]
381 [TestCase("2147483648", typeof(InvalidProtocolBufferException))]
382 [TestCase("-2147483649", typeof(InvalidProtocolBufferException))]
383 public void NumberToInt32_Invalid(string jsonValue, System.Type expected ExceptionType)
384 {
385 string json = "{ \"singleInt32\": " + jsonValue + "}";
386 Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.Parse Json(json));
387 }
388
389 [Test]
390 [TestCase("0", 0U)]
391 [TestCase("1", 1U)]
392 [TestCase("4294967295", 4294967295U)]
393 public void NumberToUInt32_Valid(string jsonValue, uint expectedParsedVa lue)
394 {
395 string json = "{ \"singleUint32\": " + jsonValue + "}";
396 var parsed = TestAllTypes.Parser.ParseJson(json);
397 Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
398 }
399
400 // Assume that anything non-bounds-related is covered in the Int32 case
401 [Test]
402 [TestCase("-1")]
403 [TestCase("4294967296")]
404 public void NumberToUInt32_Invalid(string jsonValue)
405 {
406 string json = "{ \"singleUint32\": " + jsonValue + "}";
407 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
408 }
409
410 [Test]
411 [TestCase("0", 0L)]
412 [TestCase("1", 1L)]
413 [TestCase("-1", -1L)]
414 [TestCase("9223372036854775807", 9223372036854775807, Ignore = true, Rea son = "Desired behaviour unclear")]
415 [TestCase("-9223372036854775808", -9223372036854775808, Ignore = true, R eason = "Desired behaviour unclear")]
416 public void NumberToInt64_Valid(string jsonValue, long expectedParsedVal ue)
417 {
418 string json = "{ \"singleInt64\": " + jsonValue + "}";
419 var parsed = TestAllTypes.Parser.ParseJson(json);
420 Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
421 }
422
423 // Assume that anything non-bounds-related is covered in the Int32 case
424 [Test]
425 [TestCase("-9223372036854775809", Ignore = true, Reason = "Desired behav iour unclear")]
426 [TestCase("9223372036854775808", Ignore = true, Reason = "Desired behavi our unclear")]
427 public void NumberToInt64_Invalid(string jsonValue)
428 {
429 string json = "{ \"singleInt64\": " + jsonValue + "}";
430 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
431 }
432
433 [Test]
434 [TestCase("0", 0UL)]
435 [TestCase("1", 1UL)]
436 [TestCase("18446744073709551615", 18446744073709551615, Ignore = true, R eason = "Desired behaviour unclear")]
437 public void NumberToUInt64_Valid(string jsonValue, ulong expectedParsedV alue)
438 {
439 string json = "{ \"singleUint64\": " + jsonValue + "}";
440 var parsed = TestAllTypes.Parser.ParseJson(json);
441 Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
442 }
443
444 // Assume that anything non-bounds-related is covered in the Int32 case
445 [Test]
446 [TestCase("-1")]
447 [TestCase("18446744073709551616")]
448 public void NumberToUInt64_Invalid(string jsonValue)
449 {
450 string json = "{ \"singleUint64\": " + jsonValue + "}";
451 Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Par ser.ParseJson(json));
452 }
453
454 [Test]
455 [TestCase("0", 0d)]
456 [TestCase("1", 1d)]
457 [TestCase("1.000000", 1d)]
458 [TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
459 [TestCase("-1", -1d)]
460 [TestCase("1e1", 10d)]
461 [TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
462 [TestCase("1E1", 10d)] // Either case is fine
463 [TestCase("-1e1", -10d)]
464 [TestCase("1.5e1", 15d)]
465 [TestCase("-1.5e1", -15d)]
466 [TestCase("15e-1", 1.5d)]
467 [TestCase("-15e-1", -1.5d)]
468 [TestCase("1.79769e308", 1.79769e308)]
469 [TestCase("-1.79769e308", -1.79769e308)]
470 public void NumberToDouble_Valid(string jsonValue, double expectedParsed Value)
471 {
472 string json = "{ \"singleDouble\": " + jsonValue + "}";
473 var parsed = TestAllTypes.Parser.ParseJson(json);
474 Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
475 }
476
477 [Test]
478 [TestCase("1.7977e308", Ignore = true, Reason = "Desired behaviour uncle ar")]
479 [TestCase("-1.7977e308", Ignore = true, Reason = "Desired behaviour uncl ear")]
480 [TestCase("1e309", Ignore = true, Reason = "Desired behaviour unclear")]
481 [TestCase("1,0")]
482 [TestCase("1.0.0")]
483 [TestCase("+1")]
484 [TestCase("00")]
485 [TestCase("--1")]
486 [TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity c hecking...
487 public void NumberToDouble_Invalid(string jsonValue)
488 {
489 string json = "{ \"singleDouble\": " + jsonValue + "}";
490 Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJ son(json));
491 }
492
493 [Test]
494 [TestCase("0", 0f)]
495 [TestCase("1", 1f)]
496 [TestCase("1.000000", 1f)]
497 [TestCase("-1", -1f)]
498 [TestCase("3.402823e38", 3.402823e38f)]
499 [TestCase("-3.402823e38", -3.402823e38f)]
500 [TestCase("1.5e1", 15f)]
501 [TestCase("15e-1", 1.5f)]
502 public void NumberToFloat_Valid(string jsonValue, float expectedParsedVa lue)
503 {
504 string json = "{ \"singleFloat\": " + jsonValue + "}";
505 var parsed = TestAllTypes.Parser.ParseJson(json);
506 Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
507 }
508
509 [Test]
510 [TestCase("3.402824e38", typeof(InvalidProtocolBufferException))]
511 [TestCase("-3.402824e38", typeof(InvalidProtocolBufferException))]
512 [TestCase("1,0", typeof(InvalidJsonException))]
513 [TestCase("1.0.0", typeof(InvalidJsonException))]
514 [TestCase("+1", typeof(InvalidJsonException))]
515 [TestCase("00", typeof(InvalidJsonException))]
516 [TestCase("--1", typeof(InvalidJsonException))]
517 public void NumberToFloat_Invalid(string jsonValue, System.Type expected ExceptionType)
518 {
519 string json = "{ \"singleFloat\": " + jsonValue + "}";
520 Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.Parse Json(json));
521 }
522
523 // The simplest way of testing that the value has parsed correctly is to reformat it,
524 // as we trust the formatting. In many cases that will give the same res ult as the input,
525 // so in those cases we accept an expectedFormatted value of null. Somet imes the results
526 // will be different though, due to a different number of digits being p rovided.
527 [Test]
528 // Z offset
529 [TestCase("2015-10-09T14:46:23.123456789Z", null)]
530 [TestCase("2015-10-09T14:46:23.123456Z", null)]
531 [TestCase("2015-10-09T14:46:23.123Z", null)]
532 [TestCase("2015-10-09T14:46:23Z", null)]
533 [TestCase("2015-10-09T14:46:23.123456000Z", "2015-10-09T14:46:23.123456Z ")]
534 [TestCase("2015-10-09T14:46:23.1234560Z", "2015-10-09T14:46:23.123456Z") ]
535 [TestCase("2015-10-09T14:46:23.123000000Z", "2015-10-09T14:46:23.123Z")]
536 [TestCase("2015-10-09T14:46:23.1230Z", "2015-10-09T14:46:23.123Z")]
537 [TestCase("2015-10-09T14:46:23.00Z", "2015-10-09T14:46:23Z")]
538
539 // +00:00 offset
540 [TestCase("2015-10-09T14:46:23.123456789+00:00", "2015-10-09T14:46:23.12 3456789Z")]
541 [TestCase("2015-10-09T14:46:23.123456+00:00", "2015-10-09T14:46:23.12345 6Z")]
542 [TestCase("2015-10-09T14:46:23.123+00:00", "2015-10-09T14:46:23.123Z")]
543 [TestCase("2015-10-09T14:46:23+00:00", "2015-10-09T14:46:23Z")]
544 [TestCase("2015-10-09T14:46:23.123456000+00:00", "2015-10-09T14:46:23.12 3456Z")]
545 [TestCase("2015-10-09T14:46:23.1234560+00:00", "2015-10-09T14:46:23.1234 56Z")]
546 [TestCase("2015-10-09T14:46:23.123000000+00:00", "2015-10-09T14:46:23.12 3Z")]
547 [TestCase("2015-10-09T14:46:23.1230+00:00", "2015-10-09T14:46:23.123Z")]
548 [TestCase("2015-10-09T14:46:23.00+00:00", "2015-10-09T14:46:23Z")]
549
550 // Other offsets (assume by now that the subsecond handling is okay)
551 [TestCase("2015-10-09T15:46:23.123456789+01:00", "2015-10-09T14:46:23.12 3456789Z")]
552 [TestCase("2015-10-09T13:46:23.123456789-01:00", "2015-10-09T14:46:23.12 3456789Z")]
553 [TestCase("2015-10-09T15:16:23.123456789+00:30", "2015-10-09T14:46:23.12 3456789Z")]
554 [TestCase("2015-10-09T14:16:23.123456789-00:30", "2015-10-09T14:46:23.12 3456789Z")]
555 [TestCase("2015-10-09T16:31:23.123456789+01:45", "2015-10-09T14:46:23.12 3456789Z")]
556 [TestCase("2015-10-09T13:01:23.123456789-01:45", "2015-10-09T14:46:23.12 3456789Z")]
557 [TestCase("2015-10-10T08:46:23.123456789+18:00", "2015-10-09T14:46:23.12 3456789Z")]
558 [TestCase("2015-10-08T20:46:23.123456789-18:00", "2015-10-09T14:46:23.12 3456789Z")]
559
560 // Leap years and min/max
561 [TestCase("2016-02-29T14:46:23.123456789Z", null)]
562 [TestCase("2000-02-29T14:46:23.123456789Z", null)]
563 [TestCase("0001-01-01T00:00:00Z", null)]
564 [TestCase("9999-12-31T23:59:59.999999999Z", null)]
565 public void Timestamp_Valid(string jsonValue, string expectedFormatted)
566 {
567 expectedFormatted = expectedFormatted ?? jsonValue;
568 string json = "\"" + jsonValue + "\"";
569 var parsed = Timestamp.Parser.ParseJson(json);
570 Assert.AreEqual(expectedFormatted, parsed.ToString());
571 }
572
573 [Test]
574 [TestCase("2015-10-09 14:46:23.123456789Z", Description = "No T between date and time")]
575 [TestCase("2015/10/09T14:46:23.123456789Z", Description = "Wrong date se parators")]
576 [TestCase("2015-10-09T14.46.23.123456789Z", Description = "Wrong time se parators")]
577 [TestCase("2015-10-09T14:46:23,123456789Z", Description = "Wrong fractio nal second separators (valid ISO-8601 though)")]
578 [TestCase(" 2015-10-09T14:46:23.123456789Z", Description = "Whitespace a t start")]
579 [TestCase("2015-10-09T14:46:23.123456789Z ", Description = "Whitespace a t end")]
580 [TestCase("2015-10-09T14:46:23.1234567890", Description = "Too many digi ts")]
581 [TestCase("2015-10-09T14:46:23.123456789", Description = "No offset")]
582 [TestCase("2015-13-09T14:46:23.123456789Z", Description = "Invalid month ")]
583 [TestCase("2015-10-32T14:46:23.123456789Z", Description = "Invalid day") ]
584 [TestCase("2015-10-09T24:00:00.000000000Z", Description = "Invalid hour (valid ISO-8601 though)")]
585 [TestCase("2015-10-09T14:60:23.123456789Z", Description = "Invalid minut es")]
586 [TestCase("2015-10-09T14:46:60.123456789Z", Description = "Invalid secon ds")]
587 [TestCase("2015-10-09T14:46:23.123456789+18:01", Description = "Offset t oo large (positive)")]
588 [TestCase("2015-10-09T14:46:23.123456789-18:01", Description = "Offset t oo large (negative)")]
589 [TestCase("2015-10-09T14:46:23.123456789-00:00", Description = "Local of fset (-00:00) makes no sense here")]
590 [TestCase("0001-01-01T00:00:00+00:01", Description = "Value before earli est when offset applied")]
591 [TestCase("9999-12-31T23:59:59.999999999-00:01", Description = "Value af ter latest when offset applied")]
592 [TestCase("2100-02-29T14:46:23.123456789Z", Description = "Feb 29th on a non-leap-year")]
593 public void Timestamp_Invalid(string jsonValue)
594 {
595 string json = "\"" + jsonValue + "\"";
596 Assert.Throws<InvalidProtocolBufferException>(() => Timestamp.Parser .ParseJson(json));
597 }
598
599 [Test]
600 public void StructValue_Null()
601 {
602 Assert.AreEqual(new Value { NullValue = 0 }, Value.Parser.ParseJson( "null"));
603 }
604
605 [Test]
606 public void StructValue_String()
607 {
608 Assert.AreEqual(new Value { StringValue = "hi" }, Value.Parser.Parse Json("\"hi\""));
609 }
610
611 [Test]
612 public void StructValue_Bool()
613 {
614 Assert.AreEqual(new Value { BoolValue = true }, Value.Parser.ParseJs on("true"));
615 Assert.AreEqual(new Value { BoolValue = false }, Value.Parser.ParseJ son("false"));
616 }
617
618 [Test]
619 public void StructValue_List()
620 {
621 Assert.AreEqual(Value.ForList(Value.ForNumber(1), Value.ForString("x ")), Value.Parser.ParseJson("[1, \"x\"]"));
622 }
623
624 [Test]
625 public void ParseListValue()
626 {
627 Assert.AreEqual(new ListValue { Values = { Value.ForNumber(1), Value .ForString("x") } }, ListValue.Parser.ParseJson("[1, \"x\"]"));
628 }
629
630 [Test]
631 public void StructValue_Struct()
632 {
633 Assert.AreEqual(
634 Value.ForStruct(new Struct { Fields = { { "x", Value.ForNumber(1 ) }, { "y", Value.ForString("z") } } }),
635 Value.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
636 }
637
638 [Test]
639 public void ParseStruct()
640 {
641 Assert.AreEqual(new Struct { Fields = { { "x", Value.ForNumber(1) }, { "y", Value.ForString("z") } } },
642 Struct.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
643 }
644
645 // TODO for duration parsing: upper and lower bounds.
646 // +/- 315576000000 seconds
647
648 [Test]
649 [TestCase("1.123456789s", null)]
650 [TestCase("1.123456s", null)]
651 [TestCase("1.123s", null)]
652 [TestCase("1.12300s", "1.123s")]
653 [TestCase("1.12345s", "1.123450s")]
654 [TestCase("1s", null)]
655 [TestCase("-1.123456789s", null)]
656 [TestCase("-1.123456s", null)]
657 [TestCase("-1.123s", null)]
658 [TestCase("-1s", null)]
659 [TestCase("0.123s", null)]
660 [TestCase("-0.123s", null)]
661 [TestCase("123456.123s", null)]
662 [TestCase("-123456.123s", null)]
663 // Upper and lower bounds
664 [TestCase("315576000000s", null)]
665 [TestCase("-315576000000s", null)]
666 public void Duration_Valid(string jsonValue, string expectedFormatted)
667 {
668 expectedFormatted = expectedFormatted ?? jsonValue;
669 string json = "\"" + jsonValue + "\"";
670 var parsed = Duration.Parser.ParseJson(json);
671 Assert.AreEqual(expectedFormatted, parsed.ToString());
672 }
673
674 // The simplest way of testing that the value has parsed correctly is to reformat it,
675 // as we trust the formatting. In many cases that will give the same res ult as the input,
676 // so in those cases we accept an expectedFormatted value of null. Somet imes the results
677 // will be different though, due to a different number of digits being p rovided.
678 [Test]
679 [TestCase("1.1234567890s", Description = "Too many digits")]
680 [TestCase("1.123456789", Description = "No suffix")]
681 [TestCase("1.123456789ss", Description = "Too much suffix")]
682 [TestCase("1.123456789S", Description = "Upper case suffix")]
683 [TestCase("+1.123456789s", Description = "Leading +")]
684 [TestCase(".123456789s", Description = "No integer before the fraction") ]
685 [TestCase("1,123456789s", Description = "Comma as decimal separator")]
686 [TestCase("1x1.123456789s", Description = "Non-digit in integer part")]
687 [TestCase("1.1x3456789s", Description = "Non-digit in fractional part")]
688 [TestCase(" 1.123456789s", Description = "Whitespace before fraction")]
689 [TestCase("1.123456789s ", Description = "Whitespace after value")]
690 [TestCase("01.123456789s", Description = "Leading zero (positive)")]
691 [TestCase("-01.123456789s", Description = "Leading zero (negative)")]
692 [TestCase("--0.123456789s", Description = "Double minus sign")]
693 // Violate upper/lower bounds in various ways
694 [TestCase("315576000001s", Description = "Integer part too large")]
695 [TestCase("315576000000.000000001s", Description = "Integer part is uppe r bound; non-zero fraction")]
696 [TestCase("3155760000000s", Description = "Integer part too long (positi ve)")]
697 [TestCase("-3155760000000s", Description = "Integer part too long (negat ive)")]
698 public void Duration_Invalid(string jsonValue)
699 {
700 string json = "\"" + jsonValue + "\"";
701 Assert.Throws<InvalidProtocolBufferException>(() => Duration.Parser. ParseJson(json));
702 }
703
704 // Not as many tests for field masks as I'd like; more to be added when we have more
705 // detailed specifications.
706
707 [Test]
708 [TestCase("")]
709 [TestCase("foo", "foo")]
710 [TestCase("foo,bar", "foo", "bar")]
711 [TestCase("foo.bar", "foo.bar")]
712 [TestCase("fooBar", "foo_bar")]
713 [TestCase("fooBar.bazQux", "foo_bar.baz_qux")]
714 public void FieldMask_Valid(string jsonValue, params string[] expectedPa ths)
715 {
716 string json = "\"" + jsonValue + "\"";
717 var parsed = FieldMask.Parser.ParseJson(json);
718 CollectionAssert.AreEqual(expectedPaths, parsed.Paths);
719 }
720
721 [Test]
722 public void Any_RegularMessage()
723 {
724 var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
725 var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
726 var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessa ge = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
727 var original = Any.Pack(message);
728 var json = formatter.Format(original); // This is tested in JsonForm atterTest
729 var parser = new JsonParser(new JsonParser.Settings(10, registry));
730 Assert.AreEqual(original, parser.Parse<Any>(json));
731 string valueFirstJson = "{ \"singleInt32\": 10, \"singleNestedMessag e\": { \"bb\": 20 }, \"@type\": \"type.googleapis.com/protobuf_unittest.TestAllT ypes\" }";
732 Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
733 }
734
735 [Test]
736 public void Any_UnknownType()
737 {
738 string json = "{ \"@type\": \"type.googleapis.com/bogus\" }";
739 Assert.Throws<InvalidOperationException>(() => Any.Parser.ParseJson( json));
740 }
741
742 [Test]
743 public void Any_WellKnownType()
744 {
745 var registry = TypeRegistry.FromMessages(Timestamp.Descriptor);
746 var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
747 var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.U tc).ToTimestamp();
748 var original = Any.Pack(timestamp);
749 var json = formatter.Format(original); // This is tested in JsonForm atterTest
750 var parser = new JsonParser(new JsonParser.Settings(10, registry));
751 Assert.AreEqual(original, parser.Parse<Any>(json));
752 string valueFirstJson = "{ \"value\": \"1673-06-19T12:34:56Z\", \"@t ype\": \"type.googleapis.com/google.protobuf.Timestamp\" }";
753 Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
754 }
755
756 [Test]
757 public void Any_Nested()
758 {
759 var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descript or, TestAllTypes.Descriptor);
760 var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
761 var parser = new JsonParser(new JsonParser.Settings(10, registry));
762 var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };
763 var nestedMessage = Any.Pack(doubleNestedMessage);
764 var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMes sage) };
765 var json = formatter.Format(message);
766 // Use the descriptor-based parser just for a change.
767 Assert.AreEqual(message, parser.Parse(json, TestWellKnownTypes.Descr iptor));
768 }
769
770 [Test]
771 public void DataAfterObject()
772 {
773 string json = "{} 10";
774 Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJ son(json));
775 }
776
777 /// <summary>
778 /// JSON equivalent to <see cref="CodedInputStreamTest.MaliciousRecursio n"/>
779 /// </summary>
780 [Test]
781 public void MaliciousRecursion()
782 {
783 string data64 = CodedInputStreamTest.MakeRecursiveMessage(64).ToStri ng();
784 string data65 = CodedInputStreamTest.MakeRecursiveMessage(65).ToStri ng();
785
786 var parser64 = new JsonParser(new JsonParser.Settings(64));
787 CodedInputStreamTest.AssertMessageDepth(parser64.Parse<TestRecursive Message>(data64), 64);
788 Assert.Throws<InvalidProtocolBufferException>(() => parser64.Parse<T estRecursiveMessage>(data65));
789
790 var parser63 = new JsonParser(new JsonParser.Settings(63));
791 Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<T estRecursiveMessage>(data64));
792
793 }
794 }
795 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698