namespace NitroxModel.DataStructures.Util;
[TestClass]
public class OptionalTest
{
///
/// These optional additions should be in test method but MSTest
/// reuses instances which causes Optional{T}.HasValue to be called before the new conditions are added.
///
[ClassInitialize]
public static void Init(TestContext _)
{
Optional.ApplyHasValueCondition(v => v.GetType() == typeof(A) || v.Threshold > 200); // Cheat: allow check if type A to do more complex tests on Optional.HasValue
Optional.ApplyHasValueCondition(v => v.Threshold <= 200);
}
[TestMethod]
public void OptionalGet()
{
Optional op = Optional.Of("test");
op.Value.Should().Be("test");
}
[TestMethod]
public void OptionalIsPresent()
{
Optional op = Optional.Of("test");
op.HasValue.Should().BeTrue();
}
[TestMethod]
public void OptionalIsNotPresent()
{
Optional op = Optional.Empty;
op.HasValue.Should().BeFalse();
}
[TestMethod]
public void OptionalOrElseValidValue()
{
Optional op = Optional.Of("test");
op.OrElse("test2").Should().Be("test");
}
[TestMethod]
public void OptionalOrElseNoValue()
{
Optional op = Optional.Empty;
op.OrElse("test").Should().Be("test");
}
[TestMethod]
public void OptionalEmpty()
{
Optional op = Optional.Empty;
op.HasValue.Should().BeFalse();
}
[TestMethod]
public void OptionalSetValueNull()
{
Optional op = Optional.Of(new Random());
Assert.IsTrue(op.HasValue);
Assert.ThrowsException(() => { op = null; }, "Setting optional to null should not be allowed.");
op = Optional.Empty;
Assert.IsFalse(op.HasValue);
}
[TestMethod]
public void OptionalHasValueDynamicChecks()
{
Optional opBase = Optional.Of(new Base());
opBase.HasValue.Should().BeTrue();
opBase.Value.Threshold.Should().Be(202);
Optional a = Optional.Of(new A());
a.HasValue.Should().BeTrue();
Optional actuallyB = Optional.Of(new B());
actuallyB.HasValue.Should().BeFalse();
Optional b = Optional.Of(new B());
b.HasValue.Should().BeFalse();
// A check should still happen on Base because Optional includes more-specific-than-itself checks.
Optional aAsBase = Optional.Of((Base)a);
aAsBase.HasValue.Should().BeTrue();
aAsBase.Value.Threshold.Should().Be(200);
// Optional