Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCases.cs @ 17187

Last change on this file since 17187 was 16946, checked in by mkommend, 6 years ago

#2521: Merged trunk changes up to r16945 into branch.

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