[System] Process.WaitForExit now triggers event Exited.
[mono.git] / mcs / class / System.Web.Extensions / Test / System.Web.Script.Serialization / JavaScriptSerializerTest.cs
1 //
2 // JavaScriptSerializer.cs
3 //
4 // Author:
5 //   Konstantin Triger <kostat@mainsoft.com>
6 //
7 // (C) 2007 Mainsoft, Inc.  http://www.mainsoft.com
8 //
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Collections.Generic;
32 using System.Text;
33 using NUnit.Framework;
34 using System.Web.Script.Serialization;
35 using System.Reflection;
36 using System.Collections;
37 using System.Drawing;
38 using ComponentModel = System.ComponentModel;
39 using System.Globalization;
40 using System.Threading;
41 using System.Text.RegularExpressions;
42 using System.ComponentModel;
43 using CategoryAttribute = NUnit.Framework.CategoryAttribute;
44 using System.Web.UI.WebControls;
45 using System.Collections.ObjectModel;
46
47
48 namespace MonoTests.System.Web.Script.Serialization
49 {
50         [TestFixture]
51         public class JavaScriptSerializerTest
52         {
53                 enum MyEnum
54                 {
55                         AAA,
56                         BBB,
57                         CCC
58                 }
59 #pragma warning disable 659
60                 class bug
61                 {
62                         //public DateTime dt;
63                         //public DateTime dt1;
64                         //public DateTime dt2;
65                         public bool bb;
66                         //Hashtable hash;
67
68                         public void Init() {
69                                 //dt = DateTime.MaxValue;
70                                 //dt1 = DateTime.MinValue;
71                                 //dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
72                                 bb = true;
73                                 //hash = new Hashtable ();
74                                 //hash.Add ("mykey", 1);
75                         }
76
77                         public override bool Equals (object obj) {
78                                 if (!(obj is bug))
79                                         return false;
80                                 JavaScriptSerializerTest.FieldsEqual (this, obj);
81                                 return true;
82                         }
83                 }
84                 class X
85                 {
86                         int x = 5;
87                         //int y;
88                         ulong _bb;
89                         Y[] _yy;
90                         Y [] _yyy = new Y [] { new Y (), new Y () };
91                         public int z;
92                         public char ch;
93                         public char ch_null;
94                         public string str;
95                         public byte b;
96                         public sbyte sb;
97                         public short sh;
98                         public ushort ush;
99                         public int i;
100                         public uint ui;
101                         public long l;
102                         public ulong ul;
103                         
104                         public float f;
105                         public float f1;
106                         public float f2;
107                         public float f3;
108                         public float f4;
109
110                         public double d;
111                         public double d1;
112                         public double d2;
113                         public double d3;
114                         public double d4;
115
116                         public decimal de;
117                         public decimal de1;
118                         public decimal de2;
119                         public decimal de3;
120                         public decimal de4;
121
122                         
123
124                         public Guid g;
125                         
126                         public Nullable<bool> nb;
127                         public DBNull dbn;
128                         IEnumerable<int> enum_int;
129                         IEnumerable enum_int1;
130                         public Uri uri;
131                         public Dictionary<string, Y> hash;
132                         public Point point;
133
134                         public void Init () {
135                                 //y = 6;
136                                 _bb = ulong.MaxValue - 5;
137                                 _yy = new Y [] { new Y (), new Y () };
138                                 z = 8;
139                                 ch = (char) 0xFF56;
140                                 ch_null = '\0';
141                                 str = "\uFF56\uFF57\uF58FF59g";
142                                 b = 253;
143                                 sb = -48;
144                                 sh = short.MinValue + 28;
145                                 ush = ushort.MaxValue - 24;
146                                 i = -234235453;
147                                 ui = uint.MaxValue - 234234;
148                                 l = long.MinValue + 28;
149                                 ul = ulong.MaxValue - 3;
150
151                                 f = float.NaN;
152                                 f1 = float.NegativeInfinity;
153                                 f2 = float.PositiveInfinity;
154                                 f3 = float.MinValue;
155                                 f4 = float.MaxValue;
156
157                                 d = double.NaN;
158                                 d1 = double.NegativeInfinity;
159                                 d2 = double.PositiveInfinity;
160                                 d3 = double.MinValue;
161                                 d4 = double.MaxValue;
162
163                                 de = decimal.MinusOne;
164                                 de1 = decimal.Zero;
165                                 de2 = decimal.One;
166                                 de3 = decimal.MinValue;
167                                 de4 = decimal.MaxValue;
168
169                                 g = new Guid (234, 2, 354, new byte [] { 1, 2, 3, 4, 5, 6, 7, 8 });
170                                 
171                                 nb = null;
172                                 dbn = null;
173
174                                 enum_int = new List<int> (MyEnum);
175                                 enum_int1 = new ArrayList ();
176                                 foreach (object obj in MyEnum1)
177                                         ((ArrayList) enum_int1).Add (obj);
178                                 uri = new Uri ("http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d", UriKind.RelativeOrAbsolute);
179
180                                 hash = new Dictionary<string, Y> ();
181                                 Y y = new Y ();
182                                 hash ["mykey"] = y;
183                                 point = new Point (150, 150);
184                         }
185
186                         public IEnumerable<int> MyEnum {
187                                 get {
188                                         yield return 1;
189                                         yield return 10;
190                                         yield return 345;
191                                 }
192
193                                 set {
194                                         enum_int = value;
195                                 }
196                         }
197
198                         public IEnumerable MyEnum1 {
199                                 get {
200                                         yield return 1;
201                                         yield return 10;
202                                         yield return 345;
203                                 }
204
205                                 set {
206                                         enum_int1 = value;
207                                 }
208                         }
209
210                         public int AA {
211                                 get { return x; }
212                         }
213
214                         public Y[] AA1 {
215                                 get { return _yyy; }
216                         }
217
218                         public ulong BB {
219                                 get { return _bb; }
220                                 set { _bb = value; }
221                         }
222
223                         public Y[] YY {
224                                 get { return _yy; }
225                                 set { _yy = value; }
226                         }
227
228                         public override bool Equals (object obj) {
229                                 if (!(obj is X))
230                                         return false;
231                                 JavaScriptSerializerTest.FieldsEqual (this, obj);
232                                 return true;
233                         }
234                 }
235
236                 class Y
237                 {
238
239                         long _bb = 10;
240
241                         public long BB {
242                                 get { return _bb; }
243                                 set { _bb = value; }
244                         }
245
246                         public override bool Equals (object obj) {
247                                 if (!(obj is Y))
248                                         return false;
249                                 JavaScriptSerializerTest.FieldsEqual(this, obj);
250                                 return true;
251                         }
252                 }
253
254                 class YY
255                 {
256                         public YY () 
257                         {
258                                 Y1 = new Y ();
259                                 Y2 = new Y ();
260                         }
261
262                         public Y Y1;
263                         public Y Y2;
264                 }
265
266                 [TypeConverter (typeof (MyUriConverter))]
267                 class MyUri : Uri
268                 {
269                         public MyUri (string uriString, UriKind uriKind)
270                                 : base (uriString, uriKind) {
271                         }
272
273                         public MyUri (Uri value)
274                                 : base (value.AbsoluteUri) {
275                         }
276                 }
277
278                 class MyUriConverter : UriTypeConverter
279                 {
280                         public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
281                         {
282                                 return base.ConvertTo (context, culture, value, destinationType);
283                         }
284
285                         public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value) 
286                         {
287                                 Uri convertedUri = (Uri)base.ConvertFrom (context, culture, value);
288                                 return new MyUri (convertedUri);
289                         }
290                 }
291
292                 [TypeConverter(typeof(MyPointConverter))]
293                 class MyPointContainer
294                 {
295                         public MyPointContainer () 
296                         {
297                         }
298
299                         public MyPointContainer (Point v) 
300                         {
301                                 p = v;
302                         }
303
304                         internal Point p;
305                 }
306
307                 class MyPointConverter : TypeConverter
308                 {
309                         public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType) 
310                         {
311                                 if (destinationType == typeof (string)) {
312                                         return true;
313                                 }
314                                 return base.CanConvertTo (context, destinationType);
315                         }
316
317                         public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
318                         {
319                                 if (destinationType == typeof (string)) {
320                                         MyPointContainer pc = (MyPointContainer) value;
321                                         return pc.p.X + "," + pc.p.Y;
322                                 }
323                                 return base.ConvertTo (context, culture, value, destinationType);
324                         }
325
326                         public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) 
327                         {
328                                 if (sourceType == typeof (string)) {
329                                         return true;
330                                 }
331                                 return base.CanConvertFrom (context, sourceType);
332                         }
333
334                         public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value) 
335                         {
336                                 if (value is string) {
337                                         string [] v = ((string) value).Split (new char [] { ',' });
338                                         return new MyPointContainer(new Point (int.Parse (v [0]), int.Parse (v [1])));
339                                 }
340                                 return base.ConvertFrom (context, culture, value);
341                         }
342                 }
343
344 #pragma warning restore 659
345
346                 [Test]
347                 [Category ("NotDotNet")]
348                 public void TestDefaults () {
349                         JavaScriptSerializer ser = new JavaScriptSerializer ();
350                         Assert.AreEqual (2097152, ser.MaxJsonLength);
351                         Assert.AreEqual (100, ser.RecursionLimit);
352                         //List<JavaScriptConverter> l = new List<JavaScriptConverter> ();
353                         //l.Add (new MyJavaScriptConverter ());
354                         //ser.RegisterConverters (l);
355                         //string x = ser.Serialize (new X [] { new X (), new X () });
356                         //string s = ser.Serialize (new X());
357                         //"{\"BB\":10,\"__type\":\"Tests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\"}"
358                         //X x = ser.Deserialize<X> (s);
359                         //object ddd = typeof (Y).GetMember ("BB");
360                         //object x1 = ser.Deserialize<X []> (null);
361                         //object x2 = ser.Deserialize<X []> ("");
362                         //object d = ser.Deserialize<X[]> (x);
363                 }
364
365                 [Test]
366                 public void TestDeserializeUnquotedKeys ()
367                 {
368                         JavaScriptSerializer ser = new JavaScriptSerializer ();
369                         IDictionary dict = ser.Deserialize <Dictionary <string, object>> ("{itemOne:\"1\",itemTwo:\"2\"}");
370
371                         Assert.AreEqual ("1", dict ["itemOne"], "#A1");
372                         Assert.AreEqual ("2", dict ["itemTwo"], "#A2");
373
374                         dict = ser.Deserialize <Dictionary <string, object>> ("{itemOne:1,itemTwo:2}");
375                         Assert.AreEqual (1, dict ["itemOne"], "#B1");
376                         Assert.AreEqual (2, dict ["itemTwo"], "#B2");
377                 }
378
379                 [Test]
380                 public void TestDeserializeUnquotedKeysWithSpaces ()
381                 {
382                         JavaScriptSerializer ser = new JavaScriptSerializer ();
383                         IDictionary dict = ser.Deserialize <Dictionary <string, object>> ("{ itemOne :\"1\",itemTwo:\"2\"}");
384
385                         Assert.AreEqual ("1", dict ["itemOne"], "#A1");
386                         Assert.AreEqual ("2", dict ["itemTwo"], "#A2");
387
388                         dict = ser.Deserialize <Dictionary <string, object>> ("{   itemOne   :1,   itemTwo   :2}");
389                         Assert.AreEqual (1, dict ["itemOne"], "#B1");
390                         Assert.AreEqual (2, dict ["itemTwo"], "#B2");
391                 }
392                 
393                 [Test]
394                 public void TestDeserialize () {
395                         JavaScriptSerializer ser = new JavaScriptSerializer ();
396                         Assert.IsNull (ser.Deserialize<X> (""));
397
398                         X s = new X ();
399                         s.Init ();
400                         string x = ser.Serialize (s);
401
402                         Assert.AreEqual ("{\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"BB\":10}},\"point\":{\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"BB\":10},{\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"BB\":10},{\"BB\":10}]}", x, "#A1");
403                         
404                         X n = ser.Deserialize<X> (x);
405                         Assert.AreEqual (s, n, "#A2");
406
407                         //string json = "\\uFF56";
408                         //string result = ser.Deserialize<string> (json);
409                         //Assert.AreEqual ("\uFF56", result);
410
411                         //object oo = ser.DeserializeObject ("{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}");
412                 }
413
414                 [Test]
415                 public void TestDeserializeNonGenericOverload()
416                 {
417                         JavaScriptSerializer ser = new JavaScriptSerializer();
418                         Assert.IsNull(ser.Deserialize("", typeof(X)));
419
420                         X s = new X();
421                         s.Init();
422                         string x = ser.Serialize(s);
423
424                         Assert.AreEqual("{\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"BB\":10}},\"point\":{\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"BB\":10},{\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"BB\":10},{\"BB\":10}]}", x, "#A1");
425
426                         X n = ser.Deserialize(x, typeof(X)) as X;
427                         Assert.AreEqual(s, n, "#A2");
428                 }
429
430                 [Test]
431                 public void TestDeserializeTypeResolver () 
432                 {
433 #if NET_4_5
434                         string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_5, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
435 #elif NET_4_0
436                         string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_4_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
437 #else
438                         string expected = "{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}";
439 #endif
440                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
441                         X x = new X ();
442                         x.Init ();
443
444                         string s = ser.Serialize (x);
445                         Assert.AreEqual (expected, s, "#A1");
446                         
447                         X x2 = ser.Deserialize<X> (s);
448                         Assert.AreEqual (x, x2, "#A2");
449                 }
450
451                 [Test]
452                 public void TestDeserializeBugs () {
453                         JavaScriptSerializer ser = new JavaScriptSerializer ();
454
455                         bug s = new bug ();
456                         s.Init ();
457                         string x = ser.Serialize (s);
458                         bug n = ser.Deserialize<bug> (x);
459                         Assert.AreEqual (s, n);
460
461                         // Should check correctness with .Net GA:
462                         //js = ser.Serialize (Color.Red);
463                         //Color ccc = ser.Deserialize<Color> (js);
464                         //string xml = @"<root><node attr=""xxx""/></root>";
465
466                         //XmlDocument doc = new XmlDocument ();
467                         //doc.LoadXml (xml);
468                         //string js = ser.Serialize (doc);
469                         //DataTable table = new DataTable();
470                         //table.Columns.Add ("col1", typeof (int));
471                         //table.Columns.Add ("col2", typeof (float));
472                         //table.Rows.Add (1, 1f);
473                         //table.Rows.Add (234234, 2.4f);
474
475                         //string js = ser.Serialize (table);
476                 }
477
478                 static void FieldsEqual (object expected, object actual) {
479                         Assert.AreEqual (expected.GetType (), actual.GetType ());
480                         FieldInfo [] infos = expected.GetType ().GetFields (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
481                         foreach (FieldInfo info in infos) {
482                                 object value1 = info.GetValue (expected);
483                                 object value2 = info.GetValue (actual);
484                                 if (value1 is IEnumerable) {
485                                         IEnumerator yenum = ((IEnumerable) value2).GetEnumerator ();
486                                         int index = -1;
487                                         foreach (object x in (IEnumerable) value1) {
488                                                 if (!yenum.MoveNext ())
489                                                         Assert.Fail (info.Name + " index:" + index);
490                                                 index++;
491                                                 if (x is DictionaryEntry) {
492                                                         DictionaryEntry entry = (DictionaryEntry)x;
493                                                         IDictionary dict = (IDictionary) value2;
494                                                         Assert.AreEqual (entry.Value, dict [entry.Key], info.Name + ", key:" + entry.Key);
495                                                 }
496                                                 else
497                                                         Assert.AreEqual (x, yenum.Current, info.Name + ", index:" + index);
498                                         }
499                                         Assert.IsFalse (yenum.MoveNext (), info.Name);
500                                         continue;
501                                 }
502                                 Assert.AreEqual (value1, value2, info.Name);
503                         }
504
505                 }
506
507                 [Test]
508                 [ExpectedException (typeof (ArgumentNullException))]
509                 public void TestDeserialize1 () {
510                         JavaScriptSerializer ser = new JavaScriptSerializer ();
511                         ser.Deserialize<string> (null);
512                 }
513
514                 [Test]
515                 [ExpectedException (typeof (ArgumentNullException))]
516                 public void TestDeserializeNullConverter () {
517                         JavaScriptSerializer ser = new JavaScriptSerializer ();
518                         ser.RegisterConverters (null);
519                 }
520
521                 [Test]
522                 [SetCulture ("en-US")]
523                 public void TestDeserializeConverter () {
524                         JavaScriptSerializer ser = new JavaScriptSerializer ();
525                         List<JavaScriptConverter> list = new List<JavaScriptConverter> ();
526                         list.Add (new MyJavaScriptConverter ());
527                         list.Add (new CultureInfoConverter ());
528                         ser.RegisterConverters (list);
529                         string result = ser.Serialize (new X [] { new X (), new X () });
530                         Assert.AreEqual ("{\"0\":1,\"1\":2}", result);
531                         result = ser.Serialize (Thread.CurrentThread.CurrentCulture);
532                 }
533
534                 [Test]
535                 public void TestDeserializeConverter1 () {
536                         JavaScriptSerializer serializer = new JavaScriptSerializer ();
537
538                         serializer.RegisterConverters (new JavaScriptConverter [] {new ListItemCollectionConverter()});
539
540                         ListBox ListBox1 = new ListBox ();
541                         ListBox1.Items.Add ("a1");
542                         ListBox1.Items.Add ("a2");
543                         ListBox1.Items.Add ("a3");
544
545                         string x = serializer.Serialize (ListBox1.Items);
546                         ListItemCollection recoveredList = serializer.Deserialize<ListItemCollection> (x);
547                         Assert.AreEqual (3, recoveredList.Count);
548                 }
549
550                 [Test]
551                 public void TestSerialize1 () {
552                         JavaScriptSerializer ser = new JavaScriptSerializer ();
553                         Assert.AreEqual("null", ser.Serialize(null));
554
555                         string js = ser.Serialize (1234);
556                         Assert.AreEqual ("1234", js);
557                         Assert.AreEqual (1234, ser.Deserialize<int> (js));
558                         js = ser.Serialize (1.1);
559                         Assert.AreEqual ("1.1", js);
560                         Assert.AreEqual (1.1f, ser.Deserialize<float> (js));
561                         char [] chars = "faskjhfasd0981234".ToCharArray ();
562                         js = ser.Serialize (chars);
563                         char[] actual = ser.Deserialize<char[]> (js);
564                         Assert.AreEqual (chars.Length, actual.Length);
565                         for (int i = 0; i < chars.Length; i++)
566                                 Assert.AreEqual (chars[i], actual[i]);
567
568                         string expected = @"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\""#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~""";
569                         string data = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
570
571                         string serRes = ser.Serialize (data);
572                         Assert.AreEqual (expected, serRes);
573                         string deserRes = ser.Deserialize<string> (serRes);
574                         Assert.AreEqual (data, deserRes);
575                 }
576
577                 [Test]
578                 [ExpectedException (typeof (ArgumentNullException))]
579                 [Category ("NotDotNet")]
580                 public void TestSerialize2 () {
581                         JavaScriptSerializer ser = new JavaScriptSerializer ();
582                         ser.Serialize ("aaa", (StringBuilder)null);
583                 }
584
585                 static readonly long InitialJavaScriptDateTicks = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
586
587                 [Test]
588                 public void TestSerializeDate () {
589                         JavaScriptSerializer ser = new JavaScriptSerializer ();
590                         DateTime now = new DateTime (633213894056010000L);
591
592                         string actual = ser.Serialize (now);
593                         DateTime dateTime = now.ToUniversalTime ();
594                         long javaScriptTicks = (dateTime.Ticks - InitialJavaScriptDateTicks) / (long) 10000;
595
596                         object dd = ser.DeserializeObject (@"""\/Datte(" + javaScriptTicks + @")\/""");
597                         Assert.AreEqual (@"""\/Date(" + javaScriptTicks + @")\/""", actual);
598                         Assert.AreEqual (now.ToUniversalTime(), ser.DeserializeObject (actual));
599                 }
600
601                 [Test]
602                 public void TestSerializeEnum () {
603                         JavaScriptSerializer ser = new JavaScriptSerializer ();
604                         string result = ser.Serialize (MyEnum.BBB);
605                         Assert.AreEqual ("1", result);
606                         Assert.AreEqual (MyEnum.BBB, ser.Deserialize<MyEnum> (result));
607                 }
608
609                 class MyJavaScriptConverter : JavaScriptConverter
610                 {
611                         public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
612                                 throw new Exception ("The method or operation is not implemented.");
613                         }
614
615                         public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
616                                 Array a = (Array) obj;
617                                 Dictionary<string, object> d = new Dictionary<string, object> ();
618                                 d.Add ("0", 1);
619                                 d.Add ("1", 2);
620                                 return d;
621                                 //throw new Exception ("The method or operation is not implemented.");
622                         }
623
624                         public override IEnumerable<Type> SupportedTypes {
625                                 get {
626                                         yield return typeof (X[]);
627                                 }
628                         }
629                 }
630
631                 sealed class CultureInfoConverter : JavaScriptConverter
632                 {
633                         static readonly Type typeofCultureInfo = typeof (CultureInfo);
634                         public override IEnumerable<Type> SupportedTypes {
635                                 get { yield return typeofCultureInfo; }
636                         }
637
638                         public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
639                                 throw new NotSupportedException ();
640                         }
641
642                         public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
643                                 CultureInfo ci = (CultureInfo)obj;
644                                 if (ci == null)
645                                         return null;
646                                 Dictionary<string, object> d = new Dictionary<string, object> ();
647                                 d.Add ("name", ci.Name);
648                                 d.Add ("numberFormat", ci.NumberFormat);
649                                 d.Add ("dateTimeFormat", ci.DateTimeFormat);
650                                 return d;
651                         }
652                 }
653
654                 public class ListItemCollectionConverter : JavaScriptConverter
655                 {
656                         public override IEnumerable<Type> SupportedTypes {
657                                 //Define the ListItemCollection as a supported type.
658                                 get { return new ReadOnlyCollection<Type> (new Type [] { typeof (ListItemCollection) }); }
659                         }
660
661                         public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
662                                 ListItemCollection listType = obj as ListItemCollection;
663
664                                 if (listType != null) {
665                                         // Create the representation.
666                                         Dictionary<string, object> result = new Dictionary<string, object> ();
667                                         ArrayList itemsList = new ArrayList ();
668                                         foreach (ListItem item in listType) {
669                                                 //Add each entry to the dictionary.
670                                                 Dictionary<string, object> listDict = new Dictionary<string, object> ();
671                                                 listDict.Add ("Value", item.Value);
672                                                 listDict.Add ("Text", item.Text);
673                                                 itemsList.Add (listDict);
674                                         }
675                                         result ["List"] = itemsList;
676
677                                         return result;
678                                 }
679                                 return new Dictionary<string, object> ();
680                         }
681
682                         public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
683                                 if (dictionary == null)
684                                         throw new ArgumentNullException ("dictionary");
685
686                                 if (type == typeof (ListItemCollection)) {
687                                         // Create the instance to deserialize into.
688                                         ListItemCollection list = new ListItemCollection ();
689
690                                         // Deserialize the ListItemCollection's items.
691                                         ArrayList itemsList = (ArrayList) dictionary ["List"];
692                                         for (int i = 0; i < itemsList.Count; i++)
693                                                 list.Add (serializer.ConvertToType<ListItem> (itemsList [i]));
694
695                                         return list;
696                                 }
697                                 return null;
698                         }
699                 }
700
701                 [Test]
702                 public void DeserializeObject () {
703                         object o = new JavaScriptSerializer ().DeserializeObject ("{\"Numeric\":0,\"Array\":[true,false,0]}");
704                         Assert.IsNotNull (o as Dictionary<string, object>, "type");
705                         Dictionary<string, object> dictionary = (Dictionary<string, object>) o;
706                         Assert.AreEqual (0, (int) dictionary ["Numeric"], "Numeric");
707                         Assert.IsNotNull (dictionary ["Array"] as object [], "Array type");
708                         object [] array = (object []) dictionary ["Array"];
709                         Assert.AreEqual (true, (bool) array [0], "array [0]");
710                         Assert.AreEqual (false, (bool) array [1], "array [1]");
711                         Assert.AreEqual (0, (int) array [2], "array [2]");
712                 }
713
714                 [Test]
715                 public void DeserializeObject2 () 
716                 {
717                         JavaScriptSerializer ser = new JavaScriptSerializer ();
718                         Y y = new Y ();
719                         string s = ser.Serialize (y);
720                         object y2 = ser.DeserializeObject (s);
721                         Assert.AreEqual (typeof (Dictionary<string, object>), y2.GetType (), "DeserializeObject to Dictionary");
722                 }
723
724                 [Test]
725                 public void DeserializeObject3 () 
726                 {
727                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver());
728                         Y y = new Y ();
729                         string s = ser.Serialize (y);
730                         object y2 = ser.DeserializeObject (s);
731                         Assert.AreEqual (typeof (Y), y2.GetType (), "DeserializeObject to Dictionary");
732                 }
733
734                 [Test]
735                 public void DeserializeObject4 () 
736                 {
737                         JavaScriptSerializer ser = new JavaScriptSerializer (new CustomResolver());
738                         Y y = new Y ();
739                         string s = ser.Serialize (y);
740                         object y2 = ser.DeserializeObject (s);
741                         Assert.AreEqual (typeof (Y), y2.GetType (), "DeserializeObject to Dictionary");
742                         Assert.AreEqual (1, CustomResolver.ResolvedIds.Count, "ResolvedIds Count");
743                         Assert.AreEqual ("Y", CustomResolver.ResolvedIds [0], "ResolvedIds.Y");
744                         Assert.AreEqual (1, CustomResolver.ResolvedTypes.Count, "ResolvedTypes Count");
745                         Assert.AreEqual ("Y", CustomResolver.ResolvedTypes [0], "ResolvedTypes.Y");
746                 }
747
748                 [Test]
749                 [ExpectedException(typeof(ArgumentNullException))]
750                 public void SerializeWithResolverDeserializeWithout () 
751                 {
752                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
753                         Y y = new Y ();
754                         string s = ser.Serialize (y);
755                         ser = new JavaScriptSerializer ();
756                         object y2 = ser.DeserializeObject (s);
757                 }
758
759                 [Test]
760                 public void SerializeWithoutResolverDeserializeWith ()
761                 {
762                         JavaScriptSerializer ser = new JavaScriptSerializer ();
763                         Y y = new Y ();
764                         string s = ser.Serialize (y);
765                         ser = new JavaScriptSerializer (new SimpleTypeResolver ());
766                         object y2 = ser.DeserializeObject (s);
767                         Assert.AreEqual (typeof (Dictionary<string, object>), y2.GetType (), "DeserializeObject to Dictionary");
768                 }
769
770                 class B
771                 {
772                         public int v1 = 15;
773                         public string s1 = "s1";
774                 }
775
776                 class D : B
777                 {
778                         public int v2 = 16;
779                         public string s2 = "s2";
780                 }
781
782                 class C
783                 {
784                         public B b1 = new B ();
785                         public B b2 = new D ();
786                 }
787
788                 [Test]
789                 public void SerializeDerivedType () 
790                 {
791                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
792                         B b = new D ();
793                         string s = ser.Serialize (b);
794                         B b2 = ser.Deserialize<B> (s);
795                         Assert.AreEqual (typeof (D), b2.GetType (), "Deserialize Derived Type");
796                 }
797
798                 [Test]
799                 public void SerializeDerivedType2 () 
800                 {
801                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
802                         B b = new D ();
803                         string s = ser.Serialize (b);
804                         B b2 = (B)ser.DeserializeObject (s);
805                         Assert.AreEqual (typeof (D), b2.GetType (), "Deserialize Derived Type");
806                 }
807
808                 [Test]
809                 public void SerializeContainedDerivedType () 
810                 {
811                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
812                         C c = new C ();
813                         string s = ser.Serialize (c);
814                         C c2 = ser.Deserialize<C> (s);
815                         Assert.AreEqual (typeof (C), c2.GetType (), "Deserialize Derived Type");
816                         Assert.AreEqual (typeof (D), c2.b2.GetType (), "Deserialize Derived Type");
817                 }
818
819                 [Test]
820                 public void SerializeContainedDerivedType2 () 
821                 {
822                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
823                         C c = new C ();
824                         string s = ser.Serialize (c);
825                         C c2 = (C)ser.DeserializeObject (s);
826                         Assert.AreEqual (typeof (C), c2.GetType (), "Deserialize Derived Type");
827                         Assert.AreEqual (typeof (D), c2.b2.GetType (), "Deserialize Derived Type");
828                 }
829
830                 [Test]
831                 public void SerializeWithTypeConverter () 
832                 {
833                         JavaScriptSerializer ser = new JavaScriptSerializer ();
834                         MyUri uri = new MyUri ("http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d", UriKind.RelativeOrAbsolute);
835                         string s = ser.Serialize (uri);
836                         MyUri uri2 = ser.Deserialize<MyUri> (s);
837                         Assert.AreEqual (uri, uri2);
838                 }
839
840                 [Test]
841                 public void SerializeWithTypeConverter2 () 
842                 {
843                         JavaScriptSerializer ser = new JavaScriptSerializer ();
844                         MyPointContainer pc = new MyPointContainer(new Point(15, 16));
845                         string s = ser.Serialize(pc);
846                         MyPointContainer pc2 = ser.Deserialize<MyPointContainer>(s);
847                 }
848                 
849                 [Test]
850                 public void MaxJsonLengthDeserializeObject () 
851                 {
852                         JavaScriptSerializer ser = new JavaScriptSerializer ();
853                         ser.MaxJsonLength = 16;
854                         object o = ser.DeserializeObject ("{s:'1234567890'}");
855                 }
856
857                 [Test]
858                 [ExpectedException(typeof(ArgumentException))]
859                 public void MaxJsonLengthDeserializeObjectToLong () 
860                 {
861                         JavaScriptSerializer ser = new JavaScriptSerializer ();
862                         ser.MaxJsonLength = 15;
863                         object o = ser.DeserializeObject ("{s:'1234567890'}");
864                 }
865
866                 [Test]
867                 public void MaxJsonLengthSerialize () 
868                 {
869                         JavaScriptSerializer ser = new JavaScriptSerializer ();
870                         ser.MaxJsonLength = 9;
871                         Y y = new Y ();
872                         string s = ser.Serialize (y);
873                 }
874
875                 [Test]
876                 [ExpectedException (typeof (InvalidOperationException))]
877                 public void MaxJsonLengthSerializeToLong () 
878                 {
879                         JavaScriptSerializer ser = new JavaScriptSerializer ();
880                         ser.MaxJsonLength = 8;
881                         Y y = new Y ();
882                         string s = ser.Serialize (y);
883                 }
884
885                 [Test]
886                 public void RecursionLimitDeserialize1 () 
887                 {
888                         JavaScriptSerializer ser = new JavaScriptSerializer ();
889                         ser.RecursionLimit = 3;
890                         YY yy = ser.Deserialize<YY> ("{\"Y1\":{\"BB\":10},\"Y2\":{\"BB\":10}}");
891                 }
892
893                 [Test]
894                 public void RecursionLimitDeserialize2 () 
895                 {
896                         JavaScriptSerializer ser = new JavaScriptSerializer ();
897                         ser.RecursionLimit = 2;
898                         YY yy = ser.Deserialize<YY> ("{\"Y1\":{},\"Y2\":{}}");
899                 }
900
901                 [Test]
902                 public void RecursionLimitDeserialize3 () 
903                 {
904                         JavaScriptSerializer ser = new JavaScriptSerializer ();
905                         ser.RecursionLimit = 1;
906                         object o = ser.DeserializeObject ("\"xxx\"");
907                 }
908
909                 [Test]
910                 [ExpectedException(typeof(ArgumentException))]
911                 public void RecursionLimitDeserializeToDeep () 
912                 {
913                         JavaScriptSerializer ser = new JavaScriptSerializer ();
914                         ser.RecursionLimit = 2;
915                         YY yy = ser.Deserialize<YY> ("{\"Y1\":{\"BB\":10},\"Y2\":{\"BB\":10}}");
916                 }
917
918                 [Test]
919                 public void RecursionLimitSerialize () 
920                 {
921                         JavaScriptSerializer ser = new JavaScriptSerializer ();
922                         ser.RecursionLimit = 3;
923                         YY yy = new YY();
924                         string s = ser.Serialize (yy);
925                 }
926
927                 [Test]
928                 [ExpectedException(typeof(ArgumentException))]
929                 public void RecursionLimitSerializeToDeep () 
930                 {
931                         JavaScriptSerializer ser = new JavaScriptSerializer ();
932                         ser.RecursionLimit = 2;
933                         YY yy = new YY ();
934                         string s = ser.Serialize (yy);
935                 }
936
937                 [Test]
938                 public void RecursionLimitSerialize2 () 
939                 {
940                         JavaScriptSerializer ser = new JavaScriptSerializer ();
941                         ser.RecursionLimit = 2;
942                         YY yy = new YY ();
943                         StringBuilder b = new StringBuilder ();
944                         bool caughtException = false;
945                         try {
946                                 ser.Serialize (yy, b);
947                         }
948                         catch {
949                                 caughtException = true;
950                         }
951                         Assert.IsTrue (caughtException, "RecursionLimitSerialize2 Expected an exception!");
952                         Assert.AreEqual ("{\"Y1\":{\"BB\":", b.ToString (), "RecursionLimitSerialize2");
953                 }
954
955                 [Test]
956                 public void SimpleTypeResolver () 
957                 {
958                         JavaScriptSerializer ser = new JavaScriptSerializer (new SimpleTypeResolver ());
959                         YY yy = new YY ();
960                         string s = ser.Serialize (yy);
961                         string expected = String.Format("\"__type\":\"{0}\"", yy.GetType().AssemblyQualifiedName);
962
963                         Assert.IsTrue (s.Contains (expected), "YY: expected {0} to contain {1}", s, expected);
964                         
965                         expected = String.Format ("\"__type\":\"{0}\"", yy.Y1.GetType ().AssemblyQualifiedName);
966                         Assert.IsTrue (s.Contains (expected), "Y: expected {0} to contain {1}", s, expected);
967                 }
968
969                 public class CustomResolver : JavaScriptTypeResolver
970                 {
971                         public CustomResolver () 
972                         {
973                                 Reset ();
974                         }
975
976                         public override Type ResolveType (string id) 
977                         {
978                                 ResolvedIds.Add (id);
979
980                                 switch (id) {
981                                 case "YY":
982                                         return typeof(YY);
983
984                                 case "Y":
985                                         return typeof (Y);
986
987                                 case "X":
988                                         return typeof (X);
989
990                                 case "int":
991                                         return typeof (int);
992
993                                 case "long":
994                                         return typeof (long);
995
996                                 case "string":
997                                         return typeof (string);
998
999                                 case "point":
1000                                         return typeof(Point);
1001                                 }
1002                                 return null;
1003                         }
1004
1005                         public override string ResolveTypeId (Type type) 
1006                         {
1007                                 if (type == null) {
1008                                         throw new ArgumentNullException ("type");
1009                                 }
1010
1011                                 ResolvedTypes.Add (type.Name);
1012
1013                                 if (type == typeof (YY))
1014                                         return "YY";
1015
1016                                 if (type == typeof (Y))
1017                                         return "Y";
1018
1019                                 if (type == typeof (X))
1020                                         return "X";
1021
1022                                 if (type == typeof (int))
1023                                         return "int";
1024
1025                                 if (type == typeof (long))
1026                                         return "long";
1027
1028                                 if (type == typeof (string))
1029                                         return "string";
1030
1031                                 if (type == typeof(Point))
1032                                         return "point";
1033
1034                                 return null;
1035                         }
1036
1037                         public static List<string> ResolvedTypes {
1038                                 get {
1039                                         if (resolvedTypes == null) {
1040                                                 resolvedTypes = new List<string> ();
1041                                         }
1042                                         return resolvedTypes;
1043                                 }
1044                         }
1045
1046                         public static List<string> ResolvedIds {
1047                                 get {
1048                                         if (resolvedIds == null) {
1049                                                 resolvedIds = new List<string> ();
1050                                         }
1051                                         return resolvedIds;
1052                                 }
1053                         }
1054
1055                         public static void Reset () 
1056                         {
1057                                 resolvedIds = null;
1058                                 resolvedTypes = null;
1059                         }
1060
1061                         private static List<string> resolvedTypes;
1062                         private static List<string> resolvedIds;
1063                 }
1064
1065                 [Test]
1066                 [NUnit.Framework.Category ("NotWorking")]
1067                 public void CustomTypeResolver ()
1068                 {
1069                         JavaScriptSerializer ser = new JavaScriptSerializer (new CustomResolver ());
1070                         X x = new X ();
1071                         x.Init ();
1072
1073                         string s = ser.Serialize (x);
1074
1075                         CustomResolver.Reset ();
1076                         X x1 = (X) ser.DeserializeObject (s);
1077                         Assert.IsTrue (x.Equals (x1), "x != x1");
1078
1079                         CustomResolver.Reset ();
1080                         X x2 = ser.Deserialize<X> (s);
1081                         Assert.IsTrue (x.Equals (x2), "x != x2");
1082                 }
1083
1084                 [Test]
1085                 public void InfinityAndNaN ()
1086                 {
1087                         JavaScriptSerializer ser = new JavaScriptSerializer ();
1088
1089                         double nan = Double.NaN;
1090                         string s = ser.Serialize (nan);
1091                         Assert.AreEqual (s, "NaN", "#A1");
1092                         nan = (double)ser.DeserializeObject (s);
1093                         Assert.AreEqual (Double.NaN, nan, "#A2");
1094                         nan = (double)ser.Deserialize <double> (s);
1095                         Assert.AreEqual (Double.NaN, nan, "#A3");
1096                         
1097                         double infinity = Double.PositiveInfinity;
1098                         s = ser.Serialize (infinity);
1099                         Assert.AreEqual (s, "Infinity", "#B1");
1100                         infinity = (double)ser.DeserializeObject (s);
1101                         Assert.AreEqual (Double.PositiveInfinity, infinity, "#B2");
1102                         infinity = ser.Deserialize <double> (s);
1103                         Assert.AreEqual (Double.PositiveInfinity, infinity, "#B3");
1104                         
1105                         infinity = Double.NegativeInfinity;
1106                         s = ser.Serialize (infinity);
1107                         Assert.AreEqual (s, "-Infinity", "#C1");
1108                         infinity = (double)ser.DeserializeObject (s);
1109                         Assert.AreEqual (Double.NegativeInfinity, infinity, "#C2");
1110                         infinity = ser.Deserialize <double> (s);
1111                         Assert.AreEqual (Double.NegativeInfinity, infinity, "#C3");
1112
1113                         var dict = new Dictionary <string, object> ();
1114                         dict.Add ("A", Double.NaN);
1115                         dict.Add ("B", Double.PositiveInfinity);
1116                         dict.Add ("C", Double.NegativeInfinity);
1117                         s = ser.Serialize (dict);
1118                         Assert.AreEqual ("{\"A\":NaN,\"B\":Infinity,\"C\":-Infinity}", s, "#D1");
1119                         
1120                         dict = (Dictionary <string, object>)ser.DeserializeObject (s);
1121                         Assert.AreEqual (Double.NaN, dict ["A"], "#D2");
1122                         Assert.AreEqual (Double.PositiveInfinity, dict ["B"], "#D3");
1123                         Assert.AreEqual (Double.NegativeInfinity, dict ["C"], "#D4");
1124
1125                         dict = (Dictionary <string, object>)ser.Deserialize <Dictionary <string, object>> (s);
1126                         Assert.AreEqual (Double.NaN, dict ["A"], "#D5");
1127                         Assert.AreEqual (Double.PositiveInfinity, dict ["B"], "#D6");
1128                         Assert.AreEqual (Double.NegativeInfinity, dict ["C"], "#D7");
1129
1130                         var arr = new ArrayList () {
1131                                         Double.NaN,
1132                                         Double.PositiveInfinity,
1133                                         Double.NegativeInfinity};
1134                         s = ser.Serialize (arr);
1135                         Assert.AreEqual ("[NaN,Infinity,-Infinity]", s, "#E1");
1136
1137                         object[] arr2 = (object[])ser.DeserializeObject (s);
1138                         Assert.AreEqual (3, arr2.Length, "#E2");
1139                         Assert.AreEqual (Double.NaN, arr2 [0], "#E3");
1140                         Assert.AreEqual (Double.PositiveInfinity, arr2 [1], "#E4");
1141                         Assert.AreEqual (Double.NegativeInfinity, arr2 [2], "#E5");
1142
1143                         arr = ser.Deserialize <ArrayList> (s);
1144                         Assert.AreEqual (3, arr.Count, "#E6");
1145                         Assert.AreEqual (Double.NaN, arr [0], "#E7");
1146                         Assert.AreEqual (Double.PositiveInfinity, arr [1], "#E8");
1147                         Assert.AreEqual (Double.NegativeInfinity, arr [2], "#E9");
1148                 }
1149
1150                 [Test]
1151                 public void StandalonePrimitives ()
1152                 {
1153                         JavaScriptSerializer ser = new JavaScriptSerializer ();
1154
1155                         object o;
1156                         int i;
1157                         
1158                         o = ser.DeserializeObject ("1");
1159                         Assert.AreEqual (typeof (global::System.Int32), o.GetType (), "#A1");
1160                         i = (int)o;
1161                         Assert.AreEqual (1, i, "#A2");
1162                         o =ser.DeserializeObject ("-1");
1163                         Assert.AreEqual (typeof (global::System.Int32), o.GetType (), "#A3");
1164                         i = (int)o;
1165                         Assert.AreEqual (-1, i, "#A4");
1166                         
1167                         o = ser.DeserializeObject ("2147483649");
1168                         Assert.AreEqual (typeof (global::System.Int64), o.GetType (), "#B1");
1169                         long l = (long)o;
1170                         Assert.AreEqual (2147483649, l, "#B2");
1171                         o = ser.DeserializeObject ("-2147483649");
1172                         Assert.AreEqual (typeof (global::System.Int64), o.GetType (), "#B3");
1173                         l = (long)o;
1174                         Assert.AreEqual (-2147483649, l, "#B4");
1175
1176                         o = ser.DeserializeObject ("9223372036854775808");
1177                         Assert.AreEqual (typeof (global::System.Decimal), o.GetType (), "#C1");
1178                         decimal d = (decimal)o;
1179                         Assert.AreEqual (9223372036854775808m, d, "#C2");
1180                         o = ser.DeserializeObject ("-9223372036854775809");
1181                         Assert.AreEqual (typeof (global::System.Decimal), o.GetType (), "#C3");
1182                         d = (decimal)o;
1183                         Assert.AreEqual (-9223372036854775809m, d, "#C4");
1184
1185                         o = ser.DeserializeObject ("79228162514264337593543950336");
1186                         Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#D1");
1187                         double db = (double)o;
1188                         Assert.AreEqual (79228162514264337593543950336.0, db, "#D2");
1189                         o = ser.DeserializeObject ("-79228162514264337593543950336");
1190                         Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#D3");
1191                         db = (double)o;
1192                         Assert.AreEqual (-79228162514264337593543950336.0, db, "#D4");
1193                         
1194                         o = ser.DeserializeObject ("\"test string\"");
1195                         Assert.AreEqual (typeof (global::System.String), o.GetType (), "#E1");
1196                         string s = (string)o;
1197                         Assert.AreEqual ("test string", s, "#E2");
1198
1199                         o = ser.DeserializeObject ("true");
1200                         Assert.AreEqual (typeof (global::System.Boolean), o.GetType (), "#F1");
1201                         bool b = (bool)o;
1202                         Assert.AreEqual (true, b, "#F2");
1203
1204                         o = ser.DeserializeObject ("false");
1205                         Assert.AreEqual (typeof (global::System.Boolean), o.GetType (), "#F3");
1206                         b = (bool)o;
1207                         Assert.AreEqual (false, b, "#F4");
1208
1209                         o = ser.DeserializeObject ("-1.7976931348623157E+308");
1210                         Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#G1");
1211                         db = (double)o;
1212                         Assert.AreEqual (Double.MinValue, db, "#G2");
1213
1214                         o = ser.DeserializeObject ("1.7976931348623157E+308");
1215                         Assert.AreEqual (typeof (global::System.Double), o.GetType (), "#G3");
1216                         db = (double)o;
1217                         Assert.AreEqual (Double.MaxValue, db, "#G4");
1218                 }
1219
1220                 class SomeDict : IDictionary<string, object>
1221                 {
1222                         void IDictionary<string, object>.Add (string key, object value) {
1223                                 throw new NotSupportedException ();
1224                         }
1225
1226                         bool IDictionary<string, object>.ContainsKey (string key) {
1227                                 throw new NotSupportedException ();
1228                         }
1229
1230                         ICollection<string> IDictionary<string, object>.Keys {
1231                                 get { throw new NotSupportedException (); }
1232                         }
1233
1234                         bool IDictionary<string, object>.Remove (string key) {
1235                                 throw new NotSupportedException ();
1236                         }
1237
1238                         bool IDictionary<string, object>.TryGetValue (string key, out object value) {
1239                                 throw new NotSupportedException ();
1240                         }
1241
1242                         ICollection<object> IDictionary<string, object>.Values {
1243                                 get { throw new NotSupportedException (); }
1244                         }
1245
1246                         object IDictionary<string, object>.this [string key] {
1247                                 get { throw new NotSupportedException (); }
1248                                 set { throw new NotSupportedException (); }
1249                         }
1250
1251                         void ICollection<KeyValuePair<string, object>>.Add (KeyValuePair<string, object> item) {
1252                                 throw new NotSupportedException ();
1253                         }
1254
1255                         void ICollection<KeyValuePair<string, object>>.Clear () {
1256                                 throw new NotSupportedException ();
1257                         }
1258
1259                         bool ICollection<KeyValuePair<string, object>>.Contains (KeyValuePair<string, object> item) {
1260                                 throw new NotSupportedException ();
1261                         }
1262
1263                         void ICollection<KeyValuePair<string, object>>.CopyTo (KeyValuePair<string, object> [] array, int arrayIndex) {
1264                                 throw new NotSupportedException ();
1265                         }
1266
1267                         int ICollection<KeyValuePair<string, object>>.Count {
1268                                 get { throw new NotSupportedException (); }
1269                         }
1270
1271                         bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
1272                                 get { throw new NotSupportedException (); }
1273                         }
1274
1275                         bool ICollection<KeyValuePair<string, object>>.Remove (KeyValuePair<string, object> item) {
1276                                 throw new NotSupportedException ();
1277                         }
1278
1279                         IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator () {
1280                                 return GetEnumerator ();
1281                         }
1282
1283                         IEnumerator IEnumerable.GetEnumerator () {
1284                                 return ((IEnumerable<KeyValuePair<string, object>>) this).GetEnumerator ();
1285                         }
1286
1287                         protected IEnumerator<KeyValuePair<string, object>> GetEnumerator () {
1288                                 yield return new KeyValuePair<string, object> ("hello", "world");
1289                         }
1290                 }
1291
1292                 [Test] //bug #424704
1293                 public void NonGenericClassImplementingClosedGenericIDictionary ()
1294                 {
1295                         JavaScriptSerializer ser = new JavaScriptSerializer ();
1296
1297                         SomeDict dictIn = new SomeDict ();
1298
1299                         string s = ser.Serialize (dictIn);
1300
1301                         Dictionary<string, object> dictOut = ser.Deserialize<Dictionary<string, object>> (s);
1302                         Assert.AreEqual (dictOut.Count, 1, "#1");
1303                         Assert.AreEqual (dictOut["hello"], "world", "#2");
1304                 }
1305
1306                 [Test]
1307                 public void ConvertToIDictionary ()
1308                 {
1309                         JavaScriptSerializer jss = new JavaScriptSerializer ();
1310                         string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1311                         object input = jss.Deserialize<IDictionary>(json);
1312                         IDictionary o = jss.ConvertToType<IDictionary>(input);
1313
1314                         Assert.IsTrue (o != null, "#A1");
1315                         Assert.AreEqual (typeof (Dictionary <string, object>), o.GetType (), "#A2");
1316                 }
1317
1318                 [Test]
1319                 public void ConvertToGenericIDictionary ()
1320                 {
1321                         JavaScriptSerializer jss = new JavaScriptSerializer ();
1322                         string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1323
1324                         object input = jss.Deserialize<IDictionary>(json);
1325                         
1326                         IDictionary <string, object> o = jss.ConvertToType<IDictionary <string, object>>(input);
1327                         Assert.IsTrue (o != null, "#A1");
1328                         Assert.AreEqual (typeof (Dictionary <string, object>), o.GetType (), "#A2");
1329
1330                         IDictionary <object, object> o1 = jss.ConvertToType<IDictionary <object, object>>(input);
1331                         Assert.IsTrue (o1 != null, "#B1");
1332                         Assert.AreEqual (typeof (Dictionary <object, object>), o1.GetType (), "#B2");
1333                 }
1334
1335                 [Test]
1336                 [ExpectedException (typeof (InvalidOperationException))]
1337                 public void ConvertToGenericIDictionary_InvalidDefinition ()
1338                 {
1339                         JavaScriptSerializer jss = new JavaScriptSerializer ();
1340                         string json = "{\"node\":{\"Text\":\"Root Node\",\"Value\":null,\"ExpandMode\":3,\"NavigateUrl\":null,\"PostBack\":true,\"DisabledCssClass\":null,\"SelectedCssClass\":null,\"HoveredCssClass\":null,\"ImageUrl\":null,\"HoveredImageUrl\":null,\"DisabledImageUrl\":null,\"ExpandedImageUrl\":null,\"ContextMenuID\":\"\"},\"context\":{\"NumberOfNodes\":1000}}";
1341
1342                         object input = jss.Deserialize<IDictionary>(json);
1343                         IDictionary <int, object> o = jss.ConvertToType<IDictionary <int, object>>(input);
1344                 }
1345
1346                 [Test (Description="Bug #655474")]
1347                 public void TestRelativeUri()
1348                 {
1349                         JavaScriptSerializer ser = new JavaScriptSerializer();
1350                         Uri testUri = new Uri("/lala/123", UriKind.Relative);
1351                         StringBuilder sb = new StringBuilder();
1352
1353                         ser.Serialize(testUri, sb);
1354                         Assert.AreEqual ("\"/lala/123\"", sb.ToString ());
1355                 }
1356                 
1357                 [Test]
1358                 public void DeserializeDictionaryOfArrayList ()
1359                 {
1360                         var ser = new JavaScriptSerializer ();
1361                         string test1 = "{\"key\":{\"subkey\":\"subval\"}}";
1362                         string test2 = "{\"key\":[{\"subkey\":\"subval\"}]}";
1363
1364                         var ret1 = ser.Deserialize<Dictionary<string, object>>(test1);
1365                         Assert.AreEqual (typeof (Dictionary<string, object>), ret1.GetType (), "#1.1");
1366                         var ret1v = ret1 ["key"];
1367                         Assert.AreEqual (typeof (Dictionary<string, object>), ret1v.GetType (), "#1.2");
1368                         var ret1vd = (IDictionary<string,object>) ret1v;
1369                         Assert.AreEqual ("subval", ret1vd ["subkey"], "#1.3");
1370
1371                         var ret2 = ser.Deserialize<Dictionary<string, object>>(test2);
1372                         Assert.AreEqual (typeof (Dictionary<string, object>), ret2.GetType (), "#2.1");
1373                         var ret2v = ret2 ["key"];
1374                         Assert.AreEqual (typeof (ArrayList), ret2v.GetType (), "#2.2");
1375                         var ret2va = (ArrayList) ret2v;
1376                         Assert.AreEqual (typeof (Dictionary<string, object>), ret2va [0].GetType (), "#2.3");
1377                         var ret2vad = (IDictionary<string,object>) ret2va [0];
1378                         Assert.AreEqual ("subval", ret2vad ["subkey"], "#2.4");
1379                 }
1380                 
1381                 class ClassWithNullableEnum
1382                 {
1383                         public MyEnum? Value { get; set; }
1384                 }
1385                 
1386                 [Test]
1387                 public void DeserializeNullableEnum ()
1388                 {               
1389                         var jsonValues = new Dictionary<string, MyEnum?> {
1390                                 { "{\"Value\":0}", MyEnum.AAA},
1391                                 { "{\"Value\":\"0\"}", MyEnum.AAA},
1392                                 { "{\"Value\":null}", null}
1393                         };
1394                         
1395                         var ser = new JavaScriptSerializer ();
1396                         
1397                         foreach (var kv in jsonValues)
1398                         {
1399                                 var obj = ser.Deserialize<ClassWithNullableEnum> (kv.Key);
1400                                 Assert.AreEqual (kv.Value, obj.Value);
1401                         }
1402                 }
1403
1404                 [Test]
1405                 public void DeserializeStringWithNewline ()
1406                 {
1407                         JavaScriptSerializer serializer = new JavaScriptSerializer ();
1408                         string json_with_newline = @"
1409         [
1410           {
1411           content:""      
1412 <div id=\""calendar\""><div>   
1413         ""   
1414           }
1415         ]
1416     ";
1417                         serializer.DeserializeObject (json_with_newline);
1418                 }
1419         }
1420 }