// // System.Runtime.Serialization.SerializationCallbackTest.cs // // Author: Robert Jordan (robertj@gmx.net) // #if NET_2_0 using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using NUnit.Framework; namespace MonoTests.System.Runtime.Serialization { [TestFixture] public class SerializationCallbackTest { [Test] public void Test () { Log.Clear (); Driver (new BinaryFormatter (), new A (new B())); //Console.WriteLine (Log.Text); Assert.AreEqual (Log.Text, "A1B1A2B2A3B3B4A4"); } [Test] public void TestInheritance () { Log.Clear (); Driver (new BinaryFormatter (), new C (new B())); //Console.WriteLine (Log.Text); Assert.AreEqual (Log.Text, "A1C1B1A2C2B2A3B3B4A4"); } [Test] public void TestISerializable () { Log.Clear (); Driver (new BinaryFormatter (), new A (new D())); //Console.WriteLine (Log.Text); Assert.AreEqual (Log.Text, "A1B1A2B2A3B3B4A4"); } void Driver (IFormatter formatter, A a) { MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, a); stream.Position = 0; a.CheckSerializationStatus (); a = (A) formatter.Deserialize (stream); a.CheckDeserializationStatus (); } } class Log { static StringBuilder b = new StringBuilder (); public static void Write (string msg) { b.Append (msg); } public static void Clear () { b = new StringBuilder (); } public static string Text { get { return b.ToString (); } } } [Serializable] class A : IDeserializationCallback { public int Status = 0; B inner; public A (B inner) { this.inner = inner; this.inner.Outer = this; } public void CheckSerializationStatus () { Assert.AreEqual (2, Status, "#A01"); } public void CheckDeserializationStatus () { Assert.AreEqual (2, Status, "#A01"); } [OnSerializing] void OnSerializing (StreamingContext ctx) { Log.Write ("A1"); Assert.AreEqual (0, Status, "#A01"); Assert.AreEqual (0, inner.Status, "#A02"); Status++; } [OnSerialized] void OnSerialized (StreamingContext ctx) { Log.Write ("A2"); Assert.AreEqual (1, Status, "#A03"); Assert.AreEqual (1, inner.Status, "#A04"); // must have no effect after deserialization Status++; } [OnDeserializing] void OnDeserializing (StreamingContext ctx) { Log.Write ("A3"); Assert.IsNull (inner, "#A05"); Assert.AreEqual(0, Status, "#A06"); // must have no effect after deserialization Status = 42; } [OnDeserialized] void OnDeserialized (StreamingContext ctx) { Log.Write ("A4"); Assert.IsNotNull (inner, "#A07"); Assert.AreEqual(1, Status, "#A08"); Assert.AreEqual(1, inner.Status, "#A10"); Status++; } void IDeserializationCallback.OnDeserialization (object sender) { // don't log the order because it's undefined CheckDeserializationStatus (); } } [Serializable] class B : IDeserializationCallback { public int Status = 0; public A Outer; [OnSerializing] void OnSerializing (StreamingContext ctx) { Log.Write ("B1"); Assert.AreEqual (0, Status, "#B01"); Assert.AreEqual (1, Outer.Status, "#B01.2"); Status++; } [OnSerialized] void OnSerialized (StreamingContext ctx) { Log.Write ("B2"); Assert.AreEqual (1, Status, "#B02"); Assert.AreEqual (2, Outer.Status, "#B03"); // must have no effect after deserialization Status++; } [OnDeserializing] void OnDeserializing (StreamingContext ctx) { Log.Write ("B3"); Assert.IsNull (Outer, "#B05"); Assert.AreEqual (0, Status, "#B06"); // must have no effect after deserialization Status = 42; } [OnDeserialized] void OnDeserialized (StreamingContext ctx) { Log.Write ("B4"); } void IDeserializationCallback.OnDeserialization (object sender) { // don't log the order because it's undefined Assert.AreEqual (1, Status); } } [Serializable] class C : A { public C (B inner) : base (inner) { } [OnSerializing] void OnSerializing (StreamingContext ctx) { Log.Write ("C1"); Assert.AreEqual (1, Status, "#C01"); } [OnSerialized] void OnSerialized (StreamingContext ctx) { Log.Write ("C2"); Assert.AreEqual (2, Status, "#C02"); } } [Serializable] class D : B, ISerializable { public D () { } void ISerializable.GetObjectData (SerializationInfo info, StreamingContext ctx) { info.AddValue ("Status", Status); info.AddValue ("Outer", Outer); } D (SerializationInfo info, StreamingContext ctx) { Status = info.GetInt32 ("Status"); Outer = (A) info.GetValue ("Outer", typeof (A)); } } } #endif