Merge pull request #1066 from esdrubal/bug19313
[mono.git] / mcs / class / System.Json / Test / System.Json / JsonValueTest.cs
1 //
2 // JsonValueTest.cs: Tests for JSonValue
3 //
4 // Copyright 2011 Xamarin, Inc.
5 //
6 // Authors:
7 //   Miguel de Icaza
8 //
9 using NUnit.Framework;
10 using System;
11 using System.IO;
12 using System.Text;
13 using System.Json;
14 using System.Globalization;
15 using System.Threading;
16
17 namespace MonoTests.System
18 {
19         [TestFixture]
20         public class JsonValueTests {
21                 // Tests that a trailing comma is allowed in dictionary definitions
22                 [Test]
23                 public void LoadWithTrailingComma ()
24                 {
25                         var j = JsonValue.Load (new StringReader ("{ \"a\": \"b\",}"));
26                         Assert.AreEqual (1, j.Count, "itemcount");
27                         Assert.AreEqual (JsonType.String, j ["a"].JsonType, "type");
28                         Assert.AreEqual ("b", (string) j ["a"], "value");
29
30                         JsonValue.Parse ("[{ \"a\": \"b\",}]");
31                 }
32
33                 [Test]
34                 public void LoadWithTrailingComma2 ()
35                 {
36                         JsonValue.Parse ("[{ \"a\": \"b\",}]");
37                 }
38
39                 // Test that we correctly serialize JsonArray with null elements.
40                 [Test]
41                 public void ToStringOnJsonArrayWithNulls () {
42                         var j = JsonValue.Load (new StringReader ("[1,2,3,null]"));
43                         Assert.AreEqual (4, j.Count, "itemcount");
44                         Assert.AreEqual (JsonType.Array, j.JsonType, "type");
45                         var str = j.ToString ();
46                         Assert.AreEqual (str, "[1, 2, 3, null]");
47                 }
48
49                 [Test]
50                 public void QuoteEscapeBug_20869 () 
51                 {
52                         Assert.AreEqual ((new JsonPrimitive ("\"\"")).ToString (), "\"\\\"\\\"\"");
53                 }
54
55                 void ExpectError (string s)
56                 {
57                         try {
58                                 JsonValue.Parse (s);
59                                 Assert.Fail ("Expected ArgumentException for `" + s + "'");
60                         } catch (ArgumentException) {
61                         }
62                 }
63
64                 // Test whether an exception is thrown for invalid JSON
65                 [Test]
66                 public void CheckErrors () 
67                 {
68                         ExpectError (@"-");
69                         ExpectError (@"- ");
70                         ExpectError (@"1.");
71                         ExpectError (@"1. ");
72                         ExpectError (@"1e+");
73                         ExpectError (@"1 2");
74                         ExpectError (@"077");
75
76                         ExpectError (@"[1,]");
77
78                         //ExpectError (@"{""a"":1,}"); // Not valid JSON, allowed anyway
79                 }
80
81                 // Parse a json string and compare to the expected value
82                 void CheckDouble (double expected, string json)
83                 {
84                         double jvalue = (double) JsonValue.Parse (json);
85                         Assert.AreEqual (expected, jvalue);
86                 }
87
88                 // Convert a number to json and parse the string, then compare the result to the original value
89                 void CheckDouble (double number)
90                 {
91                         double jvalue = (double) JsonValue.Parse (new JsonPrimitive (number).ToString ());
92                         Assert.AreEqual (number, jvalue); // should be exactly the same
93                 }
94
95                 [Test]
96                 public void CheckNumbers () 
97                 {
98                         CheckDouble (0, "0");
99                         CheckDouble (0, "-0");
100                         CheckDouble (0, "0.00");
101                         CheckDouble (0, "-0.00");
102                         CheckDouble (1, "1");
103                         CheckDouble (1.1, "1.1");
104                         CheckDouble (-1, "-1");
105                         CheckDouble (-1.1, "-1.1");
106                         CheckDouble (1e-10, "1e-10");
107                         CheckDouble (1e+10, "1e+10");
108                         CheckDouble (1e-30, "1e-30");
109                         CheckDouble (1e+30, "1e+30");
110
111                         CheckDouble (1, "\"1\"");
112                         CheckDouble (1.1, "\"1.1\"");
113                         CheckDouble (-1, "\"-1\"");
114                         CheckDouble (-1.1, "\"-1.1\"");
115
116                         CheckDouble (double.NaN, "\"NaN\"");
117                         CheckDouble (double.PositiveInfinity, "\"Infinity\"");
118                         CheckDouble (double.NegativeInfinity, "\"-Infinity\"");
119
120                         ExpectError ("NaN");
121                         ExpectError ("Infinity");
122                         ExpectError ("-Infinity");
123
124                         Assert.AreEqual ("1.1", new JsonPrimitive (1.1).ToString ());
125                         Assert.AreEqual ("-1.1", new JsonPrimitive (-1.1).ToString ());
126                         Assert.AreEqual ("1E-20", new JsonPrimitive (1e-20).ToString ());
127                         Assert.AreEqual ("1E+20", new JsonPrimitive (1e+20).ToString ());
128                         Assert.AreEqual ("1E-30", new JsonPrimitive (1e-30).ToString ());
129                         Assert.AreEqual ("1E+30", new JsonPrimitive (1e+30).ToString ());
130                         Assert.AreEqual ("\"NaN\"", new JsonPrimitive (double.NaN).ToString ());
131                         Assert.AreEqual ("\"Infinity\"", new JsonPrimitive (double.PositiveInfinity).ToString ());
132                         Assert.AreEqual ("\"-Infinity\"", new JsonPrimitive (double.NegativeInfinity).ToString ());
133
134                         Assert.AreEqual ("1E-30", JsonValue.Parse ("1e-30").ToString ());
135                         Assert.AreEqual ("1E+30", JsonValue.Parse ("1e+30").ToString ());
136
137                         CheckDouble (1);
138                         CheckDouble (1.1);
139                         CheckDouble (1.25);
140                         CheckDouble (-1);
141                         CheckDouble (-1.1);
142                         CheckDouble (-1.25);
143                         CheckDouble (1e-20);
144                         CheckDouble (1e+20);
145                         CheckDouble (1e-30);
146                         CheckDouble (1e+30);
147                         CheckDouble (3.1415926535897932384626433);
148                         CheckDouble (3.1415926535897932384626433e-20);
149                         CheckDouble (3.1415926535897932384626433e+20);
150                         CheckDouble (double.NaN);
151                         CheckDouble (double.PositiveInfinity);
152                         CheckDouble (double.NegativeInfinity);
153                         CheckDouble (double.MinValue);
154                         CheckDouble (double.MaxValue);
155
156                         // 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)
157                         CheckDouble (18014398509481982.0);
158
159                         // Values around the smallest positive decimal value
160                         CheckDouble (1.123456789e-29);
161                         CheckDouble (1.123456789e-28);
162
163                         CheckDouble (1.1E-29, "0.000000000000000000000000000011");
164                         // This is being parsed as a decimal and rounded to 1e-28, even though it can be more accurately be represented by a double
165                         //CheckDouble (1.1E-28, "0.00000000000000000000000000011");
166                 }
167
168                 // Retry the test with different locales
169                 [Test]
170                 public void CheckNumbersCulture () 
171                 {
172                         CultureInfo old = Thread.CurrentThread.CurrentCulture;
173                         try {
174                                 Thread.CurrentThread.CurrentCulture = new CultureInfo ("en");
175                                 CheckNumbers ();
176                                 Thread.CurrentThread.CurrentCulture = new CultureInfo ("fr");
177                                 CheckNumbers ();
178                                 Thread.CurrentThread.CurrentCulture = new CultureInfo ("de");
179                                 CheckNumbers ();
180                         } finally {
181                                 Thread.CurrentThread.CurrentCulture = old;
182                         }
183                 }
184         }
185 }