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

Last change on this file since 10896 was 10896, checked in by epitzer, 5 years ago

#1802 make the Number2StringSerializer accept nullable numbers

File size: 50.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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 System.Threading.Tasks;
32using HeuristicLab.Algorithms.GeneticAlgorithm;
33using HeuristicLab.Persistence.Auxiliary;
34using HeuristicLab.Persistence.Core;
35using HeuristicLab.Persistence.Core.Tokens;
36using HeuristicLab.Persistence.Default.CompositeSerializers;
37using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
38using HeuristicLab.Persistence.Default.DebugString;
39using HeuristicLab.Persistence.Default.Xml;
40using HeuristicLab.Persistence.Default.Xml.Primitive;
41using HeuristicLab.Persistence.Interfaces;
42using HeuristicLab.Tests;
43using Microsoft.VisualStudio.TestTools.UnitTesting;
44
45namespace HeuristicLab.Persistence.Tests {
46
47  [StorableClass]
48  public class NumberTest {
49    [Storable]
50    private bool _bool = true;
51    [Storable]
52    private byte _byte = 0xFF;
53    [Storable]
54    private sbyte _sbyte = 0xF;
55    [Storable]
56    private short _short = -123;
57    [Storable]
58    private ushort _ushort = 123;
59    [Storable]
60    private int _int = -123;
61    [Storable]
62    private uint _uint = 123;
63    [Storable]
64    private long _long = 123456;
65    [Storable]
66    private ulong _ulong = 123456;
67    public override bool Equals(object obj) {
68      NumberTest nt = obj as NumberTest;
69      if (nt == null)
70        throw new NotSupportedException();
71      return
72        nt._bool == _bool &&
73        nt._byte == _byte &&
74        nt._sbyte == _sbyte &&
75        nt._short == _short &&
76        nt._ushort == _ushort &&
77        nt._int == _int &&
78        nt._uint == _uint &&
79        nt._long == _long &&
80        nt._ulong == _ulong;
81    }
82    public override int GetHashCode() {
83      return
84        _bool.GetHashCode() ^
85        _byte.GetHashCode() ^
86        _sbyte.GetHashCode() ^
87        _short.GetHashCode() ^
88        _short.GetHashCode() ^
89        _int.GetHashCode() ^
90        _uint.GetHashCode() ^
91        _long.GetHashCode() ^
92        _ulong.GetHashCode();
93    }
94  }
95
96  [StorableClass]
97  public class NonDefaultConstructorClass {
98    [Storable]
99    int value;
100    public NonDefaultConstructorClass(int value) {
101      this.value = value;
102    }
103  }
104
105  [StorableClass]
106  public class IntWrapper {
107
108    [Storable]
109    public int Value;
110
111    private IntWrapper() { }
112
113    public IntWrapper(int value) {
114      this.Value = value;
115    }
116
117    public override bool Equals(object obj) {
118      if (obj as IntWrapper == null)
119        return false;
120      return Value.Equals(((IntWrapper)obj).Value);
121    }
122    public override int GetHashCode() {
123      return Value.GetHashCode();
124    }
125
126  }
127
128  [StorableClass]
129  public class PrimitivesTest : NumberTest {
130    [Storable]
131    private char c = 'e';
132    [Storable]
133    private long[,] _long_array =
134      new long[,] { { 123, 456, }, { 789, 123 } };
135    [Storable]
136    public List<int> list = new List<int> { 1, 2, 3, 4, 5 };
137    [Storable]
138    private object o = new object();
139    public override bool Equals(object obj) {
140      PrimitivesTest pt = obj as PrimitivesTest;
141      if (pt == null)
142        throw new NotSupportedException();
143      return base.Equals(obj) &&
144        c == pt.c &&
145        _long_array == pt._long_array &&
146        list == pt.list &&
147        o == pt.o;
148    }
149    public override int GetHashCode() {
150      return base.GetHashCode() ^
151        c.GetHashCode() ^
152        _long_array.GetHashCode() ^
153        list.GetHashCode() ^
154        o.GetHashCode();
155    }
156  }
157
158  public enum TestEnum { va1, va2, va3, va8 } ;
159
160  [StorableClass]
161  public class RootBase {
162    [Storable]
163    private string baseString = "   Serial  ";
164    [Storable]
165    public TestEnum myEnum = TestEnum.va3;
166    public override bool Equals(object obj) {
167      RootBase rb = obj as RootBase;
168      if (rb == null)
169        throw new NotSupportedException();
170      return baseString == rb.baseString &&
171        myEnum == rb.myEnum;
172    }
173    public override int GetHashCode() {
174      return baseString.GetHashCode() ^
175        myEnum.GetHashCode();
176    }
177  }
178
179  [StorableClass]
180  public class Root : RootBase {
181    [Storable]
182    public Stack<int> intStack = new Stack<int>();
183    [Storable]
184    public int[] i = new[] { 3, 4, 5, 6 };
185    [Storable(Name = "Test String")]
186    public string s;
187    [Storable]
188    public ArrayList intArray = new ArrayList(new[] { 1, 2, 3 });
189    [Storable]
190    public List<int> intList = new List<int>(new[] { 321, 312, 321 });
191    [Storable]
192    public Custom c;
193    [Storable]
194    public List<Root> selfReferences;
195    [Storable]
196    public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } };
197    [Storable]
198    public bool boolean = true;
199    [Storable]
200    public DateTime dateTime;
201    [Storable]
202    public KeyValuePair<string, int> kvp = new KeyValuePair<string, int>("Serial", 123);
203    [Storable]
204    public Dictionary<string, int> dict = new Dictionary<string, int>();
205    [Storable(DefaultValue = "default")]
206    public string uninitialized;
207  }
208
209  public enum SimpleEnum { one, two, three }
210  public enum ComplexEnum { one = 1, two = 2, three = 3 }
211  [FlagsAttribute]
212  public enum TrickyEnum { zero = 0, one = 1, two = 2 }
213
214  [StorableClass]
215  public class EnumTest {
216    [Storable]
217    public SimpleEnum simpleEnum = SimpleEnum.one;
218    [Storable]
219    public ComplexEnum complexEnum = (ComplexEnum)2;
220    [Storable]
221    public TrickyEnum trickyEnum = (TrickyEnum)15;
222  }
223
224  [StorableClass]
225  public class Custom {
226    [Storable]
227    public int i;
228    [Storable]
229    public Root r;
230    [Storable]
231    public string name = "<![CDATA[<![CDATA[Serial]]>]]>";
232  }
233
234  [StorableClass]
235  public class Manager {
236
237    public DateTime lastLoadTime;
238    [Storable]
239    private DateTime lastLoadTimePersistence {
240      get { return lastLoadTime; }
241      set { lastLoadTime = DateTime.Now; }
242    }
243    [Storable]
244    public double? dbl;
245  }
246
247  [StorableClass]
248  public class C {
249    [Storable]
250    public C[][] allCs;
251    [Storable]
252    public KeyValuePair<List<C>, C> kvpList;
253  }
254
255  public class NonSerializable {
256    int x = 0;
257    public override bool Equals(object obj) {
258      NonSerializable ns = obj as NonSerializable;
259      if (ns == null)
260        throw new NotSupportedException();
261      return ns.x == x;
262    }
263    public override int GetHashCode() {
264      return x.GetHashCode();
265    }
266  }
267
268
269  [TestClass]
270  public class UseCases {
271
272    private string tempFile;
273
274    [TestInitialize()]
275    public void CreateTempFile() {
276      tempFile = Path.GetTempFileName();
277    }
278
279    [TestCleanup()]
280    public void ClearTempFile() {
281      StreamReader reader = new StreamReader(tempFile);
282      string s = reader.ReadToEnd();
283      reader.Close();
284      File.Delete(tempFile);
285    }
286
287    [TestMethod]
288    [TestCategory("Persistence")]
289    [TestProperty("Time", "short")]
290    public void ComplexStorable() {
291      Root r = InitializeComplexStorable();
292      XmlGenerator.Serialize(r, tempFile);
293      Root newR = (Root)XmlParser.Deserialize(tempFile);
294      CompareComplexStorables(r, newR);
295    }
296
297    [TestMethod]
298    [TestCategory("Persistence")]
299    [TestProperty("Time", "short")]
300    public void ComplexEasyStorable() {
301      Root r = InitializeComplexStorable();
302      ReadableXmlGenerator.Serialize(r, tempFile);
303      using (var reader = new StreamReader(tempFile)) {
304        string text = reader.ReadToEnd();
305        Assert.IsTrue(text.StartsWith("<Root"));
306      }
307    }
308
309    private static void CompareComplexStorables(Root r, Root newR) {
310      Assert.AreEqual(
311        DebugStringGenerator.Serialize(r),
312        DebugStringGenerator.Serialize(newR));
313      Assert.AreSame(newR, newR.selfReferences[0]);
314      Assert.AreNotSame(r, newR);
315      Assert.AreEqual(r.myEnum, TestEnum.va1);
316      Assert.AreEqual(r.i[0], 7);
317      Assert.AreEqual(r.i[1], 5);
318      Assert.AreEqual(r.i[2], 6);
319      Assert.AreEqual(r.s, "new value");
320      Assert.AreEqual(r.intArray[0], 3);
321      Assert.AreEqual(r.intArray[1], 2);
322      Assert.AreEqual(r.intArray[2], 1);
323      Assert.AreEqual(r.intList[0], 9);
324      Assert.AreEqual(r.intList[1], 8);
325      Assert.AreEqual(r.intList[2], 7);
326      Assert.AreEqual(r.multiDimArray[0, 0], 5);
327      Assert.AreEqual(r.multiDimArray[0, 1], 4);
328      Assert.AreEqual(r.multiDimArray[0, 2], 3);
329      Assert.AreEqual(r.multiDimArray[1, 0], 1);
330      Assert.AreEqual(r.multiDimArray[1, 1], 4);
331      Assert.AreEqual(r.multiDimArray[1, 2], 6);
332      Assert.IsFalse(r.boolean);
333      Assert.IsTrue((DateTime.Now - r.dateTime).TotalSeconds < 10);
334      Assert.AreEqual(r.kvp.Key, "string key");
335      Assert.AreEqual(r.kvp.Value, 321);
336      Assert.IsNull(r.uninitialized);
337      Assert.AreEqual(newR.myEnum, TestEnum.va1);
338      Assert.AreEqual(newR.i[0], 7);
339      Assert.AreEqual(newR.i[1], 5);
340      Assert.AreEqual(newR.i[2], 6);
341      Assert.AreEqual(newR.s, "new value");
342      Assert.AreEqual(newR.intArray[0], 3);
343      Assert.AreEqual(newR.intArray[1], 2);
344      Assert.AreEqual(newR.intArray[2], 1);
345      Assert.AreEqual(newR.intList[0], 9);
346      Assert.AreEqual(newR.intList[1], 8);
347      Assert.AreEqual(newR.intList[2], 7);
348      Assert.AreEqual(newR.multiDimArray[0, 0], 5);
349      Assert.AreEqual(newR.multiDimArray[0, 1], 4);
350      Assert.AreEqual(newR.multiDimArray[0, 2], 3);
351      Assert.AreEqual(newR.multiDimArray[1, 0], 1);
352      Assert.AreEqual(newR.multiDimArray[1, 1], 4);
353      Assert.AreEqual(newR.multiDimArray[1, 2], 6);
354      Assert.AreEqual(newR.intStack.Pop(), 3);
355      Assert.AreEqual(newR.intStack.Pop(), 2);
356      Assert.AreEqual(newR.intStack.Pop(), 1);
357      Assert.IsFalse(newR.boolean);
358      Assert.IsTrue((DateTime.Now - newR.dateTime).TotalSeconds < 10);
359      Assert.AreEqual(newR.kvp.Key, "string key");
360      Assert.AreEqual(newR.kvp.Value, 321);
361      Assert.IsNull(newR.uninitialized);
362    }
363
364    private static Root InitializeComplexStorable() {
365      Root r = new Root();
366      r.intStack.Push(1);
367      r.intStack.Push(2);
368      r.intStack.Push(3);
369      r.selfReferences = new List<Root> { r, r };
370      r.c = new Custom { r = r };
371      r.dict.Add("one", 1);
372      r.dict.Add("two", 2);
373      r.dict.Add("three", 3);
374      r.myEnum = TestEnum.va1;
375      r.i = new[] { 7, 5, 6 };
376      r.s = "new value";
377      r.intArray = new ArrayList { 3, 2, 1 };
378      r.intList = new List<int> { 9, 8, 7 };
379      r.multiDimArray = new double[,] { { 5, 4, 3 }, { 1, 4, 6 } };
380      r.boolean = false;
381      r.dateTime = DateTime.Now;
382      r.kvp = new KeyValuePair<string, int>("string key", 321);
383      r.uninitialized = null;
384
385      return r;
386    }
387
388    [TestMethod]
389    [TestCategory("Persistence")]
390    [TestProperty("Time", "short")]
391    public void SelfReferences() {
392      C c = new C();
393      C[][] cs = new C[2][];
394      cs[0] = new C[] { c };
395      cs[1] = new C[] { c };
396      c.allCs = cs;
397      c.kvpList = new KeyValuePair<List<C>, C>(new List<C> { c }, c);
398      XmlGenerator.Serialize(cs, tempFile);
399      object o = XmlParser.Deserialize(tempFile);
400      Assert.AreEqual(
401        DebugStringGenerator.Serialize(cs),
402        DebugStringGenerator.Serialize(o));
403      Assert.AreSame(c, c.allCs[0][0]);
404      Assert.AreSame(c, c.allCs[1][0]);
405      Assert.AreSame(c, c.kvpList.Key[0]);
406      Assert.AreSame(c, c.kvpList.Value);
407      C[][] newCs = (C[][])o;
408      C newC = newCs[0][0];
409      Assert.AreSame(newC, newC.allCs[0][0]);
410      Assert.AreSame(newC, newC.allCs[1][0]);
411      Assert.AreSame(newC, newC.kvpList.Key[0]);
412      Assert.AreSame(newC, newC.kvpList.Value);
413    }
414
415    [TestMethod]
416    [TestCategory("Persistence")]
417    [TestProperty("Time", "short")]
418    public void ArrayCreation() {
419      ArrayList[] arrayListArray = new ArrayList[4];
420      arrayListArray[0] = new ArrayList();
421      arrayListArray[0].Add(arrayListArray);
422      arrayListArray[0].Add(arrayListArray);
423      arrayListArray[1] = new ArrayList();
424      arrayListArray[1].Add(arrayListArray);
425      arrayListArray[2] = new ArrayList();
426      arrayListArray[2].Add(arrayListArray);
427      arrayListArray[2].Add(arrayListArray);
428      Array a = Array.CreateInstance(
429                              typeof(object),
430                              new[] { 1, 2 }, new[] { 3, 4 });
431      arrayListArray[2].Add(a);
432      XmlGenerator.Serialize(arrayListArray, tempFile);
433      object o = XmlParser.Deserialize(tempFile);
434      Assert.AreEqual(
435        DebugStringGenerator.Serialize(arrayListArray),
436        DebugStringGenerator.Serialize(o));
437      ArrayList[] newArray = (ArrayList[])o;
438      Assert.AreSame(arrayListArray, arrayListArray[0][0]);
439      Assert.AreSame(arrayListArray, arrayListArray[2][1]);
440      Assert.AreSame(newArray, newArray[0][0]);
441      Assert.AreSame(newArray, newArray[2][1]);
442    }
443
444    [TestMethod]
445    [TestCategory("Persistence")]
446    [TestProperty("Time", "short")]
447    public void CustomSerializationProperty() {
448      Manager m = new Manager();
449      XmlGenerator.Serialize(m, tempFile);
450      Manager newM = (Manager)XmlParser.Deserialize(tempFile);
451      Assert.AreNotEqual(
452        DebugStringGenerator.Serialize(m),
453        DebugStringGenerator.Serialize(newM));
454      Assert.AreEqual(m.dbl, newM.dbl);
455      Assert.AreEqual(m.lastLoadTime, new DateTime());
456      Assert.AreNotEqual(newM.lastLoadTime, new DateTime());
457      Assert.IsTrue((DateTime.Now - newM.lastLoadTime).TotalSeconds < 10);
458    }
459
460    [TestMethod]
461    [TestCategory("Persistence")]
462    [TestProperty("Time", "short")]
463    public void Primitives() {
464      PrimitivesTest sdt = new PrimitivesTest();
465      XmlGenerator.Serialize(sdt, tempFile);
466      object o = XmlParser.Deserialize(tempFile);
467      Assert.AreEqual(
468        DebugStringGenerator.Serialize(sdt),
469        DebugStringGenerator.Serialize(o));
470    }
471
472    [TestMethod]
473    [TestCategory("Persistence")]
474    [TestProperty("Time", "short")]
475    public void MultiDimensionalArray() {
476      string[,] mDimString = new string[,] {
477        {"ora", "et", "labora"},
478        {"Beten", "und", "Arbeiten"}
479      };
480      XmlGenerator.Serialize(mDimString, tempFile);
481      object o = XmlParser.Deserialize(tempFile);
482      Assert.AreEqual(
483        DebugStringGenerator.Serialize(mDimString),
484        DebugStringGenerator.Serialize(o));
485    }
486
487    [StorableClass]
488    public class NestedType {
489      [Storable]
490      private string value = "value";
491      public override bool Equals(object obj) {
492        NestedType nt = obj as NestedType;
493        if (nt == null)
494          throw new NotSupportedException();
495        return nt.value == value;
496      }
497      public override int GetHashCode() {
498        return value.GetHashCode();
499      }
500    }
501
502    [TestMethod]
503    [TestCategory("Persistence")]
504    [TestProperty("Time", "short")]
505    public void NestedTypeTest() {
506      NestedType t = new NestedType();
507      XmlGenerator.Serialize(t, tempFile);
508      object o = XmlParser.Deserialize(tempFile);
509      Assert.AreEqual(
510        DebugStringGenerator.Serialize(t),
511        DebugStringGenerator.Serialize(o));
512      Assert.IsTrue(t.Equals(o));
513    }
514
515
516    [TestMethod]
517    [TestCategory("Persistence")]
518    [TestProperty("Time", "short")]
519    public void SimpleArray() {
520      string[] strings = { "ora", "et", "labora" };
521      XmlGenerator.Serialize(strings, tempFile);
522      object o = XmlParser.Deserialize(tempFile);
523      Assert.AreEqual(
524        DebugStringGenerator.Serialize(strings),
525        DebugStringGenerator.Serialize(o));
526    }
527
528    [TestMethod]
529    [TestCategory("Persistence")]
530    [TestProperty("Time", "short")]
531    public void PrimitiveRoot() {
532      XmlGenerator.Serialize(12.3f, tempFile);
533      object o = XmlParser.Deserialize(tempFile);
534      Assert.AreEqual(
535        DebugStringGenerator.Serialize(12.3f),
536        DebugStringGenerator.Serialize(o));
537    }
538
539    private string formatFullMemberName(MemberInfo mi) {
540      return new StringBuilder()
541        .Append(mi.DeclaringType.Assembly.GetName().Name)
542        .Append(": ")
543        .Append(mi.DeclaringType.Namespace)
544        .Append('.')
545        .Append(mi.DeclaringType.Name)
546        .Append('.')
547        .Append(mi.Name).ToString();
548    }
549
550    public void CodingConventions() {
551      List<string> lowerCaseMethodNames = new List<string>();
552      List<string> lowerCaseProperties = new List<string>();
553      List<string> lowerCaseFields = new List<string>();
554      foreach (Assembly a in PluginLoader.Assemblies) {
555        if (!a.GetName().Name.StartsWith("HeuristicLab"))
556          continue;
557        foreach (Type t in a.GetTypes()) {
558          foreach (MemberInfo mi in t.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) {
559            if (mi.DeclaringType.Name.StartsWith("<>"))
560              continue;
561            if (char.IsLower(mi.Name[0])) {
562              if (mi.MemberType == MemberTypes.Field)
563                lowerCaseFields.Add(formatFullMemberName(mi));
564              if (mi.MemberType == MemberTypes.Property)
565                lowerCaseProperties.Add(formatFullMemberName(mi));
566              if (mi.MemberType == MemberTypes.Method &&
567                !mi.Name.StartsWith("get_") &&
568                !mi.Name.StartsWith("set_") &&
569                !mi.Name.StartsWith("add_") &&
570                !mi.Name.StartsWith("remove_") &&
571                !mi.Name.StartsWith("op_"))
572                lowerCaseMethodNames.Add(formatFullMemberName(mi));
573            }
574          }
575        }
576      }
577      //Assert.AreEqual("", lowerCaseFields.Aggregate("", (a, b) => a + "\r\n" + b));
578      Assert.AreEqual("", lowerCaseMethodNames.Aggregate("", (a, b) => a + "\r\n" + b));
579      Assert.AreEqual("", lowerCaseProperties.Aggregate("", (a, b) => a + "\r\n" + b));
580    }
581
582    [TestMethod]
583    [TestCategory("Persistence")]
584    [TestProperty("Time", "short")]
585    public void Number2StringDecomposer() {
586      NumberTest sdt = new NumberTest();
587      XmlGenerator.Serialize(sdt, tempFile,
588        new Configuration(new XmlFormat(),
589          new List<IPrimitiveSerializer> { new String2XmlSerializer() },
590          new List<ICompositeSerializer> { 
591            new StorableSerializer(),
592            new Number2StringSerializer() }));
593      object o = XmlParser.Deserialize(tempFile);
594      Assert.AreEqual(
595        DebugStringGenerator.Serialize(sdt),
596        DebugStringGenerator.Serialize(o));
597      Assert.IsTrue(sdt.Equals(o));
598    }
599
600    [TestMethod]
601    [TestCategory("Persistence")]
602    [TestProperty("Time", "short")]
603    public void Enums() {
604      EnumTest et = new EnumTest();
605      et.simpleEnum = SimpleEnum.two;
606      et.complexEnum = ComplexEnum.three;
607      et.trickyEnum = TrickyEnum.two | TrickyEnum.one;
608      XmlGenerator.Serialize(et, tempFile);
609      EnumTest newEt = (EnumTest)XmlParser.Deserialize(tempFile);
610      Assert.AreEqual(et.simpleEnum, SimpleEnum.two);
611      Assert.AreEqual(et.complexEnum, ComplexEnum.three);
612      Assert.AreEqual(et.trickyEnum, (TrickyEnum)3);
613    }
614
615    [TestMethod]
616    [TestCategory("Persistence")]
617    [TestProperty("Time", "short")]
618    public void TestAliasingWithOverriddenEquals() {
619      List<IntWrapper> ints = new List<IntWrapper>();
620      ints.Add(new IntWrapper(1));
621      ints.Add(new IntWrapper(1));
622      Assert.AreEqual(ints[0], ints[1]);
623      Assert.AreNotSame(ints[0], ints[1]);
624      XmlGenerator.Serialize(ints, tempFile);
625      List<IntWrapper> newInts = (List<IntWrapper>)XmlParser.Deserialize(tempFile);
626      Assert.AreEqual(newInts[0].Value, 1);
627      Assert.AreEqual(newInts[1].Value, 1);
628      Assert.AreEqual(newInts[0], newInts[1]);
629      Assert.AreNotSame(newInts[0], newInts[1]);
630    }
631
632    [TestMethod]
633    [TestCategory("Persistence")]
634    [TestProperty("Time", "short")]
635    public void NonDefaultConstructorTest() {
636      NonDefaultConstructorClass c = new NonDefaultConstructorClass(1);
637      try {
638        XmlGenerator.Serialize(c, tempFile);
639        Assert.Fail("Exception not thrown");
640      } catch (PersistenceException) {
641      }
642    }
643
644    [TestMethod]
645    [TestCategory("Persistence")]
646    [TestProperty("Time", "short")]
647    public void TestSavingException() {
648      List<int> list = new List<int> { 1, 2, 3 };
649      XmlGenerator.Serialize(list, tempFile);
650      NonSerializable s = new NonSerializable();
651      try {
652        XmlGenerator.Serialize(s, tempFile);
653        Assert.Fail("Exception expected");
654      } catch (PersistenceException) { }
655      List<int> newList = (List<int>)XmlParser.Deserialize(tempFile);
656      Assert.AreEqual(list[0], newList[0]);
657      Assert.AreEqual(list[1], newList[1]);
658    }
659
660    [TestMethod]
661    [TestCategory("Persistence")]
662    [TestProperty("Time", "short")]
663    public void TestTypeStringConversion() {
664      string name = typeof(List<int>[]).AssemblyQualifiedName;
665      string shortName =
666        "System.Collections.Generic.List`1[[System.Int32, mscorlib]][], mscorlib";
667      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
668      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
669      Assert.AreEqual(shortName, typeof(List<int>[]).VersionInvariantName());
670    }
671
672    [TestMethod]
673    [TestCategory("Persistence")]
674    [TestProperty("Time", "short")]
675    public void TestHexadecimalPublicKeyToken() {
676      string name = "TestClass, TestAssembly, Version=1.2.3.4, PublicKey=1234abc";
677      string shortName = "TestClass, TestAssembly";
678      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
679      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
680    }
681
682    [TestMethod]
683    [TestCategory("Persistence")]
684    [TestProperty("Time", "short")]
685    public void TestMultipleFailure() {
686      List<NonSerializable> l = new List<NonSerializable>();
687      l.Add(new NonSerializable());
688      l.Add(new NonSerializable());
689      l.Add(new NonSerializable());
690      try {
691        Serializer s = new Serializer(l,
692          ConfigurationService.Instance.GetConfiguration(new XmlFormat()),
693          "ROOT", true);
694        StringBuilder tokens = new StringBuilder();
695        foreach (var token in s) {
696          tokens.Append(token.ToString());
697        }
698        Assert.Fail("Exception expected");
699      } catch (PersistenceException px) {
700        Assert.AreEqual(3, px.Data.Count);
701      }
702    }
703
704    [TestMethod]
705    [TestCategory("Persistence")]
706    [TestProperty("Time", "short")]
707    public void TestAssemblyVersionCheck() {
708      IntWrapper i = new IntWrapper(1);
709      Serializer s = new Serializer(i, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
710      XmlGenerator g = new XmlGenerator();
711      StringBuilder dataString = new StringBuilder();
712      foreach (var token in s) {
713        dataString.Append(g.Format(token));
714      }
715      StringBuilder typeString = new StringBuilder();
716      foreach (var line in g.Format(s.TypeCache))
717        typeString.Append(line);
718      Deserializer d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(typeString.ToString())));
719      XmlParser p = new XmlParser(new StringReader(dataString.ToString()));
720      IntWrapper newI = (IntWrapper)d.Deserialize(p);
721      Assert.AreEqual(i.Value, newI.Value);
722
723      string newTypeString = Regex.Replace(typeString.ToString(),
724        "Version=\\d+\\.\\d+\\.\\d+\\.\\d+",
725        "Version=0.0.9999.9999");
726      try {
727        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
728        Assert.Fail("Exception expected");
729      } catch (PersistenceException x) {
730        Assert.IsTrue(x.Message.Contains("incompatible"));
731      }
732      newTypeString = Regex.Replace(typeString.ToString(),
733        "Version=(\\d+\\.\\d+)\\.\\d+\\.\\d+",
734        "Version=$1.9999.9999");
735      try {
736        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
737        Assert.Fail("Exception expected");
738      } catch (PersistenceException x) {
739        Assert.IsTrue(x.Message.Contains("newer"));
740      }
741    }
742
743    [TestMethod]
744    [TestCategory("Persistence")]
745    [TestProperty("Time", "short")]
746    public void InheritanceTest() {
747      New n = new New();
748      XmlGenerator.Serialize(n, tempFile);
749      New nn = (New)XmlParser.Deserialize(tempFile);
750      Assert.AreEqual(n.Name, nn.Name);
751      Assert.AreEqual(((Override)n).Name, ((Override)nn).Name);
752    }
753
754    [StorableClass]
755    class Child {
756      [Storable]
757      public GrandParent grandParent;
758    }
759
760    [StorableClass]
761    class Parent {
762      [Storable]
763      public Child child;
764    }
765
766    [StorableClass]
767    class GrandParent {
768      [Storable]
769      public Parent parent;
770    }
771
772    [TestMethod]
773    [TestCategory("Persistence")]
774    [TestProperty("Time", "short")]
775    public void InstantiateParentChainReference() {
776      GrandParent gp = new GrandParent();
777      gp.parent = new Parent();
778      gp.parent.child = new Child();
779      gp.parent.child.grandParent = gp;
780      Assert.AreSame(gp, gp.parent.child.grandParent);
781      XmlGenerator.Serialize(gp, tempFile);
782      GrandParent newGp = (GrandParent)XmlParser.Deserialize(tempFile);
783      Assert.AreSame(newGp, newGp.parent.child.grandParent);
784    }
785
786    struct TestStruct {
787      int value;
788      int PropertyValue { get; set; }
789      public TestStruct(int value)
790        : this() {
791        this.value = value;
792        PropertyValue = value;
793      }
794    }
795
796    [TestMethod]
797    [TestCategory("Persistence")]
798    [TestProperty("Time", "short")]
799    public void StructTest() {
800      TestStruct s = new TestStruct(10);
801      XmlGenerator.Serialize(s, tempFile);
802      TestStruct newS = (TestStruct)XmlParser.Deserialize(tempFile);
803      Assert.AreEqual(s, newS);
804    }
805
806    [TestMethod]
807    [TestCategory("Persistence")]
808    [TestProperty("Time", "short")]
809    public void PointTest() {
810      Point p = new Point(12, 34);
811      XmlGenerator.Serialize(p, tempFile);
812      Point newP = (Point)XmlParser.Deserialize(tempFile);
813      Assert.AreEqual(p, newP);
814    }
815
816    [TestMethod]
817    [TestCategory("Persistence")]
818    [TestProperty("Time", "short")]
819    public void NullableValueTypes() {
820      double?[] d = new double?[] { null, 1, 2, 3 };
821      XmlGenerator.Serialize(d, tempFile);
822      double?[] newD = (double?[])XmlParser.Deserialize(tempFile);
823      Assert.AreEqual(d[0], newD[0]);
824      Assert.AreEqual(d[1], newD[1]);
825      Assert.AreEqual(d[2], newD[2]);
826      Assert.AreEqual(d[3], newD[3]);
827    }
828
829    [TestMethod]
830    [TestCategory("Persistence")]
831    [TestProperty("Time", "short")]
832    public void BitmapTest() {
833      Icon icon = System.Drawing.SystemIcons.Hand;
834      Bitmap bitmap = icon.ToBitmap();
835      XmlGenerator.Serialize(bitmap, tempFile);
836      Bitmap newBitmap = (Bitmap)XmlParser.Deserialize(tempFile);
837
838      Assert.AreEqual(bitmap.Size, newBitmap.Size);
839      for (int i = 0; i < bitmap.Size.Width; i++)
840        for (int j = 0; j < bitmap.Size.Height; j++)
841          Assert.AreEqual(bitmap.GetPixel(i, j), newBitmap.GetPixel(i, j));
842    }
843
844    [StorableClass]
845    private class PersistenceHooks {
846      [Storable]
847      public int a;
848      [Storable]
849      public int b;
850      public int sum;
851      public bool WasSerialized { get; private set; }
852      [StorableHook(HookType.BeforeSerialization)]
853      void PreSerializationHook() {
854        WasSerialized = true;
855      }
856      [StorableHook(HookType.AfterDeserialization)]
857      void PostDeserializationHook() {
858        sum = a + b;
859      }
860    }
861
862    [TestMethod]
863    [TestCategory("Persistence")]
864    [TestProperty("Time", "short")]
865    public void HookTest() {
866      PersistenceHooks hookTest = new PersistenceHooks();
867      hookTest.a = 2;
868      hookTest.b = 5;
869      Assert.IsFalse(hookTest.WasSerialized);
870      Assert.AreEqual(hookTest.sum, 0);
871      XmlGenerator.Serialize(hookTest, tempFile);
872      Assert.IsTrue(hookTest.WasSerialized);
873      Assert.AreEqual(hookTest.sum, 0);
874      PersistenceHooks newHookTest = (PersistenceHooks)XmlParser.Deserialize(tempFile);
875      Assert.AreEqual(newHookTest.a, hookTest.a);
876      Assert.AreEqual(newHookTest.b, hookTest.b);
877      Assert.AreEqual(newHookTest.sum, newHookTest.a + newHookTest.b);
878      Assert.IsFalse(newHookTest.WasSerialized);
879    }
880
881    [StorableClass]
882    private class CustomConstructor {
883      public string Value = "none";
884      public CustomConstructor() {
885        Value = "default";
886      }
887      [StorableConstructor]
888      private CustomConstructor(bool deserializing) {
889        Assert.IsTrue(deserializing);
890        Value = "persistence";
891      }
892    }
893
894    [TestMethod]
895    [TestCategory("Persistence")]
896    [TestProperty("Time", "short")]
897    public void TestCustomConstructor() {
898      CustomConstructor cc = new CustomConstructor();
899      Assert.AreEqual(cc.Value, "default");
900      XmlGenerator.Serialize(cc, tempFile);
901      CustomConstructor newCC = (CustomConstructor)XmlParser.Deserialize(tempFile);
902      Assert.AreEqual(newCC.Value, "persistence");
903    }
904
905    [StorableClass]
906    public class ExplodingDefaultConstructor {
907      public ExplodingDefaultConstructor() {
908        throw new Exception("this constructor will always fail");
909      }
910      public ExplodingDefaultConstructor(string password) {
911      }
912    }
913
914    [TestMethod]
915    [TestCategory("Persistence")]
916    [TestProperty("Time", "short")]
917    public void TestConstructorExceptionUnwrapping() {
918      ExplodingDefaultConstructor x = new ExplodingDefaultConstructor("password");
919      XmlGenerator.Serialize(x, tempFile);
920      try {
921        ExplodingDefaultConstructor newX = (ExplodingDefaultConstructor)XmlParser.Deserialize(tempFile);
922        Assert.Fail("Exception expected");
923      } catch (PersistenceException pe) {
924        Assert.AreEqual(pe.InnerException.Message, "this constructor will always fail");
925      }
926    }
927
928    [TestMethod]
929    [TestCategory("Persistence")]
930    [TestProperty("Time", "short")]
931    public void TestRejectionJustifications() {
932      NonSerializable ns = new NonSerializable();
933      try {
934        XmlGenerator.Serialize(ns, tempFile);
935        Assert.Fail("PersistenceException expected");
936      } catch (PersistenceException x) {
937        Assert.IsTrue(x.Message.Contains(new StorableSerializer().JustifyRejection(typeof(NonSerializable))));
938      }
939    }
940
941    [TestMethod]
942    [TestCategory("Persistence")]
943    [TestProperty("Time", "short")]
944    public void TestStreaming() {
945      using (MemoryStream stream = new MemoryStream()) {
946        Root r = InitializeComplexStorable();
947        XmlGenerator.Serialize(r, stream);
948        using (MemoryStream stream2 = new MemoryStream(stream.ToArray())) {
949          Root newR = (Root)XmlParser.Deserialize(stream2);
950          CompareComplexStorables(r, newR);
951        }
952      }
953    }
954
955    [StorableClass]
956    public class HookInheritanceTestBase {
957      [Storable]
958      public object a;
959      public object link;
960      [StorableHook(HookType.AfterDeserialization)]
961      private void relink() {
962        link = a;
963      }
964    }
965
966    [StorableClass]
967    public class HookInheritanceTestDerivedClass : HookInheritanceTestBase {
968      [Storable]
969      public object b;
970      [StorableHook(HookType.AfterDeserialization)]
971      private void relink() {
972        Assert.AreSame(a, link);
973        link = b;
974      }
975    }
976
977    [TestMethod]
978    [TestCategory("Persistence")]
979    [TestProperty("Time", "short")]
980    public void TestLinkInheritance() {
981      HookInheritanceTestDerivedClass c = new HookInheritanceTestDerivedClass();
982      c.a = new object();
983      XmlGenerator.Serialize(c, tempFile);
984      HookInheritanceTestDerivedClass newC = (HookInheritanceTestDerivedClass)XmlParser.Deserialize(tempFile);
985      Assert.AreSame(c.b, c.link);
986    }
987
988    [StorableClass(StorableClassType.AllFields)]
989    public class AllFieldsStorable {
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 AllFieldsStorable(bool isDeserializing) {
997        if (!isDeserializing) {
998          Value1 = 12;
999          Value2 = 23;
1000          Value3 = 34;
1001          Value4 = 56;
1002        }
1003      }
1004    }
1005
1006    [TestMethod]
1007    [TestCategory("Persistence")]
1008    [TestProperty("Time", "short")]
1009    public void TestStorableClassDiscoveryAllFields() {
1010      AllFieldsStorable afs = new AllFieldsStorable(false);
1011      XmlGenerator.Serialize(afs, tempFile);
1012      AllFieldsStorable newAfs = (AllFieldsStorable)XmlParser.Deserialize(tempFile);
1013      Assert.AreEqual(afs.Value1, newAfs.Value1);
1014      Assert.AreEqual(afs.Value2, newAfs.Value2);
1015      Assert.AreEqual(0, newAfs.Value3);
1016      Assert.AreEqual(0, newAfs.Value4);
1017    }
1018
1019    [StorableClass(StorableClassType.AllProperties)]
1020    public class AllPropertiesStorable {
1021      public int Value1 = 1;
1022      [Storable]
1023      public int Value2 = 2;
1024      public int Value3 { get; private set; }
1025      public int Value4 { get; private set; }
1026      [StorableConstructor]
1027      public AllPropertiesStorable(bool isDeserializing) {
1028        if (!isDeserializing) {
1029          Value1 = 12;
1030          Value2 = 23;
1031          Value3 = 34;
1032          Value4 = 56;
1033        }
1034      }
1035    }
1036
1037    [TestMethod]
1038    [TestCategory("Persistence")]
1039    [TestProperty("Time", "short")]
1040    public void TestStorableClassDiscoveryAllProperties() {
1041      AllPropertiesStorable afs = new AllPropertiesStorable(false);
1042      XmlGenerator.Serialize(afs, tempFile);
1043      AllPropertiesStorable newAfs = (AllPropertiesStorable)XmlParser.Deserialize(tempFile);
1044      Assert.AreEqual(1, newAfs.Value1);
1045      Assert.AreEqual(2, newAfs.Value2);
1046      Assert.AreEqual(afs.Value3, newAfs.Value3);
1047      Assert.AreEqual(afs.Value4, newAfs.Value4);
1048
1049    }
1050
1051    [StorableClass(StorableClassType.AllFieldsAndAllProperties)]
1052    public class AllFieldsAndAllPropertiesStorable {
1053      public int Value1 = 1;
1054      [Storable]
1055      public int Value2 = 2;
1056      public int Value3 { get; private set; }
1057      public int Value4 { get; private set; }
1058      [StorableConstructor]
1059      public AllFieldsAndAllPropertiesStorable(bool isDeserializing) {
1060        if (!isDeserializing) {
1061          Value1 = 12;
1062          Value2 = 23;
1063          Value3 = 34;
1064          Value4 = 56;
1065        }
1066      }
1067    }
1068
1069    [TestMethod]
1070    [TestCategory("Persistence")]
1071    [TestProperty("Time", "short")]
1072    public void TestStorableClassDiscoveryAllFieldsAndAllProperties() {
1073      AllFieldsAndAllPropertiesStorable afs = new AllFieldsAndAllPropertiesStorable(false);
1074      XmlGenerator.Serialize(afs, tempFile);
1075      AllFieldsAndAllPropertiesStorable newAfs = (AllFieldsAndAllPropertiesStorable)XmlParser.Deserialize(tempFile);
1076      Assert.AreEqual(afs.Value1, newAfs.Value1);
1077      Assert.AreEqual(afs.Value2, newAfs.Value2);
1078      Assert.AreEqual(afs.Value3, newAfs.Value3);
1079      Assert.AreEqual(afs.Value4, newAfs.Value4);
1080    }
1081
1082    [StorableClass(StorableClassType.MarkedOnly)]
1083    public class MarkedOnlyStorable {
1084      public int Value1 = 1;
1085      [Storable]
1086      public int Value2 = 2;
1087      public int Value3 { get; private set; }
1088      public int Value4 { get; private set; }
1089      [StorableConstructor]
1090      public MarkedOnlyStorable(bool isDeserializing) {
1091        if (!isDeserializing) {
1092          Value1 = 12;
1093          Value2 = 23;
1094          Value3 = 34;
1095          Value4 = 56;
1096        }
1097      }
1098    }
1099
1100    [TestMethod]
1101    [TestCategory("Persistence")]
1102    [TestProperty("Time", "short")]
1103    public void TestStorableClassDiscoveryMarkedOnly() {
1104      MarkedOnlyStorable afs = new MarkedOnlyStorable(false);
1105      XmlGenerator.Serialize(afs, tempFile);
1106      MarkedOnlyStorable newAfs = (MarkedOnlyStorable)XmlParser.Deserialize(tempFile);
1107      Assert.AreEqual(1, newAfs.Value1);
1108      Assert.AreEqual(afs.Value2, newAfs.Value2);
1109      Assert.AreEqual(0, newAfs.Value3);
1110      Assert.AreEqual(0, newAfs.Value4);
1111    }
1112
1113    [TestMethod]
1114    [TestCategory("Persistence")]
1115    [TestProperty("Time", "short")]
1116    public void TestLineEndings() {
1117      List<string> lineBreaks = new List<string> { "\r\n", "\n", "\r", "\n\r", Environment.NewLine };
1118      List<string> lines = new List<string>();
1119      foreach (var br in lineBreaks)
1120        lines.Add("line1" + br + "line2");
1121      XmlGenerator.Serialize(lines, tempFile);
1122      List<string> newLines = XmlParser.Deserialize<List<string>>(tempFile);
1123      Assert.AreEqual(lines.Count, newLines.Count);
1124      for (int i = 0; i < lineBreaks.Count; i++) {
1125        Assert.AreEqual(lines[i], newLines[i]);
1126      }
1127    }
1128
1129    [TestMethod]
1130    [TestCategory("Persistence")]
1131    [TestProperty("Time", "short")]
1132    public void TestSpecialNumbers() {
1133      List<double> specials = new List<double>() { 1.0 / 0, -1.0 / 0, 0.0 / 0 };
1134      Assert.IsTrue(double.IsPositiveInfinity(specials[0]));
1135      Assert.IsTrue(double.IsNegativeInfinity(specials[1]));
1136      Assert.IsTrue(double.IsNaN(specials[2]));
1137      XmlGenerator.Serialize(specials, tempFile);
1138      List<double> newSpecials = XmlParser.Deserialize<List<double>>(tempFile);
1139      Assert.IsTrue(double.IsPositiveInfinity(newSpecials[0]));
1140      Assert.IsTrue(double.IsNegativeInfinity(newSpecials[1]));
1141      Assert.IsTrue(double.IsNaN(newSpecials[2]));
1142    }
1143
1144    [TestMethod]
1145    [TestCategory("Persistence")]
1146    [TestProperty("Time", "short")]
1147    public void TestStringSplit() {
1148      string s = "1.2;2.3;3.4;;;4.9";
1149      var l = s.EnumerateSplit(';').ToList();
1150      Assert.AreEqual("1.2", l[0]);
1151      Assert.AreEqual("2.3", l[1]);
1152      Assert.AreEqual("3.4", l[2]);
1153      Assert.AreEqual("4.9", l[3]);
1154    }
1155
1156    [TestMethod]
1157    [TestCategory("Persistence")]
1158    [TestProperty("Time", "medium")]
1159    public void TestCompactNumberArraySerializer() {
1160      System.Random r = new System.Random();
1161      double[] a = new double[CompactNumberArray2StringSerializer.SPLIT_THRESHOLD * 2 + 1];
1162      for (int i = 0; i < a.Length; i++)
1163        a[i] = r.Next(10);
1164      var config = ConfigurationService.Instance.GetDefaultConfig(new XmlFormat());
1165      config = new Configuration(config.Format,
1166        config.PrimitiveSerializers.Where(s => s.SourceType != typeof(double[])),
1167        config.CompositeSerializers);
1168      XmlGenerator.Serialize(a, tempFile, config);
1169      double[] newA = XmlParser.Deserialize<double[]>(tempFile);
1170      Assert.AreEqual(a.Length, newA.Length);
1171      for (int i = 0; i < a.Rank; i++) {
1172        Assert.AreEqual(a.GetLength(i), newA.GetLength(i));
1173        Assert.AreEqual(a.GetLowerBound(i), newA.GetLowerBound(i));
1174      }
1175      for (int i = 0; i < a.Length; i++) {
1176        Assert.AreEqual(a[i], newA[i]);
1177      }
1178    }
1179    private class IdentityComparer<T> : IEqualityComparer<T> {
1180
1181      public bool Equals(T x, T y) {
1182        return x.Equals(y);
1183      }
1184
1185      public int GetHashCode(T obj) {
1186        return obj.GetHashCode();
1187      }
1188    }
1189
1190    [TestMethod]
1191    [TestCategory("Persistence")]
1192    [TestProperty("Time", "short")]
1193    public void TestHashSetSerializer() {
1194      var hashSets = new List<HashSet<int>>() {
1195        new HashSet<int>(new[] { 1, 2, 3 }),
1196        new HashSet<int>(new[] { 4, 5, 6 }, new IdentityComparer<int>()),
1197      };
1198      XmlGenerator.Serialize(hashSets, tempFile);
1199      var newHashSets = XmlParser.Deserialize<List<HashSet<int>>>(tempFile);
1200      Assert.IsTrue(newHashSets[0].Contains(1));
1201      Assert.IsTrue(newHashSets[0].Contains(2));
1202      Assert.IsTrue(newHashSets[0].Contains(3));
1203      Assert.IsTrue(newHashSets[1].Contains(4));
1204      Assert.IsTrue(newHashSets[1].Contains(5));
1205      Assert.IsTrue(newHashSets[1].Contains(6));
1206      Assert.AreEqual(newHashSets[0].Comparer.GetType(), new HashSet<int>().Comparer.GetType());
1207      Assert.AreEqual(newHashSets[1].Comparer.GetType(), typeof(IdentityComparer<int>));
1208    }
1209
1210    [TestMethod]
1211    [TestCategory("Persistence")]
1212    [TestProperty("Time", "short")]
1213    public void TestConcreteDictionarySerializer() {
1214      var dictionaries = new List<Dictionary<int, int>>() {
1215        new Dictionary<int, int>(),
1216        new Dictionary<int, int>(new IdentityComparer<int>()),
1217      };
1218      dictionaries[0].Add(1, 1);
1219      dictionaries[0].Add(2, 2);
1220      dictionaries[0].Add(3, 3);
1221      dictionaries[1].Add(4, 4);
1222      dictionaries[1].Add(5, 5);
1223      dictionaries[1].Add(6, 6);
1224      XmlGenerator.Serialize(dictionaries, tempFile, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
1225      var newDictionaries = XmlParser.Deserialize<List<Dictionary<int, int>>>(tempFile);
1226      Assert.IsTrue(newDictionaries[0].ContainsKey(1));
1227      Assert.IsTrue(newDictionaries[0].ContainsKey(2));
1228      Assert.IsTrue(newDictionaries[0].ContainsKey(3));
1229      Assert.IsTrue(newDictionaries[1].ContainsKey(4));
1230      Assert.IsTrue(newDictionaries[1].ContainsKey(5));
1231      Assert.IsTrue(newDictionaries[1].ContainsKey(6));
1232      Assert.IsTrue(newDictionaries[0].ContainsValue(1));
1233      Assert.IsTrue(newDictionaries[0].ContainsValue(2));
1234      Assert.IsTrue(newDictionaries[0].ContainsValue(3));
1235      Assert.IsTrue(newDictionaries[1].ContainsValue(4));
1236      Assert.IsTrue(newDictionaries[1].ContainsValue(5));
1237      Assert.IsTrue(newDictionaries[1].ContainsValue(6));
1238      Assert.AreEqual(new Dictionary<int, int>().Comparer.GetType(), newDictionaries[0].Comparer.GetType());
1239      Assert.AreEqual(typeof(IdentityComparer<int>), newDictionaries[1].Comparer.GetType());
1240    }
1241
1242    [StorableClass]
1243    public class ReadOnlyFail {
1244      [Storable]
1245      public string ReadOnly {
1246        get { return "fail"; }
1247      }
1248    }
1249
1250    [TestMethod]
1251    [TestCategory("Persistence")]
1252    [TestProperty("Time", "short")]
1253    public void TestReadOnlyFail() {
1254      try {
1255        XmlGenerator.Serialize(new ReadOnlyFail(), tempFile);
1256        Assert.Fail("Exception expected");
1257      } catch (PersistenceException) {
1258      } catch {
1259        Assert.Fail("PersistenceException expected");
1260      }
1261    }
1262
1263
1264    [StorableClass]
1265    public class WriteOnlyFail {
1266      [Storable]
1267      public string WriteOnly {
1268        set { throw new InvalidOperationException("this property should never be set."); }
1269      }
1270    }
1271
1272    [TestMethod]
1273    [TestCategory("Persistence")]
1274    [TestProperty("Time", "short")]
1275    public void TestWriteOnlyFail() {
1276      try {
1277        XmlGenerator.Serialize(new WriteOnlyFail(), tempFile);
1278        Assert.Fail("Exception expected");
1279      } catch (PersistenceException) {
1280      } catch {
1281        Assert.Fail("PersistenceException expected.");
1282      }
1283    }
1284
1285    [StorableClass]
1286    public class OneWayTest {
1287      public OneWayTest() { this.value = "default"; }
1288      public string value;
1289      [Storable(AllowOneWay = true)]
1290      public string ReadOnly {
1291        get { return "ReadOnly"; }
1292      }
1293      [Storable(AllowOneWay = true)]
1294      public string WriteOnly {
1295        set { this.value = value; }
1296      }
1297    }
1298
1299    [TestMethod]
1300    [TestCategory("Persistence")]
1301    [TestProperty("Time", "short")]
1302    public void TestOneWaySerialization() {
1303      var test = new OneWayTest();
1304      var serializer = new Serializer(test, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
1305      var it = serializer.GetEnumerator();
1306      it.MoveNext();
1307      Assert.AreEqual("ROOT", ((BeginToken)it.Current).Name); it.MoveNext();
1308      Assert.AreEqual("ReadOnly", ((PrimitiveToken)it.Current).Name); it.MoveNext();
1309      Assert.AreEqual("ROOT", ((EndToken)it.Current).Name); it.MoveNext();
1310      var deserializer = new Deserializer(new[] { 
1311        new TypeMapping(0, typeof(OneWayTest).AssemblyQualifiedName, typeof(StorableSerializer).AssemblyQualifiedName),
1312        new TypeMapping(1, typeof(string).AssemblyQualifiedName, typeof(String2XmlSerializer).AssemblyQualifiedName) });
1313      var newTest = (OneWayTest)deserializer.Deserialize(new ISerializationToken[] {
1314        new BeginToken("ROOT", 0, 0),
1315        new PrimitiveToken("WriteOnly", 1, 1, new XmlString("<![CDATA[serial data]]>")),
1316        new EndToken("ROOT", 0, 0)
1317      });
1318      Assert.AreEqual("serial data", newTest.value);
1319    }
1320
1321    [TestMethod]
1322    [TestCategory("Persistence")]
1323    [TestProperty("Time", "short")]
1324    public void TestTypeCacheExport() {
1325      var test = new List<List<int>>();
1326      test.Add(new List<int>() { 1, 2, 3 });
1327      IEnumerable<Type> types;
1328      using (var stream = new MemoryStream()) {
1329        XmlGenerator.Serialize(test, stream, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, out types);
1330      }
1331      List<Type> t = new List<Type>(types);
1332      // Assert.IsTrue(t.Contains(typeof(int))); not serialized as an int list is directly transformed into a string
1333      Assert.IsTrue(t.Contains(typeof(List<int>)));
1334      Assert.IsTrue(t.Contains(typeof(List<List<int>>)));
1335      Assert.AreEqual(t.Count, 2);
1336    }
1337
1338    [TestMethod]
1339    [TestCategory("Persistence")]
1340    [TestProperty("Time", "short")]
1341    public void TupleTest() {
1342      var t1 = Tuple.Create(1);
1343      var t2 = Tuple.Create('1', "2");
1344      var t3 = Tuple.Create(3.0, 3f, 5);
1345      var t4 = Tuple.Create(Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6), Tuple.Create(8, 9, 10));
1346      var tuple = Tuple.Create(t1, t2, t3, t4);
1347      XmlGenerator.Serialize(tuple, tempFile);
1348      var newTuple = XmlParser.Deserialize<Tuple<Tuple<int>, Tuple<char, string>, Tuple<double, float, int>, Tuple<Tuple<int, int, int>, Tuple<int, int, int>, Tuple<int, int, int>>>>(tempFile);
1349      Assert.AreEqual(tuple, newTuple);
1350    }
1351
1352    [TestMethod]
1353    [TestCategory("Persistence")]
1354    [TestProperty("Time", "short")]
1355    public void FontTest() {
1356      List<Font> fonts = new List<Font>() {
1357        new Font(FontFamily.GenericSansSerif, 12),
1358        new Font("Times New Roman", 21, FontStyle.Bold, GraphicsUnit.Pixel),
1359        new Font("Courier New", 10, FontStyle.Underline, GraphicsUnit.Document),
1360        new Font("Helvetica", 21, FontStyle.Strikeout, GraphicsUnit.Inch, 0, true),
1361      };
1362      XmlGenerator.Serialize(fonts, tempFile);
1363      var newFonts = XmlParser.Deserialize<List<Font>>(tempFile);
1364      Assert.AreEqual(fonts[0], newFonts[0]);
1365      Assert.AreEqual(fonts[1], newFonts[1]);
1366      Assert.AreEqual(fonts[2], newFonts[2]);
1367      Assert.AreEqual(fonts[3], newFonts[3]);
1368    }
1369
1370    [TestMethod]
1371    [TestCategory("Persistence")]
1372    [TestProperty("Time", "medium")]
1373    public void ConcurrencyTest() {
1374      int n = 20;
1375      Task[] tasks = new Task[n];
1376      for (int i = 0; i < n; i++) {
1377        tasks[i] = Task.Factory.StartNew((idx) => {
1378          byte[] data;
1379          using (var stream = new MemoryStream()) {
1380            XmlGenerator.Serialize(new GeneticAlgorithm(), stream);
1381            data = stream.ToArray();
1382          }
1383        }, i);
1384      }
1385      Task.WaitAll(tasks);
1386    }
1387
1388    [TestMethod]
1389    [TestCategory("Persistence")]
1390    [TestProperty("Time", "medium")]
1391    public void ConcurrentBitmapTest() {
1392      Bitmap b = new Bitmap(300, 300);
1393      System.Random r = new System.Random();
1394      for (int x = 0; x < b.Height; x++) {
1395        for (int y = 0; y < b.Width; y++) {
1396          b.SetPixel(x, y, Color.FromArgb(r.Next()));
1397        }
1398      }
1399      Task[] tasks = new Task[20];
1400      byte[][] datas = new byte[tasks.Length][];
1401      for (int i = 0; i < tasks.Length; i++) {
1402        tasks[i] = Task.Factory.StartNew((idx) => {
1403          using (var stream = new MemoryStream()) {
1404            XmlGenerator.Serialize(b, stream);
1405            datas[(int)idx] = stream.ToArray();
1406          }
1407        }, i);
1408      }
1409      Task.WaitAll(tasks);
1410    }
1411
1412    public class G<T, T2> {
1413      public class S { }
1414      public class S2<T3, T4> { }
1415    }
1416
1417    [TestMethod]
1418    [TestCategory("Persistence")]
1419    [TestProperty("Time", "short")]
1420    public void TestInternalClassOfGeneric() {
1421      var s = new G<int, char>.S();
1422      var typeName = s.GetType().AssemblyQualifiedName;
1423      Assert.AreEqual(
1424        "UseCases.G<Int32,Char>.S",
1425        TypeNameParser.Parse(typeName).GetTypeNameInCode(false));
1426      XmlGenerator.Serialize(s, tempFile);
1427      var s1 = XmlParser.Deserialize(tempFile);
1428    }
1429
1430    [TestMethod]
1431    [TestCategory("Persistence")]
1432    [TestProperty("Time", "short")]
1433    public void TestInternalClassOfGeneric2() {
1434      var s = new G<int, float>.S2<int, char>();
1435      var typeName = s.GetType().AssemblyQualifiedName;
1436      Assert.AreEqual(
1437        "UseCases.G<Int32,Single>.S2<Int32,Char>",
1438        TypeNameParser.Parse(typeName).GetTypeNameInCode(false));
1439      XmlGenerator.Serialize(s, tempFile);
1440      var s1 = XmlParser.Deserialize(tempFile);
1441    }
1442
1443    [TestMethod]
1444    [TestCategory("Persistence")]
1445    [TestProperty("Time", "short")]
1446    public void TestSpecialCharacters() {
1447      var s = "abc" + "\x15" + "def";
1448      XmlGenerator.Serialize(s, tempFile);
1449      var newS = XmlParser.Deserialize(tempFile);
1450      Assert.AreEqual(s, newS);
1451    }
1452
1453    [TestMethod]
1454    [TestCategory("Persistence")]
1455    [TestProperty("Time", "short")]
1456    public void TestByteArray() {
1457      var b = new byte[3];
1458      b[0] = 0;
1459      b[1] = 200;
1460      b[2] = byte.MaxValue;
1461      XmlGenerator.Serialize(b, tempFile);
1462      var newB = (byte[]) XmlParser.Deserialize(tempFile);
1463      CollectionAssert.AreEqual(b, newB);
1464    }
1465
1466    [TestMethod]
1467    [TestCategory("Persistence")]
1468    [TestProperty("Time", "short")]
1469    public void TestOptionalNumberEnumerable() {
1470      var values = new List<double?> {0, null, double.NaN, double.PositiveInfinity, double.MaxValue, 1};
1471      XmlGenerator.Serialize(values, tempFile);
1472      var newValues = (List<double?>) XmlParser.Deserialize(tempFile);
1473      CollectionAssert.AreEqual(values, newValues);
1474    }
1475
1476
1477    [ClassInitialize]
1478    public static void Initialize(TestContext testContext) {
1479      ConfigurationService.Instance.Reset();
1480    }
1481  }
1482}
Note: See TracBrowser for help on using the repository browser.