240 lines
7.6 KiB
C#
Raw Normal View History

//
// System.Runtime.Serialization.SerializationCallbackTest.cs
//
// Author: Robert Jordan (robertj@gmx.net)
//
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));
}
}
}