Skip to content

Instantly share code, notes, and snippets.

using Arcus.Messaging.Abstractions.ServiceBus.MessageHandling;
using Arcus.Messaging.Pumps.Abstractions.Resiliency;
public class OrderMessageHandler : IAzureServiceBusMessageHandler<Order>
{
private readonly IMessagePumpCircuitBreaker _circuitBreaker;
public OrderMessageHandler(IMessagePumpCircuitBreaker circuitBreaker)
{
_circuitBreaker = circuitBreaker;
// Guest -> GuestList -> ValidationResult<GuestList>
let add guest list =
Optic.map guests_ (fun gs -> g :: gs)
// Guest -> GuestList -> ValidationResult<GuestList>
let remove guest list =
Optic.get (guest_ guest.Name) list
>>= fun g -> Optic.map guests_ (List.except [g]) list
let guests = GuestList.create [
Guest.create "Eve"
Guest.create "Lisa" ]
let lens = guest_ >=> name_ "Eve"
// result : ValidationResult<GuestList>
let result = Optic.set lens "AdamEve" guests
// A lens that provides the name of the guest.
let name_ : ResultLens<Guest, string> =
(fun g -> Ok g.Name), (fun n _ -> Guest.create n)
// A lens on the guest list that provides the individual guests on the list.
let guests_ : ResultLens<GuestList, Guest list> =
(fun (GuestList xs) -> Ok xs), fun xs _ -> GuestList.create xs
// A lens that points to a single guest on the guest list.
let guest_ name : ResultLens<GuestList, Guest> =
type ValidationResult<'a> = Result<'a, ErrorsByTag>
type ResultLens<'a, 'b> = ('a -> ValidationResult<'b>) * ('b -> 'a -> ValidationResult<'a>)
module Compose =
type ResultLens =
| ResultLens with
static member (>=>) (ResultLens, (g2, s2) : ResultLens<'b, 'c>) =
fun ((g1, s1) : ResultLens<'a,'b>) ->
(fun a -> g1 a >>= fun b -> g2 b),
(fun c a -> g1 a >>= fun b -> s2 c b >>= fun b -> s1 b a) : ResultLens<'a,'c>
open FPrimitive
type Guest =
private { Name : string } with
static member create name = result {
let! name = specModel id name {
notNullOrWhiteSpace "guest name should not be blank"
alphabetical "guest name should only contain alphabetical characters" }
return { Name = name } }
[Fact]
public void Delete_WithMessageId_ShouldDeleteMessage()
{
// Arrange
Message[] leftOverMessages = CreateMessages();
Message targetMessage = CreateMessage();
var repo = new InMemoryMessageRepository(leftOverMessages.Append(targetMessage));
var service = CreateMessageService(repo);
// Act
[Fact]
public void Delete_WithMessageId_ShouldDeleteMessage()
{
// Arrange
var messageId = Guid.NewGuid().ToString();
var repo = new Mock<IMessageRepository>();
repo.Setup(r => r.DeleteMessage(messageId)).Returns(1);
var cache = new Mock<IMessageCache>();
cache.Setup(c => c.Get(messageId)).Returns(Cache.NotInCache);
restaurant fully booked always exceeds capacity failed
{ Name = GuestName "xycQKLpdXBCspKq"
Quantity = Quantity 1
Date = Date 30/11/2023 00:00:00 +00:00 } [{ Name = GuestName "kWWQQebC"
Quantity = Quantity 15
Date = Date 18/11/2023 00:00:00 +00:00 };
{ Name = GuestName "mnvWmFjdYSwqlfJDh"
Quantity = Quantity 14
Date = Date 19/11/2023 00:00:00 +00:00 };
{ Name = GuestName "ICg"
restaurant tests.restaurant accepts reservation within two weeks if the requested quantity is available failed
Failed after 2 tests. Parameters:
({ Name = GuestName "jd"
Quantity = Quantity 19
Date = Date 01/12/2023 00:00:00 +00:00 }, [])
Label of failing property:
capacity on 2023-12-01: 0