test: achieve 100% coverage of Maybe
This commit is contained in:
parent
12b2764a03
commit
b07f31f75f
|
@ -1,4 +1,5 @@
|
||||||
using FruityFoundation.Base.Structures;
|
using System;
|
||||||
|
using FruityFoundation.Base.Structures;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Base.Tests.Structures;
|
namespace Base.Tests.Structures;
|
||||||
|
@ -148,4 +149,340 @@ public class MaybeTests
|
||||||
Assert.That(result.HasValue, Is.True);
|
Assert.That(result.HasValue, Is.True);
|
||||||
Assert.That(result.Value, Is.EqualTo(25));
|
Assert.That(result.Value, Is.EqualTo(25));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Cast_ReturnsMaybe_WhenNewCastIsInvalid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create(25);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.Cast<Array>();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<Maybe<Array>>());
|
||||||
|
Assert.That(result.HasValue, Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Cast_ReturnsEmptyMaybe_WhenValueIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create((string?)null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.Cast<string>();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<Maybe<string>>());
|
||||||
|
Assert.That(result.HasValue, Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ValueType_OrValue_ReturnsProvidedValue_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<int>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrValue(25);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo(25));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ValueType_OrValue_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create(25);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrValue(321);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo(25));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ReferenceType_OrValue_ReturnsProvidedValue_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrValue("banana");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ReferenceType_OrValue_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrValue("pears");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ValueType_OrValueFactory_ReturnsOrValue_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<int>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrEval(() => 25);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo(25));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ValueType_OrValueFactory_ReturnsOrValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create(25);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrEval(() => 321);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo(25));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ReferenceType_OrValueFactory_ReturnsOrValue_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrEval(() => "banana");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ReferenceType_OrValueFactory_ReturnsOrValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrEval(() => "pears");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Try_ReturnsFalse_OutputsDefault_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string? output;
|
||||||
|
var result = maybe.Try(out output);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.False);
|
||||||
|
Assert.That(output, Is.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Try_RetunsTrue_OutputsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string? output;
|
||||||
|
var result = maybe.Try(out output);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.True);
|
||||||
|
Assert.That(output, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrow_ThrowsMessage_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Assert.Throws<ApplicationException>(() => maybe.OrThrow("This cannot be empty!"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<ApplicationException>());
|
||||||
|
Assert.That(result.Message, Is.EqualTo("This cannot be empty!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrow_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrThrow("This cannot be empty!");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrowMessageFactory_ThrowsMessage_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Assert.Throws<ApplicationException>(() => maybe.OrThrow(messageFactory: () => "This cannot be empty!"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<ApplicationException>());
|
||||||
|
Assert.That(result.Message, Is.EqualTo("This cannot be empty!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrowMessageFactory_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrThrow(messageFactory: () => "This cannot be empty!");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrowExceptionFactory_ThrowsMessage_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Assert.Throws<InvalidOperationException>(() => maybe.OrThrow(exFactory: () => new InvalidOperationException("This cannot be empty!")));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<InvalidOperationException>());
|
||||||
|
Assert.That(result.Message, Is.EqualTo("This cannot be empty!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_OrThrowExceptionFactory_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.OrThrow(exFactory: () => new InvalidOperationException("This cannot be empty!"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Map_ReturnsNewEmptyType_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<int>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.Map(x => x.ToString());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result.HasValue, Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Map_ReturnsNewMaybeWithValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create(25);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.Map(x => x.ToString());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result.HasValue, Is.True);
|
||||||
|
Assert.That(result.Value, Is.EqualTo("25"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Value_Throws_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Assert.Throws<InvalidOperationException>(() => _ = maybe.Value);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.InstanceOf<InvalidOperationException>());
|
||||||
|
Assert.That(result.Message, Is.EqualTo("Maybe value is empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_Value_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.Value;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ToString_ReturnsPlaceholder_WhenEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Empty<string>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.ToString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("<empty>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ToString_ReturnsNullPlaceholder_WhenValueIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create((string?)null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.ToString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("<null>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Maybe_ToString_ReturnsValue_WhenNotEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var maybe = Maybe.Create("banana");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = maybe.ToString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(result, Is.EqualTo("banana"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,21 @@ public readonly record struct Maybe<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T OrValue(T orVal) => HasValue ? Value : orVal;
|
public T OrValue(T orVal)
|
||||||
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
return orVal;
|
||||||
|
|
||||||
public T OrEval(Func<T> valueFactory) => HasValue ? Value : valueFactory();
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T OrEval(Func<T> valueFactory)
|
||||||
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
return valueFactory();
|
||||||
|
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Try(out T val)
|
public bool Try(out T val)
|
||||||
{
|
{
|
||||||
|
@ -47,17 +59,38 @@ public readonly record struct Maybe<T>
|
||||||
return HasValue;
|
return HasValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T OrThrow(string msg) =>
|
public T OrThrow(string msg)
|
||||||
HasValue ? Value : throw new Exception(msg);
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
throw new ApplicationException(msg);
|
||||||
|
|
||||||
public T OrThrow(Func<string> messageFactory) =>
|
return Value;
|
||||||
HasValue ? Value : throw new Exception(messageFactory());
|
}
|
||||||
|
|
||||||
public T OrThrow(Func<Exception> exFactory) =>
|
public T OrThrow(Func<string> messageFactory)
|
||||||
HasValue ? Value : throw exFactory();
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
throw new ApplicationException(messageFactory());
|
||||||
|
|
||||||
public Maybe<TOutput> Map<TOutput>(Func<T, TOutput> transformer) =>
|
return Value;
|
||||||
HasValue ? Maybe.Create(transformer(Value)) : Maybe.Empty<TOutput>();
|
}
|
||||||
|
|
||||||
|
public T OrThrow(Func<Exception> exFactory)
|
||||||
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
throw exFactory();
|
||||||
|
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Maybe<TOutput> Map<TOutput>(Func<T, TOutput> transformer)
|
||||||
|
{
|
||||||
|
if (!HasValue)
|
||||||
|
return Maybe.Empty<TOutput>();
|
||||||
|
|
||||||
|
var newValue = transformer(Value);
|
||||||
|
return new Maybe<TOutput>(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
public Maybe<TOutput> Bind<TOutput>(Func<T, Maybe<TOutput>> binder) =>
|
public Maybe<TOutput> Bind<TOutput>(Func<T, Maybe<TOutput>> binder) =>
|
||||||
HasValue ? binder(Value) : Maybe.Empty<TOutput>();
|
HasValue ? binder(Value) : Maybe.Empty<TOutput>();
|
||||||
|
@ -95,12 +128,11 @@ public readonly record struct Maybe<T>
|
||||||
|
|
||||||
public static implicit operator Maybe<T>(T val) => Maybe.Create(val);
|
public static implicit operator Maybe<T>(T val) => Maybe.Create(val);
|
||||||
|
|
||||||
public static explicit operator T(Maybe<T> val) => val.Value;
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return (Try(out var val)
|
if (!HasValue)
|
||||||
? val?.ToString()
|
return "<empty>";
|
||||||
: base.ToString())!;
|
|
||||||
|
return _value?.ToString() ?? "<null>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user