Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCases.cs @ 17105

Last change on this file since 17105 was 17105, checked in by mkommend, 5 years ago

#2520: Merged 16584, 16585,16594,16595, 16625, 16658, 16659, 16672, 16707, 16729, 16792, 16796, 16797, 16799, 16819, 16906, 16907, 16908, 16933, 16945, 16992, 16994, 16995, 16996, 16997, 17014, 17015, 17017, 17020, 17021, 17022, 17023, 17024, 17029, 17086, 17087, 17088, 17089 into stable.

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.