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