context: // --------------------------------------------------------------------------------------------------------------------
  // <copyright file="SerializationTest.cs" company="Allors bvba">
  //   Copyright 2002-2012 Allors bvba.
  // Dual Licensed under
  //   a) the Lesser General Public Licence v3 (LGPL)
  //   b) the Allors License
  // The LGPL License is included in the file lgpl.txt.
  // The Allors License is an addendum to your contract.
  // Allors Platform is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  // For more information visit http://www.allors.com/legal
  // </copyright>
  // --------------------------------------------------------------------------------------------------------------------
  
  namespace Allors.Adapters
  {
      using System;
      using System.Globalization;
      using System.IO;
      using System.Xml;
  
      using Allors;
      using Allors.Domain;
      using Allors.Meta;
  
      using Xunit;
  
      public abstract class SerializationTest : IDisposable
      {
          protected static readonly bool[] TrueFalse = { true, false };
          private static readonly string GuidString = Guid.NewGuid().ToString();
  
          #region population
          private C1 c1A;
          private C1 c1B;
          private C1 c1C;
          private C1 c1D;
          private C1 c1Empty;
          private C2 c2A;
          private C2 c2B;
          private C2 c2C;
          private C2 c2D;
          private C3 c3A;
          private C3 c3B;
          private C3 c3C;
          private C3 c3D;
          private C4 c4A;
          private C4 c4B;
          private C4 c4C;
          private C4 c4D;
          #endregion
  
          protected virtual bool EmptyStringIsNull => false;
  
          protected abstract IProfile Profile { get; }
  
          protected IDatabase Population => this.Profile.Database;
  
          protected ISession Session => this.Profile.Session;
  
          protected Action[] Markers => this.Profile.Markers;
  
          protected Action[] Inits => this.Profile.Inits;
  
          public abstract void Dispose();
  
          [Fact]
          public void DifferentVersion()
          {
              foreach (var init in this.Inits)
              {
                  init();
  
                  var otherPopulation = this.CreatePopulation();
                  using (var otherSession = otherPopulation.CreateSession())
                  {
                      this.Populate(otherSession);
                      otherSession.Commit();
  
                      var stringWriter = new StringWriter();
                      using (var writer = XmlWriter.Create(stringWriter))
                      {
                          otherPopulation.Save(writer);
                      }
  
                      var xml = stringWriter.ToString();
                      var xmlDocument = new XmlDocument();
                      xmlDocument.LoadXml(xml);
                      var populationElement = (XmlElement)xmlDocument.SelectSingleNode("//population");
                      populationElement.SetAttribute("version", "0");
                      xml = xmlDocument.OuterXml;
  
                      try
                      {
                          using (var stringReader = new StringReader(xml))
                          {
                              using (var reader = XmlReader.Create(stringReader))
                              {
                                  this.Population.Load(reader);
                              }
                          }
  
                          Assert.True(false); // Fail
                      }
                      catch (ArgumentException)
                      {
                      }
  
                      populationElement.SetAttribute("version", "2");
                      xml = xmlDocument.OuterXml;
  
                      try
                      {
                          using (var stringReader = new StringReader(xml))
                          {
                              using (var reader = XmlReader.Create(stringReader))
                              {
                                  this.Population.Load(reader);
                              }
                          }
  
                          Assert.True(false); // Fail
                      }
                      catch (ArgumentException)
                      {
                      }
  
                      populationElement.SetAttribute("version", "a");
                      xml = xmlDocument.OuterXml;
  
                      var exception = false;
                      try
                      {
                          using (var stringReader = new StringReader(xml))
                          {
                              using (var reader = XmlReader.Create(stringReader))
                              {
                                  this.Population.Load(reader);
                              }
                          }
                      }
                      catch (Exception)
                      {
                          exception = true;
                      }
  
                      Assert.True(exception);
  
                      populationElement.SetAttribute("version", string.Empty);
                      xml = xmlDocument.OuterXml;
  
                      var exceptionThrown = false;
                      try
                      {
                          using (var stringReader = new StringReader(xml))
                          {
                              using (var reader = XmlReader.Create(stringReader))
                              {
                                  this.Population.Load(reader);
                              }
                          }
                      }
                      catch (ArgumentException)
                      {
                          exceptionThrown = true;
                      }
                      catch (InvalidOperationException)
                      {
                          exceptionThrown = true;
                      }
  
                      Assert.True(exceptionThrown);    
                  }
              }
          }
  
          [Fact]
          public void Load()
          {
              foreach (var indentation in TrueFalse)
              {
                  foreach (var init in this.Inits)
                  {
                      init();
  
                      var otherPopulation = this.CreatePopulation();
                      using (var otherSession = otherPopulation.CreateSession())
                      {
                          this.Populate(otherSession);
                          otherSession.Commit();
  
                          var stringWriter = new StringWriter();
                          var xmlWriterSettings = new XmlWriterSettings { Indent = indentation };
                          using (var writer = XmlWriter.Create(stringWriter, xmlWriterSettings))
                          {
                              otherPopulation.Save(writer);
                          }
  
                          var xml = stringWriter.ToString();
                          File.WriteAllText(@"c:\temp\population.xml", xml);
                          //Console.Out.WriteLine(xml);
  
                          var stringReader = new StringReader(xml);
                          using (var reader = XmlReader.Create(stringReader))
                          {
                              this.Population.Load(reader);
                          }
  
  
                          using (var session = this.Population.CreateSession())
                          {
                              var x = (C1)session.Instantiate(1);
                              var str = x.C1AllorsString;
  
                              this.AssertPopulation(session);
                          }
                      }
                  }
              }
          }
  
          [Fact]
          public void LoadVersions()
          {
              foreach (var init in this.Inits)
              {
                  init();
  
                  var otherPopulation = this.CreatePopulation();
                  using (var otherSession = otherPopulation.CreateSession())
                  {
                      // Initial
                      var otherC1 = otherSession.Create<C1>();
  
                      otherSession.Commit();
  
                      var initialObjectVersion = otherC1.Strategy.ObjectVersion;
  
                      var xml = DoSave(otherPopulation);
                      DoLoad(this.Population, xml);
  
                      using (var session = this.Population.CreateSession())
                      {
                          var c1 = session.Instantiate(otherC1.Id);
  
                          Assert.Equal(otherC1.Strategy.ObjectVersion, c1.Strategy.ObjectVersion);
                      }
                      
                      // Change
                      otherC1.C1AllorsString = "Changed";
  
                      otherSession.Commit();
  
                      var changedObjectVersion = otherC1.Strategy.ObjectVersion;
  
  
gt:                     xml = DoSave(otherPopulation);