2 // JavaScriptSerializer.cs
5 // Konstantin Triger <kostat@mainsoft.com>
7 // (C) 2007 Mainsoft, Inc. http://www.mainsoft.com
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
31 using System.Collections.Generic;
33 using NUnit.Framework;
34 using System.Web.Script.Serialization;
35 using System.Reflection;
36 using System.Collections;
38 using ComponentModel = System.ComponentModel;
39 using System.Globalization;
40 using System.Threading;
43 namespace Tests.System.Web.Script.Serialization
46 public class JavaScriptSerializerTest
51 //public DateTime dt1;
57 //dt = DateTime.MaxValue;
58 //dt1 = DateTime.MinValue;
59 dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
61 //hash = new Hashtable ();
62 //hash.Add ("mykey", 1);
65 public override bool Equals (object obj) {
68 JavaScriptSerializerTest.FieldsEqual (this, obj);
78 Y [] _yyy = new Y [] { new Y (), new Y () };
114 public Nullable<bool> nb;
116 IEnumerable<int> enum_int;
117 IEnumerable enum_int1;
119 public Dictionary<string, Y> hash;
121 public void Init () {
123 _bb = ulong.MaxValue - 5;
124 _yy = new Y [] { new Y (), new Y () };
128 str = "\uFF56\uFF57\uF58FF59g";
131 sh = short.MinValue + 28;
132 ush = ushort.MaxValue - 24;
134 ui = uint.MaxValue - 234234;
135 l = long.MinValue + 28;
136 ul = ulong.MaxValue - 3;
139 f1 = float.NegativeInfinity;
140 f2 = float.PositiveInfinity;
145 d1 = double.NegativeInfinity;
146 d2 = double.PositiveInfinity;
147 d3 = double.MinValue;
148 d4 = double.MaxValue;
150 de = decimal.MinusOne;
153 de3 = decimal.MinValue;
154 de4 = decimal.MaxValue;
156 g = new Guid (234, 2, 354, new byte [] { 1, 2, 3, 4, 5, 6, 7, 8 });
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);
167 hash = new Dictionary<string, Y> ();
172 public IEnumerable<int> MyEnum {
184 public IEnumerable MyEnum1 {
214 public override bool Equals (object obj) {
217 JavaScriptSerializerTest.FieldsEqual (this, obj);
232 public override bool Equals (object obj) {
235 JavaScriptSerializerTest.FieldsEqual(this, obj);
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);
258 public void TestDeserialize () {
259 JavaScriptSerializer ser = new JavaScriptSerializer ();
260 Assert.IsNull (ser.Deserialize<X> (""));
264 string x = ser.Serialize (s);
265 X n = ser.Deserialize<X> (x);
266 Assert.AreEqual (s, n);
268 //string json = "\\uFF56";
269 //string result = ser.Deserialize<string> (json);
270 //Assert.AreEqual ("\uFF56", result);
272 //object oo = ser.DeserializeObject ("{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}");
276 [Category("NotWorking")]
277 public void TestDeserializeBugs () {
278 JavaScriptSerializer ser = new JavaScriptSerializer ();
282 string x = ser.Serialize (s);
283 bug n = ser.Deserialize<bug> (x);
284 Assert.AreEqual (s, n);
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>";
291 //XmlDocument doc = new XmlDocument ();
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);
300 //string js = ser.Serialize (table);
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 ();
312 foreach (object x in (IEnumerable) value1) {
313 if (!yenum.MoveNext ())
314 Assert.Fail (info.Name + " index:" + 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);
322 Assert.AreEqual (x, yenum.Current, info.Name + ", index:" + index);
324 Assert.IsFalse (yenum.MoveNext (), info.Name);
327 Assert.AreEqual (value1, value2, info.Name);
333 [ExpectedException (typeof (ArgumentNullException))]
334 public void TestDeserialize1 () {
335 JavaScriptSerializer ser = new JavaScriptSerializer ();
336 ser.Deserialize<string> (null);
340 [ExpectedException (typeof (ArgumentNullException))]
341 public void TestDeserializeNullConverter () {
342 JavaScriptSerializer ser = new JavaScriptSerializer ();
343 ser.RegisterConverters (null);
347 public void TestDeserializeConverter () {
348 JavaScriptSerializer ser = new JavaScriptSerializer ();
349 List<JavaScriptConverter> list = new List<JavaScriptConverter> ();
350 list.Add (new MyJavaScriptConverter ());
351 list.Add (new CultureInfoConverter ());
352 ser.RegisterConverters (list);
353 string result = ser.Serialize (new X [] { new X (), new X () });
354 Assert.AreEqual ("{\"0\":1,\"1\":2}", result);
355 result = ser.Serialize (Thread.CurrentThread.CurrentCulture);
359 public void TestSerialize1 () {
360 JavaScriptSerializer ser = new JavaScriptSerializer ();
361 Assert.AreEqual("null", ser.Serialize(null));
363 string js = ser.Serialize (1234);
364 Assert.AreEqual ("1234", js);
365 Assert.AreEqual (1234, ser.Deserialize<int> (js));
366 js = ser.Serialize (1.1);
367 Assert.AreEqual ("1.1", js);
368 Assert.AreEqual (1.1f, ser.Deserialize<float> (js));
369 char [] chars = "faskjhfasd0981234".ToCharArray ();
370 js = ser.Serialize (chars);
371 char[] actual = ser.Deserialize<char[]> (js);
372 Assert.AreEqual (chars.Length, actual.Length);
373 for (int i = 0; i < chars.Length; i++)
374 Assert.AreEqual (chars[i], actual[i]);
376 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{|}~""";
377 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{|}~";
379 string serRes = ser.Serialize (data);
380 Assert.AreEqual (expected, serRes);
381 string deserRes = ser.Deserialize<string> (serRes);
382 Assert.AreEqual (data, deserRes);
386 [ExpectedException (typeof (ArgumentNullException))]
387 public void TestSerialize2 () {
388 JavaScriptSerializer ser = new JavaScriptSerializer ();
389 ser.Serialize ("aaa", null);
392 class MyJavaScriptConverter : JavaScriptConverter
394 public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
395 throw new Exception ("The method or operation is not implemented.");
398 public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
399 Array a = (Array) obj;
400 Dictionary<string, object> d = new Dictionary<string, object> ();
404 //throw new Exception ("The method or operation is not implemented.");
407 public override IEnumerable<Type> SupportedTypes {
409 yield return typeof (X[]);
414 sealed class CultureInfoConverter : JavaScriptConverter
416 static readonly Type typeofCultureInfo = typeof (CultureInfo);
417 public override IEnumerable<Type> SupportedTypes {
418 get { yield return typeofCultureInfo; }
421 public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
422 throw new NotSupportedException ();
425 public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
426 CultureInfo ci = (CultureInfo)obj;
429 Dictionary<string, object> d = new Dictionary<string, object> ();
430 d.Add ("name", ci.Name);
431 d.Add ("numberFormat", ci.NumberFormat);
432 d.Add ("dateTimeFormat", ci.DateTimeFormat);
438 public void DeserializeObject () {
\r
439 object o = new JavaScriptSerializer ().DeserializeObject ("{\"Numeric\":0,\"Array\":[true,false,0]}");
\r
440 Assert.IsNotNull (o as Dictionary<string, object>, "type");
\r
441 Dictionary<string, object> dictionary = (Dictionary<string, object>) o;
\r
442 Assert.AreEqual (0, (int) dictionary ["Numeric"], "Numeric");
\r
443 Assert.IsNotNull (dictionary ["Array"] as object [], "Array type");
\r
444 object [] array = (object []) dictionary ["Array"];
\r
445 Assert.AreEqual (true, (bool) array [0], "array [0]");
\r
446 Assert.AreEqual (false, (bool) array [1], "array [1]");
\r
447 Assert.AreEqual (0, (int) array [2], "array [2]");
\r