Skip to content

Commit

Permalink
reorganize IsSerializable
Browse files Browse the repository at this point in the history
  • Loading branch information
smdn committed Apr 18, 2022
1 parent fada14e commit e9ed2b0
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 16 deletions.
91 changes: 75 additions & 16 deletions src/Smdn.Test.NUnit.Utils/Smdn.Test.NUnit/Assert.Serialization.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,109 @@
// SPDX-FileCopyrightText: 2020 smdn <smdn@smdn.jp>
// SPDX-License-Identifier: MIT
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER || NET5_0_OR_GREATER
#define SYSTEM_RUNTIME_SERIALIZATION_ISERIALIZABLE
#define SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
#endif

using System;
using System.IO;
#if SYSTEM_RUNTIME_SERIALIZATION_ISERIALIZABLE || SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
using System.Runtime.Serialization;
#endif
#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
using System.Runtime.Serialization.Formatters.Binary;
#endif

namespace Smdn.Test.NUnit;

public partial class Assert {
public static void IsSerializableBinaryFormat<TSerializable>(TSerializable obj)
/*where TSerializable : ISerializable*/
=> IsSerializableBinaryFormat(obj, null);
#if SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
private static IFormatter CreateDefaultSerializationFormatter()
#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
// TODO: use JsonSerializer instead
// https://docs.microsoft.com/ja-jp/dotnet/fundamentals/syslib-diagnostics/syslib0011
=> new BinaryFormatter();
#else
=> null;
#endif

private static IFormatter CreateDefaultDeserializationFormatter()
#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY && SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONBINDER
=> new BinaryFormatter() {
Binder = new DeserializationBinder(),
};
#else
=> null;
#endif
#endif // SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER

public static void IsSerializable<TSerializable>(
TSerializable obj,
Action<TSerializable> testDeserializedObject = null
)
#if SYSTEM_RUNTIME_SERIALIZATION_ISERIALIZABLE
where TSerializable : ISerializable
#endif
=> IsSerializableCore(
obj,
#if SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
CreateDefaultSerializationFormatter(),
CreateDefaultDeserializationFormatter(),
#endif
testDeserializedObject
);

#if SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
public static void IsSerializable<TSerializable>(
TSerializable obj,
IFormatter serializationFormatter,
IFormatter deserializationFormatter,
Action<TSerializable> testDeserializedObject = null
)
#if SYSTEM_RUNTIME_SERIALIZATION_ISERIALIZABLE
where TSerializable : ISerializable
#endif
=> IsSerializableCore(
obj,
serializationFormatter ?? throw new ArgumentNullException(nameof(serializationFormatter)),
deserializationFormatter ?? throw new ArgumentNullException(nameof(deserializationFormatter)),
testDeserializedObject
);
#endif

public static void IsSerializableBinaryFormat<TSerializable>(
private static void IsSerializableCore<TSerializable>(
TSerializable obj,
#if SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
IFormatter serializationFormatter,
IFormatter deserializationFormatter,
#endif
Action<TSerializable> testDeserializedObject
)
/*where TSerializable : ISerializable*/
#if SYSTEM_RUNTIME_SERIALIZATION_ISERIALIZABLE
where TSerializable : ISerializable
#endif
{
#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY && SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONBINDER
// TODO: use JsonSerializer instead
// https://docs.microsoft.com/ja-jp/dotnet/fundamentals/syslib-diagnostics/syslib0011
var serializeFormatter = new BinaryFormatter();
#if SYSTEM_RUNTIME_SERIALIZATION_IFORMATTER
if (serializationFormatter is null || deserializationFormatter is null)
return; // do nothing

using var stream = new MemoryStream();

#pragma warning disable SYSLIB0011
serializeFormatter.Serialize(stream, obj);
serializationFormatter.Serialize(stream, obj);
#pragma warning restore SYSLIB0011

stream.Position = 0L;

var deserializeFormatter = new BinaryFormatter() {
Binder = new DeserializationBinder()
};

#pragma warning disable SYSLIB0011
var deserialized = deserializeFormatter.Deserialize(stream);
var deserialized = deserializationFormatter.Deserialize(stream);
#pragma warning restore SYSLIB0011

IsNotNull(deserialized);
AreNotSame(obj, deserialized);
IsInstanceOf<TSerializable>(deserialized);

if (testDeserializedObject != null)
if (testDeserializedObject is not null)
testDeserializedObject((TSerializable)deserialized);
#else
// do nothing
Expand Down
108 changes: 108 additions & 0 deletions tests/Smdn.Test.NUnit.Utils/Smdn.Test.NUnit/Assert.Serialization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2022 smdn <smdn@smdn.jp>
// SPDX-License-Identifier: MIT
using System;
#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
using System.Runtime.Serialization.Formatters.Binary;
#endif
using NUnit.Framework;

namespace Smdn.Test.NUnit;

[TestFixture]
public class AssertSerializationTests {
[Test] public void IsSerializable_Uri() => Assert.IsSerializable(new Uri("http://example.com/example/"));
[Test] public void IsSerializable_IntPtr() => Assert.IsSerializable(IntPtr.Zero);
[Test] public void IsSerializable_DateTime() => Assert.IsSerializable(DateTime.MinValue);
[Test] public void IsSerializable_Exception() => Assert.IsSerializable(new InvalidOperationException());

[Test]
public void IsSerializable_WithTestAction_Uri()
{
var url = "http://example.com/example/";
var testActionCalled = false;

Assert.IsSerializable(new Uri(url), obj => {
Assert.IsNotNull(obj);
Assert.IsInstanceOf<Uri>(obj);
Assert.AreEqual(url, (obj as Uri).AbsoluteUri);

testActionCalled = true;
});

#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
Assert.IsTrue(testActionCalled, "test action called");
#else
Assert.IsFalse(testActionCalled, "test action called");
#endif
}

[Test]
public void IsSerializable_WithTestAction_IntPtr()
{
var testActionCalled = false;

Assert.IsSerializable(new IntPtr(1), obj => {
Assert.IsNotNull(obj);
Assert.IsInstanceOf<IntPtr>(obj);
Assert.AreEqual(new IntPtr(1), obj);

testActionCalled = true;
});

#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
Assert.IsTrue(testActionCalled, "test action called");
#else
Assert.IsFalse(testActionCalled, "test action called");
#endif
}

[Test]
public void IsSerializable_WithTestAction_DateTime()
{
var now = DateTime.Now;
var testActionCalled = false;

Assert.IsSerializable(now, obj => {
Assert.IsNotNull(obj);
Assert.IsInstanceOf<DateTime>(obj);
Assert.AreEqual(now, obj);

testActionCalled = true;
});

#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
Assert.IsTrue(testActionCalled, "test action called");
#else
Assert.IsFalse(testActionCalled, "test action called");
#endif
}

[Test]
public void IsSerializable_WithTestAction_Exception()
{
var innerException = new NotImplementedException("inner exception");
var message = "is serializable";
var testActionCalled = false;

Assert.IsSerializable(new NotSupportedException(message, innerException), obj => {
Assert.IsNotNull(obj);
Assert.IsInstanceOf<NotSupportedException>(obj);

var ex = (obj as NotSupportedException);

Assert.AreEqual(message, ex.Message);

Assert.IsNotNull(ex.InnerException);
Assert.IsInstanceOf<NotImplementedException>(ex.InnerException);
Assert.AreEqual(innerException.Message, ex.InnerException.Message);

testActionCalled = true;
});

#if SYSTEM_RUNTIME_SERIALIZATION_FORMATTER_BINARY
Assert.IsTrue(testActionCalled, "test action called");
#else
Assert.IsFalse(testActionCalled, "test action called");
#endif
}
}

0 comments on commit e9ed2b0

Please sign in to comment.