1 | #region Copyright notice and license
|
---|
2 | // Protocol Buffers - Google's data interchange format
|
---|
3 | // Copyright 2008 Google Inc. All rights reserved.
|
---|
4 | // http://github.com/jskeet/dotnet-protobufs/
|
---|
5 | // Original C++/Java/Python code:
|
---|
6 | // http://code.google.com/p/protobuf/
|
---|
7 | //
|
---|
8 | // Redistribution and use in source and binary forms, with or without
|
---|
9 | // modification, are permitted provided that the following conditions are
|
---|
10 | // met:
|
---|
11 | //
|
---|
12 | // * Redistributions of source code must retain the above copyright
|
---|
13 | // notice, this list of conditions and the following disclaimer.
|
---|
14 | // * Redistributions in binary form must reproduce the above
|
---|
15 | // copyright notice, this list of conditions and the following disclaimer
|
---|
16 | // in the documentation and/or other materials provided with the
|
---|
17 | // distribution.
|
---|
18 | // * Neither the name of Google Inc. nor the names of its
|
---|
19 | // contributors may be used to endorse or promote products derived from
|
---|
20 | // this software without specific prior written permission.
|
---|
21 | //
|
---|
22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
---|
23 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
---|
24 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
---|
25 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
---|
26 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
---|
27 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
---|
28 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
---|
29 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
---|
30 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
31 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
---|
32 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
33 | #endregion
|
---|
34 |
|
---|
35 | using System;
|
---|
36 | using System.IO;
|
---|
37 | using System.Text;
|
---|
38 | using Google.ProtocolBuffers.TestProtos;
|
---|
39 | using NUnit.Framework;
|
---|
40 | using System.Globalization;
|
---|
41 | using System.Threading;
|
---|
42 |
|
---|
43 | namespace Google.ProtocolBuffers {
|
---|
44 | [TestFixture]
|
---|
45 | public class TextFormatTest {
|
---|
46 |
|
---|
47 | private static readonly string AllFieldsSetText = TestUtil.ReadTextFromFile("text_format_unittest_data.txt");
|
---|
48 | private static readonly string AllExtensionsSetText = TestUtil.ReadTextFromFile("text_format_unittest_extensions_data.txt");
|
---|
49 |
|
---|
50 | /// <summary>
|
---|
51 | /// Note that this is slightly different to the Java - 123.0 becomes 123, and 1.23E17 becomes 1.23E+17.
|
---|
52 | /// Both of these differences can be parsed by the Java and the C++, and we can parse their output too.
|
---|
53 | /// </summary>
|
---|
54 | private const string ExoticText =
|
---|
55 | "repeated_int32: -1\n" +
|
---|
56 | "repeated_int32: -2147483648\n" +
|
---|
57 | "repeated_int64: -1\n" +
|
---|
58 | "repeated_int64: -9223372036854775808\n" +
|
---|
59 | "repeated_uint32: 4294967295\n" +
|
---|
60 | "repeated_uint32: 2147483648\n" +
|
---|
61 | "repeated_uint64: 18446744073709551615\n" +
|
---|
62 | "repeated_uint64: 9223372036854775808\n" +
|
---|
63 | "repeated_double: 123\n" +
|
---|
64 | "repeated_double: 123.5\n" +
|
---|
65 | "repeated_double: 0.125\n" +
|
---|
66 | "repeated_double: 1.23E+17\n" +
|
---|
67 | "repeated_double: 1.235E+22\n" +
|
---|
68 | "repeated_double: 1.235E-18\n" +
|
---|
69 | "repeated_double: 123.456789\n" +
|
---|
70 | "repeated_double: Infinity\n" +
|
---|
71 | "repeated_double: -Infinity\n" +
|
---|
72 | "repeated_double: NaN\n" +
|
---|
73 | "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
|
---|
74 | "\\341\\210\\264\"\n" +
|
---|
75 | "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
|
---|
76 |
|
---|
77 | private const string MessageSetText =
|
---|
78 | "[protobuf_unittest.TestMessageSetExtension1] {\n" +
|
---|
79 | " i: 123\n" +
|
---|
80 | "}\n" +
|
---|
81 | "[protobuf_unittest.TestMessageSetExtension2] {\n" +
|
---|
82 | " str: \"foo\"\n" +
|
---|
83 | "}\n";
|
---|
84 |
|
---|
85 | /// <summary>
|
---|
86 | /// Print TestAllTypes and compare with golden file.
|
---|
87 | /// </summary>
|
---|
88 | [Test]
|
---|
89 | public void PrintMessage() {
|
---|
90 | TestUtil.TestInMultipleCultures(() => {
|
---|
91 | string text = TextFormat.PrintToString(TestUtil.GetAllSet());
|
---|
92 | Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
|
---|
93 | });
|
---|
94 | }
|
---|
95 |
|
---|
96 | /// <summary>
|
---|
97 | /// Print TestAllExtensions and compare with golden file.
|
---|
98 | /// </summary>
|
---|
99 | [Test]
|
---|
100 | public void PrintExtensions() {
|
---|
101 | string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet());
|
---|
102 |
|
---|
103 | Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
|
---|
104 | }
|
---|
105 |
|
---|
106 | /// <summary>
|
---|
107 | /// Test printing of unknown fields in a message.
|
---|
108 | /// </summary>
|
---|
109 | [Test]
|
---|
110 | public void PrintUnknownFields() {
|
---|
111 | TestEmptyMessage message =
|
---|
112 | TestEmptyMessage.CreateBuilder()
|
---|
113 | .SetUnknownFields(
|
---|
114 | UnknownFieldSet.CreateBuilder()
|
---|
115 | .AddField(5,
|
---|
116 | UnknownField.CreateBuilder()
|
---|
117 | .AddVarint(1)
|
---|
118 | .AddFixed32(2)
|
---|
119 | .AddFixed64(3)
|
---|
120 | .AddLengthDelimited(ByteString.CopyFromUtf8("4"))
|
---|
121 | .AddGroup(
|
---|
122 | UnknownFieldSet.CreateBuilder()
|
---|
123 | .AddField(10,
|
---|
124 | UnknownField.CreateBuilder()
|
---|
125 | .AddVarint(5)
|
---|
126 | .Build())
|
---|
127 | .Build())
|
---|
128 | .Build())
|
---|
129 | .AddField(8,
|
---|
130 | UnknownField.CreateBuilder()
|
---|
131 | .AddVarint(1)
|
---|
132 | .AddVarint(2)
|
---|
133 | .AddVarint(3)
|
---|
134 | .Build())
|
---|
135 | .AddField(15,
|
---|
136 | UnknownField.CreateBuilder()
|
---|
137 | .AddVarint(0xABCDEF1234567890L)
|
---|
138 | .AddFixed32(0xABCD1234)
|
---|
139 | .AddFixed64(0xABCDEF1234567890L)
|
---|
140 | .Build())
|
---|
141 | .Build())
|
---|
142 | .Build();
|
---|
143 |
|
---|
144 | Assert.AreEqual(
|
---|
145 | "5: 1\n" +
|
---|
146 | "5: 0x00000002\n" +
|
---|
147 | "5: 0x0000000000000003\n" +
|
---|
148 | "5: \"4\"\n" +
|
---|
149 | "5 {\n" +
|
---|
150 | " 10: 5\n" +
|
---|
151 | "}\n" +
|
---|
152 | "8: 1\n" +
|
---|
153 | "8: 2\n" +
|
---|
154 | "8: 3\n" +
|
---|
155 | "15: 12379813812177893520\n" +
|
---|
156 | "15: 0xabcd1234\n" +
|
---|
157 | "15: 0xabcdef1234567890\n",
|
---|
158 | TextFormat.PrintToString(message));
|
---|
159 | }
|
---|
160 |
|
---|
161 | /// <summary>
|
---|
162 | /// Helper to construct a ByteString from a string containing only 8-bit
|
---|
163 | /// characters. The characters are converted directly to bytes, *not*
|
---|
164 | /// encoded using UTF-8.
|
---|
165 | /// </summary>
|
---|
166 | private static ByteString Bytes(string str) {
|
---|
167 | return ByteString.CopyFrom(Encoding.GetEncoding(28591).GetBytes(str));
|
---|
168 | }
|
---|
169 |
|
---|
170 | [Test]
|
---|
171 | public void PrintExotic() {
|
---|
172 | IMessage message = TestAllTypes.CreateBuilder()
|
---|
173 | // Signed vs. unsigned numbers.
|
---|
174 | .AddRepeatedInt32 (-1)
|
---|
175 | .AddRepeatedUint32(uint.MaxValue)
|
---|
176 | .AddRepeatedInt64 (-1)
|
---|
177 | .AddRepeatedUint64(ulong.MaxValue)
|
---|
178 |
|
---|
179 | .AddRepeatedInt32 (1 << 31)
|
---|
180 | .AddRepeatedUint32(1U << 31)
|
---|
181 | .AddRepeatedInt64 (1L << 63)
|
---|
182 | .AddRepeatedUint64(1UL << 63)
|
---|
183 |
|
---|
184 | // Floats of various precisions and exponents.
|
---|
185 | .AddRepeatedDouble(123)
|
---|
186 | .AddRepeatedDouble(123.5)
|
---|
187 | .AddRepeatedDouble(0.125)
|
---|
188 | .AddRepeatedDouble(123e15)
|
---|
189 | .AddRepeatedDouble(123.5e20)
|
---|
190 | .AddRepeatedDouble(123.5e-20)
|
---|
191 | .AddRepeatedDouble(123.456789)
|
---|
192 | .AddRepeatedDouble(Double.PositiveInfinity)
|
---|
193 | .AddRepeatedDouble(Double.NegativeInfinity)
|
---|
194 | .AddRepeatedDouble(Double.NaN)
|
---|
195 |
|
---|
196 | // Strings and bytes that needing escaping.
|
---|
197 | .AddRepeatedString("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u1234")
|
---|
198 | .AddRepeatedBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u00fe"))
|
---|
199 | .Build();
|
---|
200 |
|
---|
201 | Assert.AreEqual(ExoticText, message.ToString());
|
---|
202 | }
|
---|
203 |
|
---|
204 | [Test]
|
---|
205 | public void PrintMessageSet() {
|
---|
206 | TestMessageSet messageSet =
|
---|
207 | TestMessageSet.CreateBuilder()
|
---|
208 | .SetExtension(
|
---|
209 | TestMessageSetExtension1.MessageSetExtension,
|
---|
210 | TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
|
---|
211 | .SetExtension(
|
---|
212 | TestMessageSetExtension2.MessageSetExtension,
|
---|
213 | TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
|
---|
214 | .Build();
|
---|
215 |
|
---|
216 | Assert.AreEqual(MessageSetText, messageSet.ToString());
|
---|
217 | }
|
---|
218 |
|
---|
219 | // =================================================================
|
---|
220 |
|
---|
221 | [Test]
|
---|
222 | public void Parse() {
|
---|
223 | TestUtil.TestInMultipleCultures(() => {
|
---|
224 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
225 | TextFormat.Merge(AllFieldsSetText, builder);
|
---|
226 | TestUtil.AssertAllFieldsSet(builder.Build());
|
---|
227 | });
|
---|
228 | }
|
---|
229 |
|
---|
230 | [Test]
|
---|
231 | public void ParseReader() {
|
---|
232 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
233 | TextFormat.Merge(new StringReader(AllFieldsSetText), builder);
|
---|
234 | TestUtil.AssertAllFieldsSet(builder.Build());
|
---|
235 | }
|
---|
236 |
|
---|
237 | [Test]
|
---|
238 | public void ParseExtensions() {
|
---|
239 | TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
|
---|
240 | TextFormat.Merge(AllExtensionsSetText,
|
---|
241 | TestUtil.CreateExtensionRegistry(),
|
---|
242 | builder);
|
---|
243 | TestUtil.AssertAllExtensionsSet(builder.Build());
|
---|
244 | }
|
---|
245 |
|
---|
246 | [Test]
|
---|
247 | public void ParseCompatibility() {
|
---|
248 | string original = "repeated_float: inf\n" +
|
---|
249 | "repeated_float: -inf\n" +
|
---|
250 | "repeated_float: nan\n" +
|
---|
251 | "repeated_float: inff\n" +
|
---|
252 | "repeated_float: -inff\n" +
|
---|
253 | "repeated_float: nanf\n" +
|
---|
254 | "repeated_float: 1.0f\n" +
|
---|
255 | "repeated_float: infinityf\n" +
|
---|
256 | "repeated_float: -Infinityf\n" +
|
---|
257 | "repeated_double: infinity\n" +
|
---|
258 | "repeated_double: -infinity\n" +
|
---|
259 | "repeated_double: nan\n";
|
---|
260 | string canonical = "repeated_float: Infinity\n" +
|
---|
261 | "repeated_float: -Infinity\n" +
|
---|
262 | "repeated_float: NaN\n" +
|
---|
263 | "repeated_float: Infinity\n" +
|
---|
264 | "repeated_float: -Infinity\n" +
|
---|
265 | "repeated_float: NaN\n" +
|
---|
266 | "repeated_float: 1\n" + // Java has 1.0; this is fine
|
---|
267 | "repeated_float: Infinity\n" +
|
---|
268 | "repeated_float: -Infinity\n" +
|
---|
269 | "repeated_double: Infinity\n" +
|
---|
270 | "repeated_double: -Infinity\n" +
|
---|
271 | "repeated_double: NaN\n";
|
---|
272 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
273 | TextFormat.Merge(original, builder);
|
---|
274 | Assert.AreEqual(canonical, builder.Build().ToString());
|
---|
275 | }
|
---|
276 |
|
---|
277 | [Test]
|
---|
278 | public void ParseExotic() {
|
---|
279 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
280 | TextFormat.Merge(ExoticText, builder);
|
---|
281 |
|
---|
282 | // Too lazy to check things individually. Don't try to debug this
|
---|
283 | // if testPrintExotic() is Assert.Failing.
|
---|
284 | Assert.AreEqual(ExoticText, builder.Build().ToString());
|
---|
285 | }
|
---|
286 |
|
---|
287 | [Test]
|
---|
288 | public void ParseMessageSet() {
|
---|
289 | ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
|
---|
290 | extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
|
---|
291 | extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
|
---|
292 |
|
---|
293 | TestMessageSet.Builder builder = TestMessageSet.CreateBuilder();
|
---|
294 | TextFormat.Merge(MessageSetText, extensionRegistry, builder);
|
---|
295 | TestMessageSet messageSet = builder.Build();
|
---|
296 |
|
---|
297 | Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension1.MessageSetExtension));
|
---|
298 | Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
|
---|
299 | Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension2.MessageSetExtension));
|
---|
300 | Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
|
---|
301 | }
|
---|
302 |
|
---|
303 | [Test]
|
---|
304 | public void ParseNumericEnum() {
|
---|
305 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
306 | TextFormat.Merge("optional_nested_enum: 2", builder);
|
---|
307 | Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, builder.OptionalNestedEnum);
|
---|
308 | }
|
---|
309 |
|
---|
310 | [Test]
|
---|
311 | public void ParseAngleBrackets() {
|
---|
312 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
313 | TextFormat.Merge("OptionalGroup: < a: 1 >", builder);
|
---|
314 | Assert.IsTrue(builder.HasOptionalGroup);
|
---|
315 | Assert.AreEqual(1, builder.OptionalGroup.A);
|
---|
316 | }
|
---|
317 |
|
---|
318 | [Test]
|
---|
319 | public void ParseComment() {
|
---|
320 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
321 | TextFormat.Merge(
|
---|
322 | "# this is a comment\n" +
|
---|
323 | "optional_int32: 1 # another comment\n" +
|
---|
324 | "optional_int64: 2\n" +
|
---|
325 | "# EOF comment", builder);
|
---|
326 | Assert.AreEqual(1, builder.OptionalInt32);
|
---|
327 | Assert.AreEqual(2, builder.OptionalInt64);
|
---|
328 | }
|
---|
329 |
|
---|
330 |
|
---|
331 | private static void AssertParseError(string error, string text) {
|
---|
332 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
333 | try {
|
---|
334 | TextFormat.Merge(text, TestUtil.CreateExtensionRegistry(), builder);
|
---|
335 | Assert.Fail("Expected parse exception.");
|
---|
336 | } catch (FormatException e) {
|
---|
337 | Assert.AreEqual(error, e.Message);
|
---|
338 | }
|
---|
339 | }
|
---|
340 |
|
---|
341 | [Test]
|
---|
342 | public void ParseErrors() {
|
---|
343 | AssertParseError(
|
---|
344 | "1:16: Expected \":\".",
|
---|
345 | "optional_int32 123");
|
---|
346 | AssertParseError(
|
---|
347 | "1:23: Expected identifier.",
|
---|
348 | "optional_nested_enum: ?");
|
---|
349 | AssertParseError(
|
---|
350 | "1:18: Couldn't parse integer: Number must be positive: -1",
|
---|
351 | "optional_uint32: -1");
|
---|
352 | AssertParseError(
|
---|
353 | "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
|
---|
354 | "integer: 82301481290849012385230157",
|
---|
355 | "optional_int32: 82301481290849012385230157");
|
---|
356 | AssertParseError(
|
---|
357 | "1:16: Expected \"true\" or \"false\".",
|
---|
358 | "optional_bool: maybe");
|
---|
359 | AssertParseError(
|
---|
360 | "1:18: Expected string.",
|
---|
361 | "optional_string: 123");
|
---|
362 | AssertParseError(
|
---|
363 | "1:18: String missing ending quote.",
|
---|
364 | "optional_string: \"ueoauaoe");
|
---|
365 | AssertParseError(
|
---|
366 | "1:18: String missing ending quote.",
|
---|
367 | "optional_string: \"ueoauaoe\n" +
|
---|
368 | "optional_int32: 123");
|
---|
369 | AssertParseError(
|
---|
370 | "1:18: Invalid escape sequence: '\\z'",
|
---|
371 | "optional_string: \"\\z\"");
|
---|
372 | AssertParseError(
|
---|
373 | "1:18: String missing ending quote.",
|
---|
374 | "optional_string: \"ueoauaoe\n" +
|
---|
375 | "optional_int32: 123");
|
---|
376 | AssertParseError(
|
---|
377 | "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
|
---|
378 | "[nosuchext]: 123");
|
---|
379 | AssertParseError(
|
---|
380 | "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
|
---|
381 | "not extend message type \"protobuf_unittest.TestAllTypes\".",
|
---|
382 | "[protobuf_unittest.optional_int32_extension]: 123");
|
---|
383 | AssertParseError(
|
---|
384 | "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
|
---|
385 | "named \"nosuchfield\".",
|
---|
386 | "nosuchfield: 123");
|
---|
387 | AssertParseError(
|
---|
388 | "1:21: Expected \">\".",
|
---|
389 | "OptionalGroup < a: 1");
|
---|
390 | AssertParseError(
|
---|
391 | "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
|
---|
392 | "value named \"NO_SUCH_VALUE\".",
|
---|
393 | "optional_nested_enum: NO_SUCH_VALUE");
|
---|
394 | AssertParseError(
|
---|
395 | "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
|
---|
396 | "value with number 123.",
|
---|
397 | "optional_nested_enum: 123");
|
---|
398 |
|
---|
399 | // Delimiters must match.
|
---|
400 | AssertParseError(
|
---|
401 | "1:22: Expected identifier.",
|
---|
402 | "OptionalGroup < a: 1 }");
|
---|
403 | AssertParseError(
|
---|
404 | "1:22: Expected identifier.",
|
---|
405 | "OptionalGroup { a: 1 >");
|
---|
406 | }
|
---|
407 |
|
---|
408 | // =================================================================
|
---|
409 |
|
---|
410 | private static ByteString Bytes(params byte[] bytes) {
|
---|
411 | return ByteString.CopyFrom(bytes);
|
---|
412 | }
|
---|
413 |
|
---|
414 | private delegate void FormattingAction();
|
---|
415 |
|
---|
416 | private static void AssertFormatException(FormattingAction action) {
|
---|
417 | try {
|
---|
418 | action();
|
---|
419 | Assert.Fail("Should have thrown an exception.");
|
---|
420 | } catch (FormatException) {
|
---|
421 | // success
|
---|
422 | }
|
---|
423 | }
|
---|
424 |
|
---|
425 | [Test]
|
---|
426 | public void Escape() {
|
---|
427 | // Escape sequences.
|
---|
428 | Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
|
---|
429 | TextFormat.EscapeBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"")));
|
---|
430 | Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
|
---|
431 | TextFormat.EscapeText("\0\u0001\u0007\b\f\n\r\t\v\\\'\""));
|
---|
432 | Assert.AreEqual(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\""),
|
---|
433 | TextFormat.UnescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
|
---|
434 | Assert.AreEqual("\0\u0001\u0007\b\f\n\r\t\v\\\'\"",
|
---|
435 | TextFormat.UnescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
|
---|
436 |
|
---|
437 | // Unicode handling.
|
---|
438 | Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeText("\u1234"));
|
---|
439 | Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeBytes(Bytes(0xe1, 0x88, 0xb4)));
|
---|
440 | Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\341\\210\\264"));
|
---|
441 | Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\341\\210\\264"));
|
---|
442 | Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\xe1\\x88\\xb4"));
|
---|
443 | Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\xe1\\x88\\xb4"));
|
---|
444 |
|
---|
445 | // Errors.
|
---|
446 | AssertFormatException(() => TextFormat.UnescapeText("\\x"));
|
---|
447 | AssertFormatException(() => TextFormat.UnescapeText("\\z"));
|
---|
448 | AssertFormatException(() => TextFormat.UnescapeText("\\"));
|
---|
449 | }
|
---|
450 |
|
---|
451 | [Test]
|
---|
452 | public void ParseInteger() {
|
---|
453 | Assert.AreEqual( 0, TextFormat.ParseInt32( "0"));
|
---|
454 | Assert.AreEqual( 1, TextFormat.ParseInt32( "1"));
|
---|
455 | Assert.AreEqual( -1, TextFormat.ParseInt32( "-1"));
|
---|
456 | Assert.AreEqual( 12345, TextFormat.ParseInt32( "12345"));
|
---|
457 | Assert.AreEqual( -12345, TextFormat.ParseInt32( "-12345"));
|
---|
458 | Assert.AreEqual( 2147483647, TextFormat.ParseInt32( "2147483647"));
|
---|
459 | Assert.AreEqual(-2147483648, TextFormat.ParseInt32("-2147483648"));
|
---|
460 |
|
---|
461 | Assert.AreEqual( 0, TextFormat.ParseUInt32( "0"));
|
---|
462 | Assert.AreEqual( 1, TextFormat.ParseUInt32( "1"));
|
---|
463 | Assert.AreEqual( 12345, TextFormat.ParseUInt32( "12345"));
|
---|
464 | Assert.AreEqual( 2147483647, TextFormat.ParseUInt32("2147483647"));
|
---|
465 | Assert.AreEqual(2147483648U, TextFormat.ParseUInt32("2147483648"));
|
---|
466 | Assert.AreEqual(4294967295U, TextFormat.ParseUInt32("4294967295"));
|
---|
467 |
|
---|
468 | Assert.AreEqual( 0L, TextFormat.ParseInt64( "0"));
|
---|
469 | Assert.AreEqual( 1L, TextFormat.ParseInt64( "1"));
|
---|
470 | Assert.AreEqual( -1L, TextFormat.ParseInt64( "-1"));
|
---|
471 | Assert.AreEqual( 12345L, TextFormat.ParseInt64( "12345"));
|
---|
472 | Assert.AreEqual( -12345L, TextFormat.ParseInt64( "-12345"));
|
---|
473 | Assert.AreEqual( 2147483647L, TextFormat.ParseInt64( "2147483647"));
|
---|
474 | Assert.AreEqual(-2147483648L, TextFormat.ParseInt64("-2147483648"));
|
---|
475 | Assert.AreEqual( 4294967295L, TextFormat.ParseInt64( "4294967295"));
|
---|
476 | Assert.AreEqual( 4294967296L, TextFormat.ParseInt64( "4294967296"));
|
---|
477 | Assert.AreEqual(9223372036854775807L, TextFormat.ParseInt64("9223372036854775807"));
|
---|
478 | Assert.AreEqual(-9223372036854775808L, TextFormat.ParseInt64("-9223372036854775808"));
|
---|
479 |
|
---|
480 | Assert.AreEqual( 0L, TextFormat.ParseUInt64( "0"));
|
---|
481 | Assert.AreEqual( 1L, TextFormat.ParseUInt64( "1"));
|
---|
482 | Assert.AreEqual( 12345L, TextFormat.ParseUInt64( "12345"));
|
---|
483 | Assert.AreEqual( 2147483647L, TextFormat.ParseUInt64( "2147483647"));
|
---|
484 | Assert.AreEqual( 4294967295L, TextFormat.ParseUInt64( "4294967295"));
|
---|
485 | Assert.AreEqual( 4294967296L, TextFormat.ParseUInt64( "4294967296"));
|
---|
486 | Assert.AreEqual(9223372036854775807UL, TextFormat.ParseUInt64("9223372036854775807"));
|
---|
487 | Assert.AreEqual(9223372036854775808UL, TextFormat.ParseUInt64("9223372036854775808"));
|
---|
488 | Assert.AreEqual(18446744073709551615UL, TextFormat.ParseUInt64("18446744073709551615"));
|
---|
489 |
|
---|
490 | // Hex
|
---|
491 | Assert.AreEqual(0x1234abcd, TextFormat.ParseInt32("0x1234abcd"));
|
---|
492 | Assert.AreEqual(-0x1234abcd, TextFormat.ParseInt32("-0x1234abcd"));
|
---|
493 | Assert.AreEqual(0xffffffffffffffffUL, TextFormat.ParseUInt64("0xffffffffffffffff"));
|
---|
494 | Assert.AreEqual(0x7fffffffffffffffL,
|
---|
495 | TextFormat.ParseInt64("0x7fffffffffffffff"));
|
---|
496 |
|
---|
497 | // Octal
|
---|
498 | Assert.AreEqual(342391, TextFormat.ParseInt32("01234567"));
|
---|
499 |
|
---|
500 | // Out-of-range
|
---|
501 | AssertFormatException(() => TextFormat.ParseInt32("2147483648"));
|
---|
502 | AssertFormatException(() => TextFormat.ParseInt32("-2147483649"));
|
---|
503 | AssertFormatException(() => TextFormat.ParseUInt32("4294967296"));
|
---|
504 | AssertFormatException(() => TextFormat.ParseUInt32("-1"));
|
---|
505 | AssertFormatException(() => TextFormat.ParseInt64("9223372036854775808"));
|
---|
506 | AssertFormatException(() => TextFormat.ParseInt64("-9223372036854775809"));
|
---|
507 | AssertFormatException(() => TextFormat.ParseUInt64("18446744073709551616"));
|
---|
508 | AssertFormatException(() => TextFormat.ParseUInt64("-1"));
|
---|
509 | AssertFormatException(() => TextFormat.ParseInt32("abcd"));
|
---|
510 | }
|
---|
511 |
|
---|
512 | [Test]
|
---|
513 | public void ParseLongString() {
|
---|
514 | string longText =
|
---|
515 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
516 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
517 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
518 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
519 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
520 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
521 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
522 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
523 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
524 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
525 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
526 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
527 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
528 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
529 | "123456789012345678901234567890123456789012345678901234567890" +
|
---|
530 | "123456789012345678901234567890123456789012345678901234567890";
|
---|
531 | TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
|
---|
532 | TextFormat.Merge("optional_string: \"" + longText + "\"", builder);
|
---|
533 | Assert.AreEqual(longText, builder.OptionalString);
|
---|
534 | }
|
---|
535 | }
|
---|
536 | }
|
---|