implementation of converters for serialization
[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
42
43 namespace Tests.System.Web.Script.Serialization
44 {
45         [TestFixture]
46         public class JavaScriptSerializerTest
47         {
48                 class bug
49                 {
50                         //public DateTime dt;
51                         //public DateTime dt1;
52                         public DateTime dt2;
53                         public bool bb;
54                         //Hashtable hash;
55
56                         public void Init() {
57                                 //dt = DateTime.MaxValue;
58                                 //dt1 = DateTime.MinValue;
59                                 dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
60                                 bb = true;
61                                 //hash = new Hashtable ();
62                                 //hash.Add ("mykey", 1);
63                         }
64
65                         public override bool Equals (object obj) {
66                                 if (!(obj is bug))
67                                         return false;
68                                 JavaScriptSerializerTest.FieldsEqual (this, obj);
69                                 return true;
70                         }
71                 }
72                 class X
73                 {
74                         int x = 5;
75                         //int y;
76                         ulong _bb;
77                         Y[] _yy;
78                         Y [] _yyy = new Y [] { new Y (), new Y () };
79                         public int z;
80                         public char ch;
81                         public char ch_null;
82                         public string str;
83                         public byte b;
84                         public sbyte sb;
85                         public short sh;
86                         public ushort ush;
87                         public int i;
88                         public uint ui;
89                         public long l;
90                         public ulong ul;
91                         
92                         public float f;
93                         public float f1;
94                         public float f2;
95                         public float f3;
96                         public float f4;
97
98                         public double d;
99                         public double d1;
100                         public double d2;
101                         public double d3;
102                         public double d4;
103
104                         public decimal de;
105                         public decimal de1;
106                         public decimal de2;
107                         public decimal de3;
108                         public decimal de4;
109
110                         
111
112                         public Guid g;
113                         
114                         public Nullable<bool> nb;
115                         public DBNull dbn;
116                         IEnumerable<int> enum_int;
117                         IEnumerable enum_int1;
118                         public Uri uri;
119                         public Dictionary<string, Y> hash;
120
121                         public void Init () {
122                                 //y = 6;
123                                 _bb = ulong.MaxValue - 5;
124                                 _yy = new Y [] { new Y (), new Y () };
125                                 z = 8;
126                                 ch = (char) 0xFF56;
127                                 ch_null = '\0';
128                                 str = "\uFF56\uFF57\uF58FF59g";
129                                 b = 253;
130                                 sb = -48;
131                                 sh = short.MinValue + 28;
132                                 ush = ushort.MaxValue - 24;
133                                 i = -234235453;
134                                 ui = uint.MaxValue - 234234;
135                                 l = long.MinValue + 28;
136                                 ul = ulong.MaxValue - 3;
137
138                                 f = float.NaN;
139                                 f1 = float.NegativeInfinity;
140                                 f2 = float.PositiveInfinity;
141                                 f3 = float.MinValue;
142                                 f4 = float.MaxValue;
143
144                                 d = double.NaN;
145                                 d1 = double.NegativeInfinity;
146                                 d2 = double.PositiveInfinity;
147                                 d3 = double.MinValue;
148                                 d4 = double.MaxValue;
149
150                                 de = decimal.MinusOne;
151                                 de1 = decimal.Zero;
152                                 de2 = decimal.One;
153                                 de3 = decimal.MinValue;
154                                 de4 = decimal.MaxValue;
155
156                                 g = new Guid (234, 2, 354, new byte [] { 1, 2, 3, 4, 5, 6, 7, 8 });
157                                 
158                                 nb = null;
159                                 dbn = null;
160
161                                 enum_int = new List<int> (MyEnum);
162                                 enum_int1 = new ArrayList ();
163                                 foreach (object obj in MyEnum1)
164                                         ((ArrayList) enum_int1).Add (obj);
165                                 uri = new Uri ("http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d", UriKind.RelativeOrAbsolute);
166
167                                 hash = new Dictionary<string, Y> ();
168                                 Y y = new Y ();
169                                 hash ["mykey"] = y;
170                         }
171
172                         public IEnumerable<int> MyEnum {
173                                 get {
174                                         yield return 1;
175                                         yield return 10;
176                                         yield return 345;
177                                 }
178
179                                 set {
180                                         enum_int = value;
181                                 }
182                         }
183
184                         public IEnumerable MyEnum1 {
185                                 get {
186                                         yield return 1;
187                                         yield return 10;
188                                         yield return 345;
189                                 }
190
191                                 set {
192                                         enum_int1 = value;
193                                 }
194                         }
195
196                         public int AA {
197                                 get { return x; }
198                         }
199
200                         public Y[] AA1 {
201                                 get { return _yyy; }
202                         }
203
204                         public ulong BB {
205                                 get { return _bb; }
206                                 set { _bb = value; }
207                         }
208
209                         public Y[] YY {
210                                 get { return _yy; }
211                                 set { _yy = value; }
212                         }
213
214                         public override bool Equals (object obj) {
215                                 if (!(obj is X))
216                                         return false;
217                                 JavaScriptSerializerTest.FieldsEqual (this, obj);
218                                 return true;
219                         }
220                 }
221
222                 class Y
223                 {
224
225                         long _bb = 10;
226
227                         public long BB {
228                                 get { return _bb; }
229                                 set { _bb = value; }
230                         }
231
232                         public override bool Equals (object obj) {
233                                 if (!(obj is Y))
234                                         return false;
235                                 JavaScriptSerializerTest.FieldsEqual(this, obj);
236                                 return true;
237                         }
238                 }
239                 [Test]
240                 public void TestDefaults () {
241                         JavaScriptSerializer ser = new JavaScriptSerializer ();
242                         Assert.AreEqual (2097152, ser.MaxJsonLength);
243                         Assert.AreEqual (100, ser.RecursionLimit);
244                         //List<JavaScriptConverter> l = new List<JavaScriptConverter> ();
245                         //l.Add (new MyJavaScriptConverter ());
246                         //ser.RegisterConverters (l);
247                         //string x = ser.Serialize (new X [] { new X (), new X () });
248                         //string s = ser.Serialize (new X());
249                         //"{\"BB\":10,\"__type\":\"Tests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\"}"
250                         //X x = ser.Deserialize<X> (s);
251                         //object ddd = typeof (Y).GetMember ("BB");
252                         //object x1 = ser.Deserialize<X []> (null);
253                         //object x2 = ser.Deserialize<X []> ("");
254                         //object d = ser.Deserialize<X[]> (x);
255                 }
256
257                 [Test]
258                 public void TestDeserialize () {
259                         JavaScriptSerializer ser = new JavaScriptSerializer ();
260                         Assert.IsNull (ser.Deserialize<X> (""));
261
262                         X s = new X ();
263                         s.Init ();
264                         string x = ser.Serialize (s);
265                         X n = ser.Deserialize<X> (x);
266                         Assert.AreEqual (s, n);
267
268                         //string json = "\\uFF56";
269                         //string result = ser.Deserialize<string> (json);
270                         //Assert.AreEqual ("\uFF56", result);
271
272                         //object oo = ser.DeserializeObject ("{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}");
273                 }
274
275                 [Test]
276                 [Category("NotWorking")]
277                 public void TestDeserializeBugs () {
278                         JavaScriptSerializer ser = new JavaScriptSerializer ();
279
280                         bug s = new bug ();
281                         s.Init ();
282                         string x = ser.Serialize (s);
283                         bug n = ser.Deserialize<bug> (x);
284                         Assert.AreEqual (s, n);
285
286                         // Should check correctness with .Net GA:
287                         //js = ser.Serialize (Color.Red);
288                         //Color ccc = ser.Deserialize<Color> (js);
289                         //string xml = @"<root><node attr=""xxx""/></root>";
290
291                         //XmlDocument doc = new XmlDocument ();
292                         //doc.LoadXml (xml);
293                         //string js = ser.Serialize (doc);
294                         //DataTable table = new DataTable();
295                         //table.Columns.Add ("col1", typeof (int));
296                         //table.Columns.Add ("col2", typeof (float));
297                         //table.Rows.Add (1, 1f);
298                         //table.Rows.Add (234234, 2.4f);
299
300                         //string js = ser.Serialize (table);
301                 }
302
303                 static void FieldsEqual (object expected, object actual) {
304                         Assert.AreEqual (expected.GetType (), actual.GetType ());
305                         FieldInfo [] infos = expected.GetType ().GetFields (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
306                         foreach (FieldInfo info in infos) {
307                                 object value1 = info.GetValue (expected);
308                                 object value2 = info.GetValue (actual);
309                                 if (value1 is IEnumerable) {
310                                         IEnumerator yenum = ((IEnumerable) value2).GetEnumerator ();
311                                         int index = -1;
312                                         foreach (object x in (IEnumerable) value1) {
313                                                 if (!yenum.MoveNext ())
314                                                         Assert.Fail (info.Name + " index:" + index);
315                                                 index++;
316                                                 if (x is DictionaryEntry) {
317                                                         DictionaryEntry entry = (DictionaryEntry)x;
318                                                         IDictionary dict = (IDictionary) value2;
319                                                         Assert.AreEqual (entry.Value, dict [entry.Key], info.Name + ", key:" + entry.Key);
320                                                 }
321                                                 else
322                                                         Assert.AreEqual (x, yenum.Current, info.Name + ", index:" + index);
323                                         }
324                                         Assert.IsFalse (yenum.MoveNext (), info.Name);
325                                         continue;
326                                 }
327                                 Assert.AreEqual (value1, value2, info.Name);
328                         }
329
330                 }
331
332                 [Test]
333                 [ExpectedException (typeof (ArgumentNullException))]
334                 public void TestDeserialize1 () {
335                         JavaScriptSerializer ser = new JavaScriptSerializer ();
336                         ser.Deserialize<string> (null);
337                 }
338
339                 [Test]
340                 [ExpectedException (typeof (ArgumentNullException))]
341                 public void TestDeserializeNullConverter () {
342                         JavaScriptSerializer ser = new JavaScriptSerializer ();
343                         ser.RegisterConverters (null);
344                 }
345
346                 [Test]
347                 public void TestDeserializeConverter () {
348                         JavaScriptSerializer ser = new JavaScriptSerializer ();
349                         List<JavaScriptConverter> list = new List<JavaScriptConverter> ();
350                         list.Add (new MyJavaScriptConverter ());
351                         ser.RegisterConverters (list);
352                         string result = ser.Serialize (new X [] { new X (), new X () });
353                         Assert.AreEqual ("{\"0\":1,\"1\":2}", result);
354                 }
355
356                 [Test]
357                 public void TestSerialize1 () {
358                         JavaScriptSerializer ser = new JavaScriptSerializer ();
359                         Assert.AreEqual("null", ser.Serialize(null));
360
361                         string js = ser.Serialize (1234);
362                         Assert.AreEqual ("1234", js);
363                         Assert.AreEqual (1234, ser.Deserialize<int> (js));
364                         js = ser.Serialize (1.1);
365                         Assert.AreEqual ("1.1", js);
366                         Assert.AreEqual (1.1f, ser.Deserialize<float> (js));
367                         char [] chars = "faskjhfasd0981234".ToCharArray ();
368                         js = ser.Serialize (chars);
369                         char[] actual = ser.Deserialize<char[]> (js);
370                         Assert.AreEqual (chars.Length, actual.Length);
371                         for (int i = 0; i < chars.Length; i++)
372                                 Assert.AreEqual (chars[i], actual[i]);
373                 }
374
375                 [Test]
376                 [ExpectedException (typeof (ArgumentNullException))]
377                 public void TestSerialize2 () {
378                         JavaScriptSerializer ser = new JavaScriptSerializer ();
379                         ser.Serialize ("aaa", null);
380                 }
381
382                 class MyJavaScriptConverter : JavaScriptConverter
383                 {
384                         public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
385                                 throw new Exception ("The method or operation is not implemented.");
386                         }
387
388                         public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
389                                 Array a = (Array) obj;
390                                 Dictionary<string, object> d = new Dictionary<string, object> ();
391                                 d.Add ("0", 1);
392                                 d.Add ("1", 2);
393                                 return d;
394                                 //throw new Exception ("The method or operation is not implemented.");
395                         }
396
397                         public override IEnumerable<Type> SupportedTypes {
398                                 get {
399                                         yield return typeof (X[]);
400                                 }
401                         }
402                 }
403         }
404 }