X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Json%2FTest%2FSystem.Json%2FJsonValueTest.cs;h=baff3cc32b181579cbcbb199970fde60290d7cb4;hb=7c6607a000b6239e86d1736a1815264af55c13e2;hp=754f8556a5fea0dbef54f21fdc055342afd69f8e;hpb=c251b192a55c255f278c9b9ad2ec949264a36526;p=mono.git diff --git a/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs b/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs index 754f8556a5f..baff3cc32b1 100644 --- a/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs +++ b/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs @@ -11,6 +11,8 @@ using System; using System.IO; using System.Text; using System.Json; +using System.Globalization; +using System.Threading; namespace MonoTests.System { @@ -24,6 +26,273 @@ namespace MonoTests.System Assert.AreEqual (1, j.Count, "itemcount"); Assert.AreEqual (JsonType.String, j ["a"].JsonType, "type"); Assert.AreEqual ("b", (string) j ["a"], "value"); + + JsonValue.Parse ("[{ \"a\": \"b\",}]"); + } + + [Test] + public void LoadWithTrailingComma2 () + { + JsonValue.Parse ("[{ \"a\": \"b\",}]"); + } + + // Test that we correctly serialize JsonArray with null elements. + [Test] + public void ToStringOnJsonArrayWithNulls () { + var j = JsonValue.Load (new StringReader ("[1,2,3,null]")); + Assert.AreEqual (4, j.Count, "itemcount"); + Assert.AreEqual (JsonType.Array, j.JsonType, "type"); + var str = j.ToString (); + Assert.AreEqual (str, "[1, 2, 3, null]"); + ((JsonArray) j).Add (null); + str = j.ToString (); + Assert.AreEqual (str, "[1, 2, 3, null, null]"); + } + + // Test that we correctly serialize JsonObject with null elements. + [Test] + public void ToStringOnJsonObjectWithNulls () { + var j = JsonValue.Load (new StringReader ("{\"a\":null,\"b\":2}")); + Assert.AreEqual (2, j.Count, "itemcount"); + Assert.AreEqual (JsonType.Object, j.JsonType, "type"); + var str = j.ToString (); + Assert.AreEqual (str, "{\"a\": null, \"b\": 2}"); + } + + [Test] + public void JsonObjectOrder () { + var obj = new JsonObject (); + obj["a"] = 1; + obj["c"] = 3; + obj["b"] = 2; + var str = obj.ToString (); + Assert.AreEqual (str, "{\"a\": 1, \"b\": 2, \"c\": 3}"); + } + + [Test] + public void QuoteEscapeBug_20869 () + { + Assert.AreEqual ((new JsonPrimitive ("\"\"")).ToString (), "\"\\\"\\\"\""); + } + + void ExpectError (string s) + { + try { + JsonValue.Parse (s); + Assert.Fail ("Expected ArgumentException for `" + s + "'"); + } catch (ArgumentException) { + } + } + + // Test whether an exception is thrown for invalid JSON + [Test] + public void CheckErrors () + { + ExpectError (@"-"); + ExpectError (@"- "); + ExpectError (@"1."); + ExpectError (@"1. "); + ExpectError (@"1e+"); + ExpectError (@"1 2"); + ExpectError (@"077"); + + ExpectError (@"[1,]"); + + //ExpectError (@"{""a"":1,}"); // Not valid JSON, allowed anyway + } + + // Parse a json string and compare to the expected value + void CheckDouble (double expected, string json) + { + double jvalue = (double) JsonValue.Parse (json); + Assert.AreEqual (expected, jvalue); + } + + // Convert a number to json and parse the string, then compare the result to the original value + void CheckDouble (double number) + { + double jvalue = (double) JsonValue.Parse (new JsonPrimitive (number).ToString ()); + Assert.AreEqual (number, jvalue); // should be exactly the same + } + + [Test] + public void CheckIntegers () + { + Assert.AreEqual (sbyte.MinValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MinValue).ToString ())); + Assert.AreEqual (sbyte.MaxValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MaxValue).ToString ())); + Assert.AreEqual (byte.MinValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MinValue).ToString ())); + Assert.AreEqual (byte.MaxValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MaxValue).ToString ())); + + Assert.AreEqual (short.MinValue, (short) JsonValue.Parse (new JsonPrimitive (short.MinValue).ToString ())); + Assert.AreEqual (short.MaxValue, (short) JsonValue.Parse (new JsonPrimitive (short.MaxValue).ToString ())); + Assert.AreEqual (ushort.MinValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MinValue).ToString ())); + Assert.AreEqual (ushort.MaxValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MaxValue).ToString ())); + + Assert.AreEqual (int.MinValue, (int) JsonValue.Parse (new JsonPrimitive (int.MinValue).ToString ())); + Assert.AreEqual (int.MaxValue, (int) JsonValue.Parse (new JsonPrimitive (int.MaxValue).ToString ())); + Assert.AreEqual (uint.MinValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MinValue).ToString ())); + Assert.AreEqual (uint.MaxValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MaxValue).ToString ())); + + Assert.AreEqual (long.MinValue, (long) JsonValue.Parse (new JsonPrimitive (long.MinValue).ToString ())); + Assert.AreEqual (long.MaxValue, (long) JsonValue.Parse (new JsonPrimitive (long.MaxValue).ToString ())); + Assert.AreEqual (ulong.MinValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MinValue).ToString ())); + Assert.AreEqual (ulong.MaxValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MaxValue).ToString ())); + } + + [Test] + public void CheckNumbers () + { + CheckDouble (0, "0"); + CheckDouble (0, "-0"); + CheckDouble (0, "0.00"); + CheckDouble (0, "-0.00"); + CheckDouble (1, "1"); + CheckDouble (1.1, "1.1"); + CheckDouble (-1, "-1"); + CheckDouble (-1.1, "-1.1"); + CheckDouble (1e-10, "1e-10"); + CheckDouble (1e+10, "1e+10"); + CheckDouble (1e-30, "1e-30"); + CheckDouble (1e+30, "1e+30"); + + CheckDouble (1, "\"1\""); + CheckDouble (1.1, "\"1.1\""); + CheckDouble (-1, "\"-1\""); + CheckDouble (-1.1, "\"-1.1\""); + + CheckDouble (double.NaN, "\"NaN\""); + CheckDouble (double.PositiveInfinity, "\"Infinity\""); + CheckDouble (double.NegativeInfinity, "\"-Infinity\""); + + ExpectError ("NaN"); + ExpectError ("Infinity"); + ExpectError ("-Infinity"); + + Assert.AreEqual ("1.1", new JsonPrimitive (1.1).ToString ()); + Assert.AreEqual ("-1.1", new JsonPrimitive (-1.1).ToString ()); + Assert.AreEqual ("1E-20", new JsonPrimitive (1e-20).ToString ()); + Assert.AreEqual ("1E+20", new JsonPrimitive (1e+20).ToString ()); + Assert.AreEqual ("1E-30", new JsonPrimitive (1e-30).ToString ()); + Assert.AreEqual ("1E+30", new JsonPrimitive (1e+30).ToString ()); + Assert.AreEqual ("\"NaN\"", new JsonPrimitive (double.NaN).ToString ()); + Assert.AreEqual ("\"Infinity\"", new JsonPrimitive (double.PositiveInfinity).ToString ()); + Assert.AreEqual ("\"-Infinity\"", new JsonPrimitive (double.NegativeInfinity).ToString ()); + + Assert.AreEqual ("1E-30", JsonValue.Parse ("1e-30").ToString ()); + Assert.AreEqual ("1E+30", JsonValue.Parse ("1e+30").ToString ()); + + CheckDouble (1); + CheckDouble (1.1); + CheckDouble (1.25); + CheckDouble (-1); + CheckDouble (-1.1); + CheckDouble (-1.25); + CheckDouble (1e-20); + CheckDouble (1e+20); + CheckDouble (1e-30); + CheckDouble (1e+30); + CheckDouble (3.1415926535897932384626433); + CheckDouble (3.1415926535897932384626433e-20); + CheckDouble (3.1415926535897932384626433e+20); + CheckDouble (double.NaN); + CheckDouble (double.PositiveInfinity); + CheckDouble (double.NegativeInfinity); + CheckDouble (double.MinValue); + CheckDouble (double.MaxValue); + + // A number which needs 17 digits (see http://stackoverflow.com/questions/6118231/why-do-i-need-17-significant-digits-and-not-16-to-represent-a-double) + CheckDouble (18014398509481982.0); + + // Values around the smallest positive decimal value + CheckDouble (1.123456789e-29); + CheckDouble (1.123456789e-28); + + CheckDouble (1.1E-29, "0.000000000000000000000000000011"); + // This is being parsed as a decimal and rounded to 1e-28, even though it can be more accurately be represented by a double + //CheckDouble (1.1E-28, "0.00000000000000000000000000011"); + } + + // Retry the test with different locales + [Test] + public void CheckNumbersCulture () + { + CultureInfo old = Thread.CurrentThread.CurrentCulture; + try { + Thread.CurrentThread.CurrentCulture = new CultureInfo ("en"); + CheckNumbers (); + Thread.CurrentThread.CurrentCulture = new CultureInfo ("fr"); + CheckNumbers (); + Thread.CurrentThread.CurrentCulture = new CultureInfo ("de"); + CheckNumbers (); + } finally { + Thread.CurrentThread.CurrentCulture = old; + } + } + + // Convert a string to json and parse the string, then compare the result to the original value + void CheckString (string str) + { + var json = new JsonPrimitive (str).ToString (); + // Check whether the string is valid Unicode (will throw for broken surrogate pairs) + new UTF8Encoding (false, true).GetBytes (json); + string jvalue = (string) JsonValue.Parse (json); + Assert.AreEqual (str, jvalue); + } + + // String handling: http://tools.ietf.org/html/rfc7159#section-7 + [Test] + public void CheckStrings () + { + Assert.AreEqual ("\"test\"", new JsonPrimitive ("test").ToString ()); + // Handling of characters + Assert.AreEqual ("\"f\"", new JsonPrimitive ('f').ToString ()); + Assert.AreEqual ('f', (char) JsonValue.Parse ("\"f\"")); + + // Control characters with special escape sequence + Assert.AreEqual ("\"\\b\\f\\n\\r\\t\"", new JsonPrimitive ("\b\f\n\r\t").ToString ()); + // Other characters which must be escaped + Assert.AreEqual (@"""\""\\""", new JsonPrimitive ("\"\\").ToString ()); + // Control characters without special escape sequence + for (int i = 0; i < 32; i++) + if (i != '\b' && i != '\f' && i != '\n' && i != '\r' && i != '\t') + Assert.AreEqual ("\"\\u" + i.ToString ("x04") + "\"", new JsonPrimitive ("" + (char) i).ToString ()); + + // JSON does not require U+2028 and U+2029 to be escaped, but + // JavaScript does require this: + // http://stackoverflow.com/questions/2965293/javascript-parse-error-on-u2028-unicode-character/9168133#9168133 + Assert.AreEqual ("\"\\u2028\\u2029\"", new JsonPrimitive ("\u2028\u2029").ToString ()); + + // '/' also does not have to be escaped, but escaping it when + // preceeded by a '<' avoids problems with JSON in HTML