diff --git a/Stop.cs b/Stop.cs new file mode 100644 index 0000000..9076ba0 --- /dev/null +++ b/Stop.cs @@ -0,0 +1,47 @@ +using System; + +namespace AggregateConsistencyBoundary +{ + public abstract class Stop + { + public int StopId { get; set; } + public StopStatus Status { get; set; } + public int Sequence { get; set; } + + public void Arrive() + { + if (Status != StopStatus.InTransit) + { + throw new InvalidOperationException("Stop has already arrived."); + } + + Status = StopStatus.Arrived; + } + + public void Depart() + { + if (Status == StopStatus.Departed) + { + throw new InvalidOperationException("Stop has already departed."); + } + + if (Status == StopStatus.InTransit) + { + throw new InvalidOperationException("Stop hasn't arrived yet."); + } + + Status = StopStatus.Departed; + } + } + + public class PickupStop : Stop { } + + public class DeliveryStop : Stop { } + + public enum StopStatus + { + InTransit, + Arrived, + Departed + } +} \ No newline at end of file diff --git a/Stop.cs b/Stop.cs new file mode 100644 index 0000000..9076ba0 --- /dev/null +++ b/Stop.cs @@ -0,0 +1,47 @@ +using System; + +namespace AggregateConsistencyBoundary +{ + public abstract class Stop + { + public int StopId { get; set; } + public StopStatus Status { get; set; } + public int Sequence { get; set; } + + public void Arrive() + { + if (Status != StopStatus.InTransit) + { + throw new InvalidOperationException("Stop has already arrived."); + } + + Status = StopStatus.Arrived; + } + + public void Depart() + { + if (Status == StopStatus.Departed) + { + throw new InvalidOperationException("Stop has already departed."); + } + + if (Status == StopStatus.InTransit) + { + throw new InvalidOperationException("Stop hasn't arrived yet."); + } + + Status = StopStatus.Departed; + } + } + + public class PickupStop : Stop { } + + public class DeliveryStop : Stop { } + + public enum StopStatus + { + InTransit, + Arrived, + Departed + } +} \ No newline at end of file diff --git a/Tests.cs b/Tests.cs new file mode 100644 index 0000000..f577ace --- /dev/null +++ b/Tests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using Shouldly; +using Xunit; + +namespace AggregateConsistencyBoundary +{ + public class Tests + { + private readonly Shipment _shipment; + + public Tests() + { + var stops = new List + { + new PickupStop + { + StopId = 1, + Sequence = 1, + }, + new DeliveryStop + { + StopId = 2, + Sequence = 2, + } + }; + _shipment = new Shipment(stops); + } + + [Fact] + public void CompleteShipment() + { + _shipment.Arrive(1); + _shipment.Pickup(1); + _shipment.Arrive(2); + _shipment.Deliver(2); + _shipment.IsComplete().ShouldBeTrue(); + } + + [Fact] + public void CannotPickupWithoutArriving() + { + Should.Throw(() => _shipment.Pickup(1), "Stop hasn't arrived yet."); + } + + [Fact] + public void CannotDeliverWithoutArriving() + { + Should.Throw(() => _shipment.Deliver(2), "Stop hasn't arrived yet."); + } + + [Fact] + public void CannotPickupAtDelivery() + { + Should.Throw(() => _shipment.Pickup(2), "Stop is not a delivery."); + } + + [Fact] + public void CannotDeliverAtPickup() + { + Should.Throw(() => _shipment.Deliver(1), "Stop is not a pickup."); + } + + [Fact] + public void ArriveStopDoesNotExist() + { + Should.Throw(() => _shipment.Arrive(0), "Stop does not exist."); + } + + [Fact] + public void PickupStopDoesNotExist() + { + Should.Throw(() => _shipment.Pickup(0), "Stop does not exist."); + } + + [Fact] + public void DeliverStopDoesNotExist() + { + Should.Throw(() => _shipment.Deliver(0), "Stop does not exist."); + } + + [Fact] + public void ArriveNonDepartedStops() + { + _shipment.Arrive(1); + Should.Throw(() => _shipment.Arrive(2), "Previous stops have not departed."); + } + + [Fact] + public void AlreadyArrived() + { + _shipment.Arrive(1); + Should.Throw(() => _shipment.Arrive(1), "Stop has already arrived."); + } + + [Fact] + public void AlreadyPickedUp() + { + _shipment.Arrive(1); + _shipment.Pickup(1); + Should.Throw(() => _shipment.Pickup(1), "Stop has already departed."); + } + + [Fact] + public void AlreadyDelivered() + { + _shipment.Arrive(1); + _shipment.Pickup(1); + _shipment.Arrive(2); + _shipment.Deliver(2); + Should.Throw(() => _shipment.Deliver(2), "Stop has already departed."); + } + } +} \ No newline at end of file