using System; using System.Linq; using UnitTestSharp; namespace Amphora.UnitTests { public class StatusOrTests : TestFixture { public class LayoutTests : TestFixture { public void IsThreeFlatFieldsAndTheValue() { var fields = FlatLayout.InstanceFields(typeof(StatusOr<>)); CheckEqual(4, fields.Length); CheckEqual(1, fields.Count(field => field.FieldType.IsGenericParameter)); CheckTrue(fields.Where(field => !field.FieldType.IsGenericParameter).All(FlatLayout.IsFlat)); } } public class EqualsTests : TestFixture { public void EqualValues_AreEqual() { CheckEqual((StatusOr)5, (StatusOr)5); } public void DifferentValues_AreNotEqual() { CheckNotEqual((StatusOr)5, (StatusOr)6); } public void EqualFailures_AreEqual() { CheckEqual( (StatusOr)Status.FromWire(FailureTestKinds.Unreachable, reference: "ref", bits: 5), (StatusOr)Status.FromWire(FailureTestKinds.Unreachable, reference: "ref", bits: 5)); } public void DifferentFailureParts_AreNotEqual() { var failure = (StatusOr)Status.FromWire(FailureTestKinds.Unreachable, reference: "ref", bits: 5); CheckNotEqual(failure, (StatusOr)BlockedCellKind.Instance.Fail(FailureTestKinds.Wall)); CheckNotEqual(failure, (StatusOr)Status.FromWire(FailureTestKinds.Unreachable, reference: "other", bits: 5)); CheckNotEqual(failure, (StatusOr)Status.FromWire(FailureTestKinds.Unreachable, reference: "ref", bits: 6)); } public void ValueAndFailure_AreNotEqual() { CheckNotEqual((StatusOr)0, (StatusOr)FailureTestKinds.Unreachable.Fail()); } public void OtherType_IsNotEqual() { CheckFalse(((StatusOr)5).Equals((object)5)); } } public class GetHashCodeTests : TestFixture { public void EqualValues_HashTheSame() { string value = "value"; string copy = new string(value.ToCharArray()); CheckEqual(((StatusOr)value).GetHashCode(), ((StatusOr)copy).GetHashCode()); } public void EqualFailures_HashTheSame() { string reference = "ref"; string copy = new string(reference.ToCharArray()); StatusOr failure = Status.FromWire(FailureTestKinds.Unreachable, reference, bits: 5); StatusOr same = Status.FromWire(FailureTestKinds.Unreachable, copy, bits: 5); CheckEqual(failure.GetHashCode(), same.GetHashCode()); } public void NullValue_HashesWithoutThrowing() { ((StatusOr)(string)null).GetHashCode(); } } public class OperatorEqualsTests : TestFixture { public void EqualStatusOrs_AreEqual() { StatusOr five = 5; CheckTrue(five == 5); CheckFalse(five != 5); } public void DifferentStatusOrs_AreNotEqual() { StatusOr five = 5; CheckFalse(five == 6); CheckTrue(five != 6); } } public class IsOkTests : TestFixture { public void Value_IsTrue() { StatusOr five = 5; CheckTrue(five.IsOk); } public void Failed_IsFalse() { StatusOr failed = FailureTestKinds.Unreachable.Fail(); CheckFalse(failed.IsOk); } } public class ValueTests : TestFixture { public void Ok_IsTheValue() { StatusOr five = 5; CheckEqual(5, five.Value); } public void Failed_Throws() { StatusOr failed = FailureTestKinds.Unreachable.Fail(); CheckThrow(typeof(InvalidOperationException)); _ = failed.Value; } } public class StatusTests : TestFixture { public void Ok_IsOk() { StatusOr five = 5; CheckEqual(Status.Ok, five.Status); } public void Failed_IsTheStatusItCameFrom() { Status failure = BlockedCellKind.Instance.Fail(FailureTestKinds.Wall); StatusOr failed = failure; CheckEqual(failure, failed.Status); } public void Failed_AllocatesNothing() { Allocations.StatusOrSink = BlockedCellKind.Instance.Fail(FailureTestKinds.Wall); CheckEqual(0L, Allocations.During(() => Allocations.StatusSink = Allocations.StatusOrSink.Status)); } } public class TryGetValueTests : TestFixture { public void Ok_ReturnsTrueAndTheValue() { StatusOr five = 5; CheckTrue(five.TryGetValue(out int value)); CheckEqual(5, value); } public void Failed_ReturnsFalseAndTheDefault() { StatusOr failed = FailureTestKinds.Unreachable.Fail(); CheckFalse(failed.TryGetValue(out int value)); CheckEqual(0, value); } } public class FromResultTests : TestFixture { public void HoldsTheValueAndNoFailure() { StatusOr statusOr = "value"; CheckEqual("value", statusOr.Value); CheckNull(statusOr.Kind); CheckNull(statusOr.Ref); CheckEqual(0L, statusOr.Bits); } public void Null_IsAnOkNullValue() { StatusOr statusOr = (string)null; CheckTrue(statusOr.IsOk); CheckNull(statusOr.Value); } public void AllocatesNothing() { CheckEqual(0L, Allocations.During(() => Allocations.StatusOrSink = 5)); } } public class FromStatusTests : TestFixture { public void CopiesEveryPart() { StatusOr failed = Status.FromWire(FailureTestKinds.Unreachable, reference: "ref", bits: -5); CheckEqual(FailureTestKinds.Unreachable, failed.Kind); CheckEqual("ref", failed.Ref); CheckEqual(-5L, failed.Bits); } public void Ok_Throws() { CheckThrow(typeof(ArgumentException)); StatusOr statusOr = Status.Ok; } public void AllocatesNothing() { Allocations.StatusSink = BlockedCellKind.Instance.Fail(FailureTestKinds.Wall); CheckEqual(0L, Allocations.During(() => Allocations.StatusOrSink = Allocations.StatusSink)); } } } }