Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs @ 5304

Last change on this file since 5304 was 5290, checked in by epitzer, 14 years ago

Added custom serializers for generic HashSets and Dictionaries that include the Comparer property (#1375)

File size: 39.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.Drawing;
26using System.IO;
27using System.Linq;
28using System.Reflection;
29using System.Text;
30using System.Text.RegularExpressions;
31using HeuristicLab.Persistence.Auxiliary;
32using HeuristicLab.Persistence.Core;
33using HeuristicLab.Persistence.Default.CompositeSerializers;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.Persistence.Default.DebugString;
36using HeuristicLab.Persistence.Default.Xml;
37using HeuristicLab.Persistence.Default.Xml.Primitive;
38using HeuristicLab.Persistence.Interfaces;
39using Microsoft.VisualStudio.TestTools.UnitTesting;
40
41namespace HeuristicLab.Persistence_33.Tests {
42
43  [StorableClass]
44  public class NumberTest {
45    [Storable]
46    private bool _bool = true;
47    [Storable]
48    private byte _byte = 0xFF;
49    [Storable]
50    private sbyte _sbyte = 0xF;
51    [Storable]
52    private short _short = -123;
53    [Storable]
54    private ushort _ushort = 123;
55    [Storable]
56    private int _int = -123;
57    [Storable]
58    private uint _uint = 123;
59    [Storable]
60    private long _long = 123456;
61    [Storable]
62    private ulong _ulong = 123456;
63    public override bool Equals(object obj) {
64      NumberTest nt = obj as NumberTest;
65      if (nt == null)
66        throw new NotSupportedException();
67      return
68        nt._bool == _bool &&
69        nt._byte == _byte &&
70        nt._sbyte == _sbyte &&
71        nt._short == _short &&
72        nt._ushort == _ushort &&
73        nt._int == _int &&
74        nt._uint == _uint &&
75        nt._long == _long &&
76        nt._ulong == _ulong;
77    }
78    public override int GetHashCode() {
79      return
80        _bool.GetHashCode() ^
81        _byte.GetHashCode() ^
82        _sbyte.GetHashCode() ^
83        _short.GetHashCode() ^
84        _short.GetHashCode() ^
85        _int.GetHashCode() ^
86        _uint.GetHashCode() ^
87        _long.GetHashCode() ^
88        _ulong.GetHashCode();
89    }
90  }
91
92  [StorableClass]
93  public class NonDefaultConstructorClass {
94    [Storable]
95    int value;
96    public NonDefaultConstructorClass(int value) {
97      this.value = value;
98    }
99  }
100
101  [StorableClass]
102  public class IntWrapper {
103
104    [Storable]
105    public int Value;
106
107    private IntWrapper() { }
108
109    public IntWrapper(int value) {
110      this.Value = value;
111    }
112
113    public override bool Equals(object obj) {
114      if (obj as IntWrapper == null)
115        return false;
116      return Value.Equals(((IntWrapper)obj).Value);
117    }
118    public override int GetHashCode() {
119      return Value.GetHashCode();
120    }
121
122  }
123
124  [StorableClass]
125  public class PrimitivesTest : NumberTest {
126    [Storable]
127    private char c = 'e';
128    [Storable]
129    private long[,] _long_array =
130      new long[,] { { 123, 456, }, { 789, 123 } };
131    [Storable]
132    public List<int> list = new List<int> { 1, 2, 3, 4, 5 };
133    [Storable]
134    private object o = new object();
135    public override bool Equals(object obj) {
136      PrimitivesTest pt = obj as PrimitivesTest;
137      if (pt == null)
138        throw new NotSupportedException();
139      return base.Equals(obj) &&
140        c == pt.c &&
141        _long_array == pt._long_array &&
142        list == pt.list &&
143        o == pt.o;
144    }
145    public override int GetHashCode() {
146      return base.GetHashCode() ^
147        c.GetHashCode() ^
148        _long_array.GetHashCode() ^
149        list.GetHashCode() ^
150        o.GetHashCode();
151    }
152  }
153
154  public enum TestEnum { va1, va2, va3, va8 } ;
155
156  [StorableClass]
157  public class RootBase {
158    [Storable]
159    private string baseString = "   Serial  ";
160    [Storable]
161    public TestEnum myEnum = TestEnum.va3;
162    public override bool Equals(object obj) {
163      RootBase rb = obj as RootBase;
164      if (rb == null)
165        throw new NotSupportedException();
166      return baseString == rb.baseString &&
167        myEnum == rb.myEnum;
168    }
169    public override int GetHashCode() {
170      return baseString.GetHashCode() ^
171        myEnum.GetHashCode();
172    }
173  }
174
175  [StorableClass]
176  public class Root : RootBase {
177    [Storable]
178    public Stack<int> intStack = new Stack<int>();
179    [Storable]
180    public int[] i = new[] { 3, 4, 5, 6 };
181    [Storable(Name = "Test String")]
182    public string s;
183    [Storable]
184    public ArrayList intArray = new ArrayList(new[] { 1, 2, 3 });
185    [Storable]
186    public List<int> intList = new List<int>(new[] { 321, 312, 321 });
187    [Storable]
188    public Custom c;
189    [Storable]
190    public List<Root> selfReferences;
191    [Storable]
192    public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } };
193    [Storable]
194    public bool boolean = true;
195    [Storable]
196    public DateTime dateTime;
197    [Storable]
198    public KeyValuePair<string, int> kvp = new KeyValuePair<string, int>("Serial", 123);
199    [Storable]
200    public Dictionary<string, int> dict = new Dictionary<string, int>();
201    [Storable(DefaultValue = "default")]
202    public string uninitialized;
203  }
204
205  public enum SimpleEnum { one, two, three }
206  public enum ComplexEnum { one = 1, two = 2, three = 3 }
207  [FlagsAttribute]
208  public enum TrickyEnum { zero = 0, one = 1, two = 2 }
209
210  [StorableClass]
211  public class EnumTest {
212    [Storable]
213    public SimpleEnum simpleEnum = SimpleEnum.one;
214    [Storable]
215    public ComplexEnum complexEnum = (ComplexEnum)2;
216    [Storable]
217    public TrickyEnum trickyEnum = (TrickyEnum)15;
218  }
219
220  [StorableClass]
221  public class Custom {
222    [Storable]
223    public int i;
224    [Storable]
225    public Root r;
226    [Storable]
227    public string name = "<![CDATA[<![CDATA[Serial]]>]]>";
228  }
229
230  [StorableClass]
231  public class Manager {
232
233    public DateTime lastLoadTime;
234    [Storable]
235    private DateTime lastLoadTimePersistence {
236      get { return lastLoadTime; }
237      set { lastLoadTime = DateTime.Now; }
238    }
239    [Storable]
240    public double? dbl;
241  }
242
243  [StorableClass]
244  public class C {
245    [Storable]
246    public C[][] allCs;
247    [Storable]
248    public KeyValuePair<List<C>, C> kvpList;
249  }
250
251  public class NonSerializable {
252    int x = 0;
253    public override bool Equals(object obj) {
254      NonSerializable ns = obj as NonSerializable;
255      if (ns == null)
256        throw new NotSupportedException();
257      return ns.x == x;
258    }
259    public override int GetHashCode() {
260      return x.GetHashCode();
261    }
262  }
263
264
265  [TestClass]
266  public class UseCases {
267
268    private string tempFile;
269
270    [TestInitialize()]
271    public void CreateTempFile() {
272      tempFile = Path.GetTempFileName();
273    }
274
275    [TestCleanup()]
276    public void ClearTempFile() {
277      StreamReader reader = new StreamReader(tempFile);
278      string s = reader.ReadToEnd();
279      reader.Close();
280      File.Delete(tempFile);
281    }
282
283    [TestMethod]
284    public void ComplexStorable() {
285      Root r = InitializeComplexStorable();
286      XmlGenerator.Serialize(r, tempFile);
287      Root newR = (Root)XmlParser.Deserialize(tempFile);
288      CompareComplexStorables(r, newR);
289    }
290
291    [TestMethod]
292    public void ComplexEasyStorable() {
293      Root r = InitializeComplexStorable();
294      ReadableXmlGenerator.Serialize(r, tempFile);
295      using (var reader = new StreamReader(tempFile)) {
296        string text = reader.ReadToEnd();
297        Assert.IsTrue(text.StartsWith("<Root"));
298      }
299    }
300
301    private static void CompareComplexStorables(Root r, Root newR) {
302      Assert.AreEqual(
303        DebugStringGenerator.Serialize(r),
304        DebugStringGenerator.Serialize(newR));
305      Assert.AreSame(newR, newR.selfReferences[0]);
306      Assert.AreNotSame(r, newR);
307      Assert.AreEqual(r.myEnum, TestEnum.va1);
308      Assert.AreEqual(r.i[0], 7);
309      Assert.AreEqual(r.i[1], 5);
310      Assert.AreEqual(r.i[2], 6);
311      Assert.AreEqual(r.s, "new value");
312      Assert.AreEqual(r.intArray[0], 3);
313      Assert.AreEqual(r.intArray[1], 2);
314      Assert.AreEqual(r.intArray[2], 1);
315      Assert.AreEqual(r.intList[0], 9);
316      Assert.AreEqual(r.intList[1], 8);
317      Assert.AreEqual(r.intList[2], 7);
318      Assert.AreEqual(r.multiDimArray[0, 0], 5);
319      Assert.AreEqual(r.multiDimArray[0, 1], 4);
320      Assert.AreEqual(r.multiDimArray[0, 2], 3);
321      Assert.AreEqual(r.multiDimArray[1, 0], 1);
322      Assert.AreEqual(r.multiDimArray[1, 1], 4);
323      Assert.AreEqual(r.multiDimArray[1, 2], 6);
324      Assert.IsFalse(r.boolean);
325      Assert.IsTrue((DateTime.Now - r.dateTime).TotalSeconds < 10);
326      Assert.AreEqual(r.kvp.Key, "string key");
327      Assert.AreEqual(r.kvp.Value, 321);
328      Assert.IsNull(r.uninitialized);
329      Assert.AreEqual(newR.myEnum, TestEnum.va1);
330      Assert.AreEqual(newR.i[0], 7);
331      Assert.AreEqual(newR.i[1], 5);
332      Assert.AreEqual(newR.i[2], 6);
333      Assert.AreEqual(newR.s, "new value");
334      Assert.AreEqual(newR.intArray[0], 3);
335      Assert.AreEqual(newR.intArray[1], 2);
336      Assert.AreEqual(newR.intArray[2], 1);
337      Assert.AreEqual(newR.intList[0], 9);
338      Assert.AreEqual(newR.intList[1], 8);
339      Assert.AreEqual(newR.intList[2], 7);
340      Assert.AreEqual(newR.multiDimArray[0, 0], 5);
341      Assert.AreEqual(newR.multiDimArray[0, 1], 4);
342      Assert.AreEqual(newR.multiDimArray[0, 2], 3);
343      Assert.AreEqual(newR.multiDimArray[1, 0], 1);
344      Assert.AreEqual(newR.multiDimArray[1, 1], 4);
345      Assert.AreEqual(newR.multiDimArray[1, 2], 6);
346      Assert.AreEqual(newR.intStack.Pop(), 3);
347      Assert.AreEqual(newR.intStack.Pop(), 2);
348      Assert.AreEqual(newR.intStack.Pop(), 1);
349      Assert.IsFalse(newR.boolean);
350      Assert.IsTrue((DateTime.Now - newR.dateTime).TotalSeconds < 10);
351      Assert.AreEqual(newR.kvp.Key, "string key");
352      Assert.AreEqual(newR.kvp.Value, 321);
353      Assert.IsNull(newR.uninitialized);
354    }
355
356    private static Root InitializeComplexStorable() {
357      Root r = new Root();
358      r.intStack.Push(1);
359      r.intStack.Push(2);
360      r.intStack.Push(3);
361      r.selfReferences = new List<Root> { r, r };
362      r.c = new Custom { r = r };
363      r.dict.Add("one", 1);
364      r.dict.Add("two", 2);
365      r.dict.Add("three", 3);
366      r.myEnum = TestEnum.va1;
367      r.i = new[] { 7, 5, 6 };
368      r.s = "new value";
369      r.intArray = new ArrayList { 3, 2, 1 };
370      r.intList = new List<int> { 9, 8, 7 };
371      r.multiDimArray = new double[,] { { 5, 4, 3 }, { 1, 4, 6 } };
372      r.boolean = false;
373      r.dateTime = DateTime.Now;
374      r.kvp = new KeyValuePair<string, int>("string key", 321);
375      r.uninitialized = null;
376
377      return r;
378    }
379
380    [TestMethod]
381    public void SelfReferences() {
382      C c = new C();
383      C[][] cs = new C[2][];
384      cs[0] = new C[] { c };
385      cs[1] = new C[] { c };
386      c.allCs = cs;
387      c.kvpList = new KeyValuePair<List<C>, C>(new List<C> { c }, c);
388      XmlGenerator.Serialize(cs, tempFile);
389      object o = XmlParser.Deserialize(tempFile);
390      Assert.AreEqual(
391        DebugStringGenerator.Serialize(cs),
392        DebugStringGenerator.Serialize(o));
393      Assert.AreSame(c, c.allCs[0][0]);
394      Assert.AreSame(c, c.allCs[1][0]);
395      Assert.AreSame(c, c.kvpList.Key[0]);
396      Assert.AreSame(c, c.kvpList.Value);
397      C[][] newCs = (C[][])o;
398      C newC = newCs[0][0];
399      Assert.AreSame(newC, newC.allCs[0][0]);
400      Assert.AreSame(newC, newC.allCs[1][0]);
401      Assert.AreSame(newC, newC.kvpList.Key[0]);
402      Assert.AreSame(newC, newC.kvpList.Value);
403    }
404
405    [TestMethod]
406    public void ArrayCreation() {
407      ArrayList[] arrayListArray = new ArrayList[4];
408      arrayListArray[0] = new ArrayList();
409      arrayListArray[0].Add(arrayListArray);
410      arrayListArray[0].Add(arrayListArray);
411      arrayListArray[1] = new ArrayList();
412      arrayListArray[1].Add(arrayListArray);
413      arrayListArray[2] = new ArrayList();
414      arrayListArray[2].Add(arrayListArray);
415      arrayListArray[2].Add(arrayListArray);
416      Array a = Array.CreateInstance(
417                              typeof(object),
418                              new[] { 1, 2 }, new[] { 3, 4 });
419      arrayListArray[2].Add(a);
420      XmlGenerator.Serialize(arrayListArray, tempFile);
421      object o = XmlParser.Deserialize(tempFile);
422      Assert.AreEqual(
423        DebugStringGenerator.Serialize(arrayListArray),
424        DebugStringGenerator.Serialize(o));
425      ArrayList[] newArray = (ArrayList[])o;
426      Assert.AreSame(arrayListArray, arrayListArray[0][0]);
427      Assert.AreSame(arrayListArray, arrayListArray[2][1]);
428      Assert.AreSame(newArray, newArray[0][0]);
429      Assert.AreSame(newArray, newArray[2][1]);
430    }
431
432    [TestMethod]
433    public void CustomSerializationProperty() {
434      Manager m = new Manager();
435      XmlGenerator.Serialize(m, tempFile);
436      Manager newM = (Manager)XmlParser.Deserialize(tempFile);
437      Assert.AreNotEqual(
438        DebugStringGenerator.Serialize(m),
439        DebugStringGenerator.Serialize(newM));
440      Assert.AreEqual(m.dbl, newM.dbl);
441      Assert.AreEqual(m.lastLoadTime, new DateTime());
442      Assert.AreNotEqual(newM.lastLoadTime, new DateTime());
443      Assert.IsTrue((DateTime.Now - newM.lastLoadTime).TotalSeconds < 10);
444    }
445
446    [TestMethod]
447    public void Primitives() {
448      PrimitivesTest sdt = new PrimitivesTest();
449      XmlGenerator.Serialize(sdt, tempFile);
450      object o = XmlParser.Deserialize(tempFile);
451      Assert.AreEqual(
452        DebugStringGenerator.Serialize(sdt),
453        DebugStringGenerator.Serialize(o));
454    }
455
456    [TestMethod]
457    public void MultiDimensionalArray() {
458      string[,] mDimString = new string[,] {
459        {"ora", "et", "labora"},
460        {"Beten", "und", "Arbeiten"}
461      };
462      XmlGenerator.Serialize(mDimString, tempFile);
463      object o = XmlParser.Deserialize(tempFile);
464      Assert.AreEqual(
465        DebugStringGenerator.Serialize(mDimString),
466        DebugStringGenerator.Serialize(o));
467    }
468
469    [StorableClass]
470    public class NestedType {
471      [Storable]
472      private string value = "value";
473      public override bool Equals(object obj) {
474        NestedType nt = obj as NestedType;
475        if (nt == null)
476          throw new NotSupportedException();
477        return nt.value == value;
478      }
479      public override int GetHashCode() {
480        return value.GetHashCode();
481      }
482    }
483
484    [TestMethod]
485    public void NestedTypeTest() {
486      NestedType t = new NestedType();
487      XmlGenerator.Serialize(t, tempFile);
488      object o = XmlParser.Deserialize(tempFile);
489      Assert.AreEqual(
490        DebugStringGenerator.Serialize(t),
491        DebugStringGenerator.Serialize(o));
492      Assert.IsTrue(t.Equals(o));
493    }
494
495
496    [TestMethod]
497    public void SimpleArray() {
498      string[] strings = { "ora", "et", "labora" };
499      XmlGenerator.Serialize(strings, tempFile);
500      object o = XmlParser.Deserialize(tempFile);
501      Assert.AreEqual(
502        DebugStringGenerator.Serialize(strings),
503        DebugStringGenerator.Serialize(o));
504    }
505
506    [TestMethod]
507    public void PrimitiveRoot() {
508      XmlGenerator.Serialize(12.3f, tempFile);
509      object o = XmlParser.Deserialize(tempFile);
510      Assert.AreEqual(
511        DebugStringGenerator.Serialize(12.3f),
512        DebugStringGenerator.Serialize(o));
513    }
514
515    private string formatFullMemberName(MemberInfo mi) {
516      return new StringBuilder()
517        .Append(mi.DeclaringType.Assembly.GetName().Name)
518        .Append(": ")
519        .Append(mi.DeclaringType.Namespace)
520        .Append('.')
521        .Append(mi.DeclaringType.Name)
522        .Append('.')
523        .Append(mi.Name).ToString();
524    }
525
526    [TestMethod]
527    public void CodingConventions() {
528      List<string> lowerCaseMethodNames = new List<string>();
529      List<string> lowerCaseProperties = new List<string>();
530      List<string> lowerCaseFields = new List<string>();
531      foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
532        if (!a.GetName().Name.StartsWith("HeuristicLab"))
533          continue;
534        foreach (Type t in a.GetTypes()) {
535          foreach (MemberInfo mi in t.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) {
536            if (mi.DeclaringType.Name.StartsWith("<>"))
537              continue;
538            if (char.IsLower(mi.Name[0])) {
539              if (mi.MemberType == MemberTypes.Field)
540                lowerCaseFields.Add(formatFullMemberName(mi));
541              if (mi.MemberType == MemberTypes.Property)
542                lowerCaseProperties.Add(formatFullMemberName(mi));
543              if (mi.MemberType == MemberTypes.Method &&
544                !mi.Name.StartsWith("get_") &&
545                !mi.Name.StartsWith("set_") &&
546                !mi.Name.StartsWith("add_") &&
547                !mi.Name.StartsWith("remove_"))
548                lowerCaseMethodNames.Add(formatFullMemberName(mi));
549            }
550          }
551        }
552      }
553      //Assert.AreEqual("", lowerCaseFields.Aggregate("", (a, b) => a + "\r\n" + b));
554      Assert.AreEqual("", lowerCaseMethodNames.Aggregate("", (a, b) => a + "\r\n" + b));
555      Assert.AreEqual("", lowerCaseProperties.Aggregate("", (a, b) => a + "\r\n" + b));
556    }
557
558    [TestMethod]
559    public void Number2StringDecomposer() {
560      NumberTest sdt = new NumberTest();
561      XmlGenerator.Serialize(sdt, tempFile,
562        new Configuration(new XmlFormat(),
563          new List<IPrimitiveSerializer> { new String2XmlSerializer() },
564          new List<ICompositeSerializer> {
565            new StorableSerializer(),
566            new Number2StringSerializer() }));
567      object o = XmlParser.Deserialize(tempFile);
568      Assert.AreEqual(
569        DebugStringGenerator.Serialize(sdt),
570        DebugStringGenerator.Serialize(o));
571      Assert.IsTrue(sdt.Equals(o));
572    }
573
574    [TestMethod]
575    public void Enums() {
576      EnumTest et = new EnumTest();
577      et.simpleEnum = SimpleEnum.two;
578      et.complexEnum = ComplexEnum.three;
579      et.trickyEnum = TrickyEnum.two | TrickyEnum.one;
580      XmlGenerator.Serialize(et, tempFile);
581      EnumTest newEt = (EnumTest)XmlParser.Deserialize(tempFile);
582      Assert.AreEqual(et.simpleEnum, SimpleEnum.two);
583      Assert.AreEqual(et.complexEnum, ComplexEnum.three);
584      Assert.AreEqual(et.trickyEnum, (TrickyEnum)3);
585    }
586
587    [TestMethod]
588    public void TestAliasingWithOverriddenEquals() {
589      List<IntWrapper> ints = new List<IntWrapper>();
590      ints.Add(new IntWrapper(1));
591      ints.Add(new IntWrapper(1));
592      Assert.AreEqual(ints[0], ints[1]);
593      Assert.AreNotSame(ints[0], ints[1]);
594      XmlGenerator.Serialize(ints, tempFile);
595      List<IntWrapper> newInts = (List<IntWrapper>)XmlParser.Deserialize(tempFile);
596      Assert.AreEqual(newInts[0].Value, 1);
597      Assert.AreEqual(newInts[1].Value, 1);
598      Assert.AreEqual(newInts[0], newInts[1]);
599      Assert.AreNotSame(newInts[0], newInts[1]);
600    }
601
602    [TestMethod]
603    public void NonDefaultConstructorTest() {
604      NonDefaultConstructorClass c = new NonDefaultConstructorClass(1);
605      try {
606        XmlGenerator.Serialize(c, tempFile);
607        Assert.Fail("Exception not thrown");
608      }
609      catch (PersistenceException) {
610      }
611    }
612
613    [TestMethod]
614    public void TestSavingException() {
615      List<int> list = new List<int> { 1, 2, 3 };
616      XmlGenerator.Serialize(list, tempFile);
617      NonSerializable s = new NonSerializable();
618      try {
619        XmlGenerator.Serialize(s, tempFile);
620        Assert.Fail("Exception expected");
621      }
622      catch (PersistenceException) { }
623      List<int> newList = (List<int>)XmlParser.Deserialize(tempFile);
624      Assert.AreEqual(list[0], newList[0]);
625      Assert.AreEqual(list[1], newList[1]);
626    }
627
628    [TestMethod]
629    public void TestTypeStringConversion() {
630      string name = typeof(List<int>[]).AssemblyQualifiedName;
631      string shortName =
632        "System.Collections.Generic.List`1[[System.Int32, mscorlib]][], mscorlib";
633      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
634      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
635      Assert.AreEqual(shortName, typeof(List<int>[]).VersionInvariantName());
636    }
637
638    [TestMethod]
639    public void TestHexadecimalPublicKeyToken() {
640      string name = "TestClass, TestAssembly, Version=1.2.3.4, PublicKey=1234abc";
641      string shortName = "TestClass, TestAssembly";
642      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
643      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
644    }
645
646    [TestMethod]
647    public void TestMultipleFailure() {
648      List<NonSerializable> l = new List<NonSerializable>();
649      l.Add(new NonSerializable());
650      l.Add(new NonSerializable());
651      l.Add(new NonSerializable());
652      try {
653        Serializer s = new Serializer(l,
654          ConfigurationService.Instance.GetConfiguration(new XmlFormat()),
655          "ROOT", true);
656        StringBuilder tokens = new StringBuilder();
657        foreach (var token in s) {
658          tokens.Append(token.ToString());
659        }
660        Assert.Fail("Exception expected");
661      }
662      catch (PersistenceException px) {
663        Assert.AreEqual(3, px.Data.Count);
664      }
665    }
666
667    [TestMethod]
668    public void TestAssemblyVersionCheck() {
669      IntWrapper i = new IntWrapper(1);
670      Serializer s = new Serializer(i, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
671      XmlGenerator g = new XmlGenerator();
672      StringBuilder dataString = new StringBuilder();
673      foreach (var token in s) {
674        dataString.Append(g.Format(token));
675      }
676      StringBuilder typeString = new StringBuilder();
677      foreach (var line in g.Format(s.TypeCache))
678        typeString.Append(line);
679      Deserializer d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(typeString.ToString())));
680      XmlParser p = new XmlParser(new StringReader(dataString.ToString()));
681      IntWrapper newI = (IntWrapper)d.Deserialize(p);
682      Assert.AreEqual(i.Value, newI.Value);
683
684      string newTypeString = Regex.Replace(typeString.ToString(),
685        "Version=\\d+\\.\\d+\\.\\d+\\.\\d+",
686        "Version=0.0.9999.9999");
687      try {
688        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
689        Assert.Fail("Exception expected");
690      }
691      catch (PersistenceException x) {
692        Assert.IsTrue(x.Message.Contains("incompatible"));
693      }
694      newTypeString = Regex.Replace(typeString.ToString(),
695        "Version=(\\d+\\.\\d+)\\.\\d+\\.\\d+",
696        "Version=$1.9999.9999");
697      try {
698        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
699        Assert.Fail("Exception expected");
700      }
701      catch (PersistenceException x) {
702        Assert.IsTrue(x.Message.Contains("newer"));
703      }
704    }
705
706    [TestMethod]
707    public void InheritanceTest() {
708      New n = new New();
709      XmlGenerator.Serialize(n, tempFile);
710      New nn = (New)XmlParser.Deserialize(tempFile);
711      Assert.AreEqual(n.Name, nn.Name);
712      Assert.AreEqual(((Override)n).Name, ((Override)nn).Name);
713    }
714
715    [StorableClass]
716    class Child {
717      [Storable]
718      public GrandParent grandParent;
719    }
720
721    [StorableClass]
722    class Parent {
723      [Storable]
724      public Child child;
725    }
726
727    [StorableClass]
728    class GrandParent {
729      [Storable]
730      public Parent parent;
731    }
732
733    [TestMethod]
734    public void InstantiateParentChainReference() {
735      GrandParent gp = new GrandParent();
736      gp.parent = new Parent();
737      gp.parent.child = new Child();
738      gp.parent.child.grandParent = gp;
739      Assert.AreSame(gp, gp.parent.child.grandParent);
740      XmlGenerator.Serialize(gp, tempFile);
741      GrandParent newGp = (GrandParent)XmlParser.Deserialize(tempFile);
742      Assert.AreSame(newGp, newGp.parent.child.grandParent);
743    }
744
745    struct TestStruct {
746      int value;
747      int PropertyValue { get; set; }
748      public TestStruct(int value)
749        : this() {
750        this.value = value;
751        PropertyValue = value;
752      }
753    }
754
755    [TestMethod]
756    public void StructTest() {
757      TestStruct s = new TestStruct(10);
758      XmlGenerator.Serialize(s, tempFile);
759      TestStruct newS = (TestStruct)XmlParser.Deserialize(tempFile);
760      Assert.AreEqual(s, newS);
761    }
762
763    [TestMethod]
764    public void PointTest() {
765      Point p = new Point(12, 34);
766      XmlGenerator.Serialize(p, tempFile);
767      Point newP = (Point)XmlParser.Deserialize(tempFile);
768      Assert.AreEqual(p, newP);
769    }
770
771    [TestMethod]
772    public void NullableValueTypes() {
773      double?[] d = new double?[] { null, 1, 2, 3 };
774      XmlGenerator.Serialize(d, tempFile);
775      double?[] newD = (double?[])XmlParser.Deserialize(tempFile);
776      Assert.AreEqual(d[0], newD[0]);
777      Assert.AreEqual(d[1], newD[1]);
778      Assert.AreEqual(d[2], newD[2]);
779      Assert.AreEqual(d[3], newD[3]);
780    }
781
782    [TestMethod]
783    public void BitmapTest() {
784      Icon icon = System.Drawing.SystemIcons.Hand;
785      Bitmap bitmap = icon.ToBitmap();
786      XmlGenerator.Serialize(bitmap, tempFile);
787      Bitmap newBitmap = (Bitmap)XmlParser.Deserialize(tempFile);
788
789      Assert.AreEqual(bitmap.Size, newBitmap.Size);
790      for (int i = 0; i < bitmap.Size.Width; i++)
791        for (int j = 0; j < bitmap.Size.Height; j++)
792          Assert.AreEqual(bitmap.GetPixel(i, j), newBitmap.GetPixel(i, j));
793    }
794
795    [StorableClass]
796    private class PersistenceHooks {
797      [Storable]
798      public int a;
799      [Storable]
800      public int b;
801      public int sum;
802      public bool WasSerialized { get; private set; }
803      [StorableHook(HookType.BeforeSerialization)]
804      void PreSerializationHook() {
805        WasSerialized = true;
806      }
807      [StorableHook(HookType.AfterDeserialization)]
808      void PostDeserializationHook() {
809        sum = a + b;
810      }
811    }
812
813    [TestMethod]
814    public void HookTest() {
815      PersistenceHooks hookTest = new PersistenceHooks();
816      hookTest.a = 2;
817      hookTest.b = 5;
818      Assert.IsFalse(hookTest.WasSerialized);
819      Assert.AreEqual(hookTest.sum, 0);
820      XmlGenerator.Serialize(hookTest, tempFile);
821      Assert.IsTrue(hookTest.WasSerialized);
822      Assert.AreEqual(hookTest.sum, 0);
823      PersistenceHooks newHookTest = (PersistenceHooks)XmlParser.Deserialize(tempFile);
824      Assert.AreEqual(newHookTest.a, hookTest.a);
825      Assert.AreEqual(newHookTest.b, hookTest.b);
826      Assert.AreEqual(newHookTest.sum, newHookTest.a + newHookTest.b);
827      Assert.IsFalse(newHookTest.WasSerialized);
828    }
829
830    [StorableClass]
831    private class CustomConstructor {
832      public string Value = "none";
833      public CustomConstructor() {
834        Value = "default";
835      }
836      [StorableConstructor]
837      private CustomConstructor(bool deserializing) {
838        Assert.IsTrue(deserializing);
839        Value = "persistence";
840      }
841    }
842
843    [TestMethod]
844    public void TestCustomConstructor() {
845      CustomConstructor cc = new CustomConstructor();
846      Assert.AreEqual(cc.Value, "default");
847      XmlGenerator.Serialize(cc, tempFile);
848      CustomConstructor newCC = (CustomConstructor)XmlParser.Deserialize(tempFile);
849      Assert.AreEqual(newCC.Value, "persistence");
850    }
851
852    [StorableClass]
853    public class ExplodingDefaultConstructor {
854      public ExplodingDefaultConstructor() {
855        throw new Exception("this constructor will always fail");
856      }
857      public ExplodingDefaultConstructor(string password) {
858      }
859    }
860
861    [TestMethod]
862    public void TestConstructorExceptionUnwrapping() {
863      ExplodingDefaultConstructor x = new ExplodingDefaultConstructor("password");
864      XmlGenerator.Serialize(x, tempFile);
865      try {
866        ExplodingDefaultConstructor newX = (ExplodingDefaultConstructor)XmlParser.Deserialize(tempFile);
867        Assert.Fail("Exception expected");
868      }
869      catch (PersistenceException pe) {
870        Assert.AreEqual(pe.InnerException.Message, "this constructor will always fail");
871      }
872    }
873
874    [TestMethod]
875    public void TestRejectionJustifications() {
876      NonSerializable ns = new NonSerializable();
877      try {
878        XmlGenerator.Serialize(ns, tempFile);
879        Assert.Fail("PersistenceException expected");
880      }
881      catch (PersistenceException x) {
882        Assert.IsTrue(x.Message.Contains(new StorableSerializer().JustifyRejection(typeof(NonSerializable))));
883      }
884    }
885
886    [TestMethod]
887    public void TestStreaming() {
888      using (MemoryStream stream = new MemoryStream()) {
889        Root r = InitializeComplexStorable();
890        XmlGenerator.Serialize(r, stream);
891        using (MemoryStream stream2 = new MemoryStream(stream.ToArray())) {
892          Root newR = (Root)XmlParser.Deserialize(stream2);
893          CompareComplexStorables(r, newR);
894        }
895      }
896    }
897
898    [StorableClass]
899    public class HookInheritanceTestBase {
900      [Storable]
901      public object a;
902      public object link;
903      [StorableHook(HookType.AfterDeserialization)]
904      private void relink() {
905        link = a;
906      }
907    }
908
909    [StorableClass]
910    public class HookInheritanceTestDerivedClass : HookInheritanceTestBase {
911      [Storable]
912      public object b;
913      [StorableHook(HookType.AfterDeserialization)]
914      private void relink() {
915        Assert.AreSame(a, link);
916        link = b;
917      }
918    }
919
920    [TestMethod]
921    public void TestLinkInheritance() {
922      HookInheritanceTestDerivedClass c = new HookInheritanceTestDerivedClass();
923      c.a = new object();
924      XmlGenerator.Serialize(c, tempFile);
925      HookInheritanceTestDerivedClass newC = (HookInheritanceTestDerivedClass)XmlParser.Deserialize(tempFile);
926      Assert.AreSame(c.b, c.link);
927    }
928
929    [StorableClass(StorableClassType.AllFields)]
930    public class AllFieldsStorable {
931      public int Value1 = 1;
932      [Storable]
933      public int Value2 = 2;
934      public int Value3 { get; private set; }
935      public int Value4 { get; private set; }
936      [StorableConstructor]
937      public AllFieldsStorable(bool isDeserializing) {
938        if (!isDeserializing) {
939          Value1 = 12;
940          Value2 = 23;
941          Value3 = 34;
942          Value4 = 56;
943        }
944      }
945    }
946
947    [TestMethod]
948    public void TestStorableClassDiscoveryAllFields() {
949      AllFieldsStorable afs = new AllFieldsStorable(false);
950      XmlGenerator.Serialize(afs, tempFile);
951      AllFieldsStorable newAfs = (AllFieldsStorable)XmlParser.Deserialize(tempFile);
952      Assert.AreEqual(afs.Value1, newAfs.Value1);
953      Assert.AreEqual(afs.Value2, newAfs.Value2);
954      Assert.AreEqual(0, newAfs.Value3);
955      Assert.AreEqual(0, newAfs.Value4);
956    }
957
958    [StorableClass(StorableClassType.AllProperties)]
959    public class AllPropertiesStorable {
960      public int Value1 = 1;
961      [Storable]
962      public int Value2 = 2;
963      public int Value3 { get; private set; }
964      public int Value4 { get; private set; }
965      [StorableConstructor]
966      public AllPropertiesStorable(bool isDeserializing) {
967        if (!isDeserializing) {
968          Value1 = 12;
969          Value2 = 23;
970          Value3 = 34;
971          Value4 = 56;
972        }
973      }
974    }
975
976    [TestMethod]
977    public void TestStorableClassDiscoveryAllProperties() {
978      AllPropertiesStorable afs = new AllPropertiesStorable(false);
979      XmlGenerator.Serialize(afs, tempFile);
980      AllPropertiesStorable newAfs = (AllPropertiesStorable)XmlParser.Deserialize(tempFile);
981      Assert.AreEqual(1, newAfs.Value1);
982      Assert.AreEqual(2, newAfs.Value2);
983      Assert.AreEqual(afs.Value3, newAfs.Value3);
984      Assert.AreEqual(afs.Value4, newAfs.Value4);
985
986    }
987
988    [StorableClass(StorableClassType.AllFieldsAndAllProperties)]
989    public class AllFieldsAndAllPropertiesStorable {
990      public int Value1 = 1;
991      [Storable]
992      public int Value2 = 2;
993      public int Value3 { get; private set; }
994      public int Value4 { get; private set; }
995      [StorableConstructor]
996      public AllFieldsAndAllPropertiesStorable(bool isDeserializing) {
997        if (!isDeserializing) {
998          Value1 = 12;
999          Value2 = 23;
1000          Value3 = 34;
1001          Value4 = 56;
1002        }
1003      }
1004    }
1005
1006    [TestMethod]
1007    public void TestStorableClassDiscoveryAllFieldsAndAllProperties() {
1008      AllFieldsAndAllPropertiesStorable afs = new AllFieldsAndAllPropertiesStorable(false);
1009      XmlGenerator.Serialize(afs, tempFile);
1010      AllFieldsAndAllPropertiesStorable newAfs = (AllFieldsAndAllPropertiesStorable)XmlParser.Deserialize(tempFile);
1011      Assert.AreEqual(afs.Value1, newAfs.Value1);
1012      Assert.AreEqual(afs.Value2, newAfs.Value2);
1013      Assert.AreEqual(afs.Value3, newAfs.Value3);
1014      Assert.AreEqual(afs.Value4, newAfs.Value4);
1015    }
1016
1017    [StorableClass(StorableClassType.MarkedOnly)]
1018    public class MarkedOnlyStorable {
1019      public int Value1 = 1;
1020      [Storable]
1021      public int Value2 = 2;
1022      public int Value3 { get; private set; }
1023      public int Value4 { get; private set; }
1024      [StorableConstructor]
1025      public MarkedOnlyStorable(bool isDeserializing) {
1026        if (!isDeserializing) {
1027          Value1 = 12;
1028          Value2 = 23;
1029          Value3 = 34;
1030          Value4 = 56;
1031        }
1032      }
1033    }
1034
1035    [TestMethod]
1036    public void TestStorableClassDiscoveryMarkedOnly() {
1037      MarkedOnlyStorable afs = new MarkedOnlyStorable(false);
1038      XmlGenerator.Serialize(afs, tempFile);
1039      MarkedOnlyStorable newAfs = (MarkedOnlyStorable)XmlParser.Deserialize(tempFile);
1040      Assert.AreEqual(1, newAfs.Value1);
1041      Assert.AreEqual(afs.Value2, newAfs.Value2);
1042      Assert.AreEqual(0, newAfs.Value3);
1043      Assert.AreEqual(0, newAfs.Value4);
1044    }
1045
1046    [TestMethod]
1047    public void TestLineEndings() {
1048      List<string> lineBreaks = new List<string> { "\r\n", "\n", "\r", "\n\r", Environment.NewLine };
1049      List<string> lines = new List<string>();
1050      foreach (var br in lineBreaks)
1051        lines.Add("line1" + br + "line2");
1052      XmlGenerator.Serialize(lines, tempFile);
1053      List<string> newLines = XmlParser.Deserialize<List<string>>(tempFile);
1054      Assert.AreEqual(lines.Count, newLines.Count);
1055      for (int i = 0; i < lineBreaks.Count; i++) {
1056        Assert.AreEqual(lines[i], newLines[i]);
1057      }
1058    }
1059
1060    [TestMethod]
1061    public void TestSpecialNumbers() {
1062      List<double> specials = new List<double>() { 1.0 / 0, -1.0 / 0, 0.0 / 0 };
1063      Assert.IsTrue(double.IsPositiveInfinity(specials[0]));
1064      Assert.IsTrue(double.IsNegativeInfinity(specials[1]));
1065      Assert.IsTrue(double.IsNaN(specials[2]));
1066      XmlGenerator.Serialize(specials, tempFile);
1067      List<double> newSpecials = XmlParser.Deserialize<List<double>>(tempFile);
1068      Assert.IsTrue(double.IsPositiveInfinity(newSpecials[0]));
1069      Assert.IsTrue(double.IsNegativeInfinity(newSpecials[1]));
1070      Assert.IsTrue(double.IsNaN(newSpecials[2]));
1071    }
1072
1073    [TestMethod]
1074    public void TestStringSplit() {
1075      string s = "1.2;2.3;3.4;;;4.9";
1076      var l = s.EnumerateSplit(';').ToList();
1077      Assert.AreEqual("1.2", l[0]);
1078      Assert.AreEqual("2.3", l[1]);
1079      Assert.AreEqual("3.4", l[2]);
1080      Assert.AreEqual("4.9", l[3]);
1081    }
1082
1083    [TestMethod]
1084    public void TestCompactNumberArraySerializer() {
1085      Random r = new Random();
1086      double[] a = new double[CompactNumberArray2StringSerializer.SPLIT_THRESHOLD * 2 + 1];
1087      for (int i = 0; i < a.Length; i++)
1088        a[i] = r.Next(10);
1089      var config = ConfigurationService.Instance.GetDefaultConfig(new XmlFormat());
1090      config = new Configuration(config.Format,
1091        config.PrimitiveSerializers.Where(s => s.SourceType != typeof(double[])),
1092        config.CompositeSerializers);
1093      XmlGenerator.Serialize(a, tempFile, config);
1094      double[] newA = XmlParser.Deserialize<double[]>(tempFile);
1095      Assert.AreEqual(a.Length, newA.Length);
1096      for (int i = 0; i < a.Rank; i++) {
1097        Assert.AreEqual(a.GetLength(i), newA.GetLength(i));
1098        Assert.AreEqual(a.GetLowerBound(i), newA.GetLowerBound(i));
1099      }
1100      for (int i = 0; i < a.Length; i++) {
1101        Assert.AreEqual(a[i], newA[i]);
1102      }
1103    }
1104    private class IdentityComparer<T> : IEqualityComparer<T> {
1105
1106      public bool Equals(T x, T y) {
1107        return x.Equals(y);
1108      }
1109
1110      public int GetHashCode(T obj) {
1111        return obj.GetHashCode();
1112      }
1113    }
1114
1115    [TestMethod]
1116    public void TestHashSetSerializer() {
1117      var hashSets = new List<HashSet<int>>() {
1118        new HashSet<int>(new[] { 1, 2, 3 }),
1119        new HashSet<int>(new[] { 4, 5, 6 }, new IdentityComparer<int>()),
1120      };
1121      XmlGenerator.Serialize(hashSets, tempFile);
1122      var newHashSets = XmlParser.Deserialize<List<HashSet<int>>>(tempFile);
1123      Assert.IsTrue(newHashSets[0].Contains(1));
1124      Assert.IsTrue(newHashSets[0].Contains(2));
1125      Assert.IsTrue(newHashSets[0].Contains(3));
1126      Assert.IsTrue(newHashSets[1].Contains(4));
1127      Assert.IsTrue(newHashSets[1].Contains(5));
1128      Assert.IsTrue(newHashSets[1].Contains(6));
1129      Assert.AreEqual(newHashSets[0].Comparer.GetType(), new HashSet<int>().Comparer.GetType());
1130      Assert.AreEqual(newHashSets[1].Comparer.GetType(), typeof(IdentityComparer<int>));
1131    }
1132
1133    [TestMethod]
1134    public void TestConcreteDictionarySerializer() {
1135      var dictionaries = new List<Dictionary<int, int>>() {
1136        new Dictionary<int, int>(),
1137        new Dictionary<int, int>(new IdentityComparer<int>()),
1138      };
1139      dictionaries[0].Add(1, 1);
1140      dictionaries[0].Add(2, 2);
1141      dictionaries[0].Add(3, 3);
1142      dictionaries[1].Add(4, 4);
1143      dictionaries[1].Add(5, 5);
1144      dictionaries[1].Add(6, 6);
1145      XmlGenerator.Serialize(dictionaries, tempFile);
1146      var newDictionaries = XmlParser.Deserialize<List<Dictionary<int, int>>>(tempFile);
1147      Assert.IsTrue(newDictionaries[0].ContainsKey(1));
1148      Assert.IsTrue(newDictionaries[0].ContainsKey(2));
1149      Assert.IsTrue(newDictionaries[0].ContainsKey(3));
1150      Assert.IsTrue(newDictionaries[1].ContainsKey(4));
1151      Assert.IsTrue(newDictionaries[1].ContainsKey(5));
1152      Assert.IsTrue(newDictionaries[1].ContainsKey(6));
1153      Assert.IsTrue(newDictionaries[0].ContainsValue(1));
1154      Assert.IsTrue(newDictionaries[0].ContainsValue(2));
1155      Assert.IsTrue(newDictionaries[0].ContainsValue(3));
1156      Assert.IsTrue(newDictionaries[1].ContainsValue(4));
1157      Assert.IsTrue(newDictionaries[1].ContainsValue(5));
1158      Assert.IsTrue(newDictionaries[1].ContainsValue(6));
1159      Assert.AreEqual(newDictionaries[0].Comparer.GetType(), new Dictionary<int, int>().Comparer.GetType());
1160      Assert.AreEqual(newDictionaries[1].Comparer.GetType(), typeof(IdentityComparer<int>));
1161    }
1162
1163    [ClassInitialize]
1164    public static void Initialize(TestContext testContext) {
1165      ConfigurationService.Instance.Reset();
1166    }
1167  }
1168}
Note: See TracBrowser for help on using the repository browser.