using JetBrains.Annotations;
using NUnit.Framework;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
using Robust.UnitTesting.Shared;
namespace Robust.Shared.IntegrationTests.Serialization;
[Serializable, NetSerializable]
[UsedImplicitly(Reason = "Needed so RobustSerializer is guaranteed to pick up on the unsafe types.")]
internal sealed class MakeTheseSerializable
{
#pragma warning disable CS0649
public UnsafeFloat Single;
public UnsafeDouble Double;
public UnsafeHalf Half;
public Half SafeHalf;
#pragma warning restore CS0649
}
///
/// Tests the serialization behavior of float types when is *not* set to do anything special.
/// Tests both primitives and Robust's "Unsafe" variants.
///
[TestFixture, TestOf(typeof(RobustSerializer)), TestOf(typeof(NetUnsafeFloatSerializer))]
internal sealed class NetSerializerDefaultFloatTest : OurRobustUnitTest
{
private IRobustSerializer _serializer = null!;
[OneTimeSetUp]
public void Setup()
{
_serializer = IoCManager.Resolve();
_serializer.Initialize();
}
internal static readonly TestCaseData[] PassThroughFloatTests =
[
new TestCaseData(0.0).Returns(0.0),
new TestCaseData(1.0).Returns(1.0),
new TestCaseData(double.NaN).Returns(double.NaN),
new TestCaseData(double.PositiveInfinity).Returns(double.PositiveInfinity),
];
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestSingle(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (float)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestUnsafeSingle(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeFloat)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestDouble(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestUnsafeDouble(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeDouble)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestHalf(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (Half)input);
ms.Position = 0;
return (double)_serializer.Deserialize(ms);
}
[TestCaseSource(nameof(PassThroughFloatTests))]
public double TestUnsafeHalf(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeHalf)(Half)input);
ms.Position = 0;
return (double)(Half)_serializer.Deserialize(ms);
}
}
///
/// Tests the serialization behavior of float types when is set to remove NaNs on read.
/// Tests both primitives and Robust's "Unsafe" variants.
///
[TestFixture]
[TestOf(typeof(RobustSerializer)), TestOf(typeof(NetUnsafeFloatSerializer)), TestOf(typeof(NetSafeFloatSerializer))]
internal sealed class NetSerializerSafeFloatTest : OurRobustUnitTest
{
private IRobustSerializer _serializer = default!;
[OneTimeSetUp]
public void Setup()
{
_serializer = IoCManager.Resolve();
_serializer.FloatFlags = SerializerFloatFlags.RemoveReadNan;
_serializer.Initialize();
}
internal static readonly TestCaseData[] SafeFloatTests =
[
new TestCaseData(0.0).Returns(0.0),
new TestCaseData(1.0).Returns(1.0),
new TestCaseData(double.NaN).Returns(0.0),
new TestCaseData(double.PositiveInfinity).Returns(double.PositiveInfinity),
];
[TestCaseSource(nameof(SafeFloatTests))]
public double TestSingle(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (float)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(typeof(NetSerializerDefaultFloatTest), nameof(NetSerializerDefaultFloatTest.PassThroughFloatTests))]
public double TestUnsafeSingle(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeFloat)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(SafeFloatTests))]
public double TestDouble(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(typeof(NetSerializerDefaultFloatTest), nameof(NetSerializerDefaultFloatTest.PassThroughFloatTests))]
public double TestUnsafeDouble(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeDouble)input);
ms.Position = 0;
return _serializer.Deserialize(ms);
}
[TestCaseSource(nameof(SafeFloatTests))]
public double TestHalf(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (Half)input);
ms.Position = 0;
return (double)_serializer.Deserialize(ms);
}
[TestCaseSource(typeof(NetSerializerDefaultFloatTest), nameof(NetSerializerDefaultFloatTest.PassThroughFloatTests))]
public double TestUnsafeHalf(double input)
{
var ms = new MemoryStream();
_serializer.Serialize(ms, (UnsafeHalf)(Half)input);
ms.Position = 0;
return (double)(Half)_serializer.Deserialize(ms);
}
}