Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/UnitTests/UseCases.cs @ 2728

Last change on this file since 2728 was 2106, checked in by epitzer, 15 years ago

Collect all exceptions during serialization and continue as far as possible. Throw a collected exception in th end. (#678)

File size: 19.5 KB
Line 
1using System;
2using System.Text;
3using System.Collections.Generic;
4using System.Linq;
5using Microsoft.VisualStudio.TestTools.UnitTesting;
6using HeuristicLab.Persistence.Core;
7using System.Collections;
8using HeuristicLab.Persistence.Default.Xml;
9using HeuristicLab.Persistence.Default.DebugString;
10using System.IO;
11using System.Reflection;
12using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
13using HeuristicLab.Persistence.Interfaces;
14using HeuristicLab.Persistence.Default.Xml.Primitive;
15using HeuristicLab.Persistence.Default.CompositeSerializers;
16using HeuristicLab.Persistence.Auxiliary;
17using System.Text.RegularExpressions;
18using HeuristicLab.Persistence.Test;
19
20namespace HeuristicLab.Persistence.UnitTest {
21
22  public class NumberTest {
23    [Storable]
24    private bool _bool = true;
25    [Storable]
26    private byte _byte = 0xFF;
27    [Storable]
28    private sbyte _sbyte = 0xF;
29    [Storable]
30    private short _short = -123;
31    [Storable]
32    private ushort _ushort = 123;
33    [Storable]
34    private int _int = -123;
35    [Storable]
36    private uint _uint = 123;
37    [Storable]
38    private long _long = 123456;
39    [Storable]
40    private ulong _ulong = 123456;
41  }
42
43  public class NonDefaultConstructorClass {
44    [Storable]
45    int value;
46    public NonDefaultConstructorClass(int value) {
47      this.value = value;
48    }
49  }
50
51  public class IntWrapper {
52
53    [Storable]
54    public int Value;
55
56    private IntWrapper() { }
57
58    public IntWrapper(int value) {
59      this.Value = value;
60    }
61
62    public override bool Equals(object obj) {
63      if (obj as IntWrapper == null)
64        return false;
65      return Value.Equals(((IntWrapper)obj).Value);
66    }
67    public override int GetHashCode() {
68      return Value.GetHashCode();
69    }
70
71  }
72
73  public class PrimitivesTest : NumberTest {
74    [Storable]
75    private char c = 'e';
76    [Storable]
77    private long[,] _long_array =
78      new long[,] { { 123, 456, }, { 789, 123 } };
79    [Storable]
80    public List<int> list = new List<int> { 1, 2, 3, 4, 5 };
81    [Storable]
82    private object o = new object();
83  }
84
85  public enum TestEnum { va1, va2, va3, va8 } ;
86
87  public class RootBase {
88    [Storable]
89    private string baseString = "   Serial  ";
90    [Storable]
91    public TestEnum myEnum = TestEnum.va3;
92  }
93
94  public class Root : RootBase {
95    [Storable]
96    public Stack<int> intStack = new Stack<int>();
97    [Storable]
98    public int[] i = new[] { 3, 4, 5, 6 };
99    [Storable(Name = "Test String")]
100    public string s;
101    [Storable]
102    public ArrayList intArray = new ArrayList(new[] { 1, 2, 3 });
103    [Storable]
104    public List<int> intList = new List<int>(new[] { 321, 312, 321 });
105    [Storable]
106    public Custom c;
107    [Storable]
108    public List<Root> selfReferences;
109    [Storable]
110    public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } };
111    [Storable]
112    public bool boolean = true;
113    [Storable]
114    public DateTime dateTime;
115    [Storable]
116    public KeyValuePair<string, int> kvp = new KeyValuePair<string, int>("Serial", 123);
117    [Storable]
118    public Dictionary<string, int> dict = new Dictionary<string, int>();
119    [Storable(DefaultValue = "default")]
120    public string uninitialized;
121  }
122
123  public enum SimpleEnum { one, two, three }
124  public enum ComplexEnum { one = 1, two = 2, three = 3 }
125  [FlagsAttribute]
126  public enum TrickyEnum { zero = 0, one = 1, two = 2 }
127
128  public class EnumTest {
129    [Storable]
130    public SimpleEnum simpleEnum = SimpleEnum.one;
131    [Storable]
132    public ComplexEnum complexEnum = (ComplexEnum)2;
133    [Storable]
134    public TrickyEnum trickyEnum = (TrickyEnum)15;
135  }
136
137  public class Custom {
138    [Storable]
139    public int i;
140    [Storable]
141    public Root r;
142    [Storable]
143    public string name = "<![CDATA[<![CDATA[Serial]]>]]>";
144  }
145
146  public class Manager {
147
148    public DateTime lastLoadTime;
149    [Storable]
150    private DateTime lastLoadTimePersistence {
151      get { return lastLoadTime; }
152      set { lastLoadTime = DateTime.Now; }
153    }
154    [Storable]
155    public double? dbl;
156  }
157
158  public class C {
159    [Storable]
160    public C[][] allCs;
161    [Storable]
162    public KeyValuePair<List<C>, C> kvpList;
163  }
164
165  public class NonSerializable {
166    int x;
167  }
168
169
170  [TestClass]
171  public class UseCases {
172
173    private string tempFile;
174
175    [TestInitialize()]
176    public void CreateTempFile() {
177      tempFile = Path.GetTempFileName();
178    }
179
180    [TestCleanup()]
181    public void ClearTempFile() {
182      StreamReader reader = new StreamReader(tempFile);
183      string s = reader.ReadToEnd();
184      reader.Close();
185      File.Delete(tempFile);
186    }
187
188    [TestMethod]
189    public void ComplexStorable() {
190      Root r = new Root();
191      r.intStack.Push(1);
192      r.intStack.Push(2);
193      r.intStack.Push(3);
194      r.selfReferences = new List<Root> { r, r };
195      r.c = new Custom { r = r };
196      r.dict.Add("one", 1);
197      r.dict.Add("two", 2);
198      r.dict.Add("three", 3);
199      r.myEnum = TestEnum.va1;
200      r.i = new[] { 7, 5, 6 };
201      r.s = "new value";
202      r.intArray = new ArrayList { 3, 2, 1 };
203      r.intList = new List<int> { 9, 8, 7 };
204      r.multiDimArray = new double[,] { { 5, 4, 3 }, { 1, 4, 6 } };
205      r.boolean = false;
206      r.dateTime = DateTime.Now;
207      r.kvp = new KeyValuePair<string, int>("string key", 321);
208      r.uninitialized = null;
209      XmlGenerator.Serialize(r, tempFile);
210      Root newR = (Root)XmlParser.Deserialize(tempFile);
211      Assert.AreEqual(
212        DebugStringGenerator.Serialize(r),
213        DebugStringGenerator.Serialize(newR));
214      Assert.AreSame(newR, newR.selfReferences[0]);
215      Assert.AreNotSame(r, newR);
216      Assert.AreEqual(r.myEnum, TestEnum.va1);
217      Assert.AreEqual(r.i[0], 7);
218      Assert.AreEqual(r.i[1], 5);
219      Assert.AreEqual(r.i[2], 6);
220      Assert.AreEqual(r.s, "new value");
221      Assert.AreEqual(r.intArray[0], 3);
222      Assert.AreEqual(r.intArray[1], 2);
223      Assert.AreEqual(r.intArray[2], 1);
224      Assert.AreEqual(r.intList[0], 9);
225      Assert.AreEqual(r.intList[1], 8);
226      Assert.AreEqual(r.intList[2], 7);
227      Assert.AreEqual(r.multiDimArray[0, 0], 5);
228      Assert.AreEqual(r.multiDimArray[0, 1], 4);
229      Assert.AreEqual(r.multiDimArray[0, 2], 3);
230      Assert.AreEqual(r.multiDimArray[1, 0], 1);
231      Assert.AreEqual(r.multiDimArray[1, 1], 4);
232      Assert.AreEqual(r.multiDimArray[1, 2], 6);
233      Assert.IsFalse(r.boolean);
234      Assert.IsTrue((DateTime.Now - r.dateTime).TotalSeconds < 10);
235      Assert.AreEqual(r.kvp.Key, "string key");
236      Assert.AreEqual(r.kvp.Value, 321);
237      Assert.IsNull(r.uninitialized);
238      Assert.AreEqual(newR.myEnum, TestEnum.va1);
239      Assert.AreEqual(newR.i[0], 7);
240      Assert.AreEqual(newR.i[1], 5);
241      Assert.AreEqual(newR.i[2], 6);
242      Assert.AreEqual(newR.s, "new value");
243      Assert.AreEqual(newR.intArray[0], 3);
244      Assert.AreEqual(newR.intArray[1], 2);
245      Assert.AreEqual(newR.intArray[2], 1);
246      Assert.AreEqual(newR.intList[0], 9);
247      Assert.AreEqual(newR.intList[1], 8);
248      Assert.AreEqual(newR.intList[2], 7);
249      Assert.AreEqual(newR.multiDimArray[0, 0], 5);
250      Assert.AreEqual(newR.multiDimArray[0, 1], 4);
251      Assert.AreEqual(newR.multiDimArray[0, 2], 3);
252      Assert.AreEqual(newR.multiDimArray[1, 0], 1);
253      Assert.AreEqual(newR.multiDimArray[1, 1], 4);
254      Assert.AreEqual(newR.multiDimArray[1, 2], 6);
255      Assert.AreEqual(newR.intStack.Pop(), 3);
256      Assert.AreEqual(newR.intStack.Pop(), 2);
257      Assert.AreEqual(newR.intStack.Pop(), 1);
258      Assert.IsFalse(newR.boolean);
259      Assert.IsTrue((DateTime.Now - newR.dateTime).TotalSeconds < 10);
260      Assert.AreEqual(newR.kvp.Key, "string key");
261      Assert.AreEqual(newR.kvp.Value, 321);
262      Assert.IsNull(newR.uninitialized);
263    }
264
265    [TestMethod]
266    public void SelfReferences() {
267      C c = new C();
268      C[][] cs = new C[2][];
269      cs[0] = new C[] { c };
270      cs[1] = new C[] { c };
271      c.allCs = cs;
272      c.kvpList = new KeyValuePair<List<C>, C>(new List<C> { c }, c);
273      XmlGenerator.Serialize(cs, tempFile);
274      object o = XmlParser.Deserialize(tempFile);
275      Assert.AreEqual(
276        DebugStringGenerator.Serialize(cs),
277        DebugStringGenerator.Serialize(o));
278      Assert.AreSame(c, c.allCs[0][0]);
279      Assert.AreSame(c, c.allCs[1][0]);
280      Assert.AreSame(c, c.kvpList.Key[0]);
281      Assert.AreSame(c, c.kvpList.Value);
282      C[][] newCs = (C[][])o;
283      C newC = newCs[0][0];
284      Assert.AreSame(newC, newC.allCs[0][0]);
285      Assert.AreSame(newC, newC.allCs[1][0]);
286      Assert.AreSame(newC, newC.kvpList.Key[0]);
287      Assert.AreSame(newC, newC.kvpList.Value);
288    }
289
290    [TestMethod]
291    public void ArrayCreation() {
292      ArrayList[] arrayListArray = new ArrayList[4];
293      arrayListArray[0] = new ArrayList();
294      arrayListArray[0].Add(arrayListArray);
295      arrayListArray[0].Add(arrayListArray);
296      arrayListArray[1] = new ArrayList();
297      arrayListArray[1].Add(arrayListArray);
298      arrayListArray[2] = new ArrayList();
299      arrayListArray[2].Add(arrayListArray);
300      arrayListArray[2].Add(arrayListArray);
301      Array a = Array.CreateInstance(
302                              typeof(object),
303                              new[] { 1, 2 }, new[] { 3, 4 });
304      arrayListArray[2].Add(a);
305      XmlGenerator.Serialize(arrayListArray, tempFile);
306      object o = XmlParser.Deserialize(tempFile);
307      Assert.AreEqual(
308        DebugStringGenerator.Serialize(arrayListArray),
309        DebugStringGenerator.Serialize(o));
310      ArrayList[] newArray = (ArrayList[])o;
311      Assert.AreSame(arrayListArray, arrayListArray[0][0]);
312      Assert.AreSame(arrayListArray, arrayListArray[2][1]);
313      Assert.AreSame(newArray, newArray[0][0]);
314      Assert.AreSame(newArray, newArray[2][1]);
315    }
316
317    [TestMethod]
318    public void CustomSerializationProperty() {
319      Manager m = new Manager();
320      XmlGenerator.Serialize(m, tempFile);
321      Manager newM = (Manager)XmlParser.Deserialize(tempFile);
322      Assert.AreNotEqual(
323        DebugStringGenerator.Serialize(m),
324        DebugStringGenerator.Serialize(newM));
325      Assert.AreEqual(m.dbl, newM.dbl);
326      Assert.AreEqual(m.lastLoadTime, new DateTime());
327      Assert.AreNotEqual(newM.lastLoadTime, new DateTime());
328      Assert.IsTrue((DateTime.Now - newM.lastLoadTime).TotalSeconds < 10);
329    }
330
331    [TestMethod]
332    public void Primitives() {
333      PrimitivesTest sdt = new PrimitivesTest();
334      XmlGenerator.Serialize(sdt, tempFile);
335      object o = XmlParser.Deserialize(tempFile);
336      Assert.AreEqual(
337        DebugStringGenerator.Serialize(sdt),
338        DebugStringGenerator.Serialize(o));
339    }
340
341    [TestMethod]
342    public void MultiDimensionalArray() {
343      string[,] mDimString = new string[,] {
344        {"ora", "et", "labora"},
345        {"Beten", "und", "Arbeiten"}
346      };
347      XmlGenerator.Serialize(mDimString, tempFile);
348      object o = XmlParser.Deserialize(tempFile);
349      Assert.AreEqual(
350        DebugStringGenerator.Serialize(mDimString),
351        DebugStringGenerator.Serialize(o));
352    }
353
354    public class NestedType {
355      [Storable]
356      private string value = "value";
357    }
358
359    [TestMethod]
360    public void NestedTypeTest() {
361      NestedType t = new NestedType();
362      XmlGenerator.Serialize(t, tempFile);
363      object o = XmlParser.Deserialize(tempFile);
364      Assert.AreEqual(
365        DebugStringGenerator.Serialize(t),
366        DebugStringGenerator.Serialize(o));
367    }
368
369
370    [TestMethod]
371    public void SimpleArray() {
372      string[] strings = { "ora", "et", "labora" };
373      XmlGenerator.Serialize(strings, tempFile);
374      object o = XmlParser.Deserialize(tempFile);
375      Assert.AreEqual(
376        DebugStringGenerator.Serialize(strings),
377        DebugStringGenerator.Serialize(o));
378    }
379
380    [TestMethod]
381    public void PrimitiveRoot() {
382      XmlGenerator.Serialize(12.3f, tempFile);
383      object o = XmlParser.Deserialize(tempFile);
384      Assert.AreEqual(
385        DebugStringGenerator.Serialize(12.3f),
386        DebugStringGenerator.Serialize(o));
387    }
388
389    private string formatFullMemberName(MemberInfo mi) {
390      return new StringBuilder()
391        .Append(mi.DeclaringType.Assembly.GetName().Name)
392        .Append(": ")
393        .Append(mi.DeclaringType.Namespace)
394        .Append('.')
395        .Append(mi.DeclaringType.Name)
396        .Append('.')
397        .Append(mi.Name).ToString();
398    }
399
400    [TestMethod]
401    public void CodingConventions() {
402      List<string> lowerCaseMethodNames = new List<string>();
403      List<string> lowerCaseProperties = new List<string>();
404      List<string> lowerCaseFields = new List<string>();
405      foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
406        if (!a.GetName().Name.StartsWith("HeuristicLab"))
407          continue;
408        foreach (Type t in a.GetTypes()) {
409          foreach (MemberInfo mi in t.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) {
410            if (char.IsLower(mi.Name[0])) {
411              if (mi.MemberType == MemberTypes.Field)
412                lowerCaseFields.Add(formatFullMemberName(mi));
413              if (mi.MemberType == MemberTypes.Property)
414                lowerCaseProperties.Add(formatFullMemberName(mi));
415              if (mi.MemberType == MemberTypes.Method &&
416                !mi.Name.StartsWith("get_") &&
417                !mi.Name.StartsWith("set_") &&
418                !mi.Name.StartsWith("add_") &&
419                !mi.Name.StartsWith("remove_"))
420                lowerCaseMethodNames.Add(formatFullMemberName(mi));
421            }
422          }
423        }
424      }
425      //Assert.AreEqual("", lowerCaseFields.Aggregate("", (a, b) => a + "\r\n" + b));
426      Assert.AreEqual("", lowerCaseMethodNames.Aggregate("", (a, b) => a + "\r\n" + b));
427      Assert.AreEqual("", lowerCaseProperties.Aggregate("", (a, b) => a + "\r\n" + b));
428    }
429
430    [TestMethod]
431    public void Number2StringDecomposer() {
432      NumberTest sdt = new NumberTest();
433      XmlGenerator.Serialize(sdt, tempFile,
434        new Configuration(new XmlFormat(),
435          new List<IPrimitiveSerializer> { new String2XmlSerializer() },
436          new List<ICompositeSerializer> {
437            new StorableSerializer(),
438            new Number2StringSerializer() }));
439      object o = XmlParser.Deserialize(tempFile);
440      Assert.AreEqual(
441        DebugStringGenerator.Serialize(sdt),
442        DebugStringGenerator.Serialize(o));
443    }
444
445    [TestMethod]
446    public void Enums() {
447      EnumTest et = new EnumTest();
448      et.simpleEnum = SimpleEnum.two;
449      et.complexEnum = ComplexEnum.three;
450      et.trickyEnum = TrickyEnum.two | TrickyEnum.one;
451      XmlGenerator.Serialize(et, tempFile);
452      EnumTest newEt = (EnumTest)XmlParser.Deserialize(tempFile);
453      Assert.AreEqual(et.simpleEnum, SimpleEnum.two);
454      Assert.AreEqual(et.complexEnum, ComplexEnum.three);
455      Assert.AreEqual(et.trickyEnum, (TrickyEnum)3);
456    }
457
458    [TestMethod]
459    public void TestAliasingWithOverriddenEquals() {
460      List<IntWrapper> ints = new List<IntWrapper>();
461      ints.Add(new IntWrapper(1));
462      ints.Add(new IntWrapper(1));
463      Assert.AreEqual(ints[0], ints[1]);
464      Assert.AreNotSame(ints[0], ints[1]);
465      XmlGenerator.Serialize(ints, tempFile);
466      List<IntWrapper> newInts = (List<IntWrapper>)XmlParser.Deserialize(tempFile);
467      Assert.AreEqual(newInts[0].Value, 1);
468      Assert.AreEqual(newInts[1].Value, 1);
469      Assert.AreEqual(newInts[0], newInts[1]);
470      Assert.AreNotSame(newInts[0], newInts[1]);
471    }
472
473    [TestMethod]
474    public void NonDefaultConstructorTest() {
475      NonDefaultConstructorClass c = new NonDefaultConstructorClass(1);
476      try {
477        XmlGenerator.Serialize(c, tempFile);
478        Assert.Fail("Exception not thrown");
479      } catch (PersistenceException) {
480      }
481    }
482
483    [TestMethod]
484    public void TestSavingException() {
485      List<int> list = new List<int> { 1, 2, 3 };
486      XmlGenerator.Serialize(list, tempFile);
487      NonSerializable s = new NonSerializable();
488      try {
489        XmlGenerator.Serialize(s, tempFile);
490        Assert.Fail("Exception expected");
491      } catch (PersistenceException) { }
492      List<int> newList = (List<int>)XmlParser.Deserialize(tempFile);
493      Assert.AreEqual(list[0], newList[0]);
494      Assert.AreEqual(list[1], newList[1]);
495    }
496
497    [TestMethod]
498    public void TestTypeStringConversion() {
499      string name = typeof(List<int>[]).AssemblyQualifiedName;
500      string shortName =
501        "System.Collections.Generic.List`1[[System.Int32, mscorlib]][], mscorlib";
502      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
503      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
504      Assert.AreEqual(shortName, typeof(List<int>[]).VersionInvariantName());
505    }
506
507    [TestMethod]
508    public void TestMultipleFailure() {
509      List<NonSerializable> l = new List<NonSerializable>();
510      l.Add(new NonSerializable());
511      l.Add(new NonSerializable());
512      l.Add(new NonSerializable());
513      try {
514        Serializer s = new Serializer(l,
515          ConfigurationService.Instance.GetConfiguration(new XmlFormat()),
516          "ROOT", true);
517        StringBuilder tokens = new StringBuilder();
518        foreach (var token in s) {
519          tokens.Append(token.ToString());
520        }
521        Assert.Fail("Exception expected");
522      } catch (PersistenceException px) {
523        Assert.AreEqual(3, px.Data.Count);
524      }
525    }
526
527    [TestMethod]
528    public void TestAssemblyVersionCheck() {
529      IntWrapper i = new IntWrapper(1);
530      Serializer s = new Serializer(i, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
531      XmlGenerator g = new XmlGenerator();
532      StringBuilder dataString = new StringBuilder();
533      foreach (var token in s) {
534        dataString.Append(g.Format(token));
535      }
536      StringBuilder typeString = new StringBuilder();
537      foreach (var line in g.Format(s.TypeCache))
538        typeString.Append(line);
539      Deserializer d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(typeString.ToString())));
540      XmlParser p = new XmlParser(new StringReader(dataString.ToString()));
541      IntWrapper newI = (IntWrapper)d.Deserialize(p);
542      Assert.AreEqual(i.Value, newI.Value);
543
544      string newTypeString = Regex.Replace(typeString.ToString(),
545        "Version=\\d+\\.\\d+\\.\\d+\\.\\d+",
546        "Version=0.0.9999.9999");
547      try {
548        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
549        Assert.Fail("Exception expected");
550      } catch (PersistenceException x) {
551        Assert.IsTrue(x.Message.Contains("incompatible"));
552      }
553      newTypeString = Regex.Replace(typeString.ToString(),
554        "Version=(\\d+\\.\\d+)\\.\\d+\\.\\d+",
555        "Version=$1.9999.9999");
556      try {
557        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
558        Assert.Fail("Exception expected");
559      } catch (PersistenceException x) {
560        Assert.IsTrue(x.Message.Contains("newer"));
561      }
562    }
563
564    [TestMethod]
565    public void InheritanceTest() {
566      New n = new New();
567      XmlGenerator.Serialize(n, tempFile);
568      New nn = (New)XmlParser.Deserialize(tempFile);
569      Assert.AreEqual(n.Name, nn.Name);
570      Assert.AreEqual(((Override)n).Name, ((Override)nn).Name);
571    }
572
573    [ClassInitialize]
574    public static void Initialize(TestContext testContext) {
575      ConfigurationService.Instance.Reset();
576    }
577  }
578}
Note: See TracBrowser for help on using the repository browser.