Skip to content

Instantly share code, notes, and snippets.

@thefringeninja
Created July 15, 2014 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thefringeninja/0ff4129f0eb7764774e0 to your computer and use it in GitHub Desktop.
Save thefringeninja/0ff4129f0eb7764774e0 to your computer and use it in GitHub Desktop.
Message Specification
public class MessageSpecification : TypedSpecification<MessageSpecification.Result>, HasMessages
{
public Action Before;
public Action<Bus> Bootstrap = bus => { };
public List<Expression<Func<Result, bool>>> Assertions = new List<Expression<Func<Result, bool>>>();
public Action Finally;
public readonly List<Event> Given = new List<Event>();
public string Name;
public Message When;
public readonly List<Event> Expect = new List<Event>();
#region TypedSpecification<Result> Members
public string GetName()
{
return Name;
}
public Action GetBefore()
{
return Before;
}
public Delegate GetOn()
{
var messages = new List<Message>(Given)
{
When
};
return new Func<Messages>(() => new Messages(messages));
}
public Delegate GetWhen()
{
return new Func<Messages, Result>(
input =>
{
var output = new List<Message>();
var bus = new InMemoryBus(GetType().FullName);
Bootstrap(bus);
bus.Subscribe(new AdHocHandler<Message>(output.Add));
Exception thrownException = null;
try
{
foreach (var message in input)
{
bus.Publish(message);
}
}
catch (Exception ex)
{
thrownException = ex;
}
return new Result(output.Except(input), thrownException);
});
}
public IEnumerable<Expression<Func<Result, bool>>> GetAssertions()
{
return new List<Expression<Func<Result, bool>>>(Assertions)
{
result => result.EventsMatched(this)
};
}
public Action GetFinally()
{
return Finally;
}
#endregion
#region Nested type: Messages
private class Messages : IEnumerable<Message>
{
private readonly IList<Message> list;
public Messages(IEnumerable<Message> source)
{
list = new List<Message>(source);
}
#region IEnumerable<Message> Members
public IEnumerator<Message> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
public override string ToString()
{
return this.Aggregate(
new StringBuilder(),
(builder, x) => builder.AppendLine(x.ToString()),
builder => builder.ToString());
}
}
#endregion
#region Nested type: NoExceptionWasThrownException
public class NoExceptionWasThrownException : Exception
{
}
#endregion
#region Nested type: Result
public class Result : HasMessages
{
public readonly IEnumerable<Message> Actions;
public Result(IEnumerable<Message> actions, Exception ex = null)
{
this.Actions = actions;
if (ex is AggregateException)
{
ex = ex.GetBaseException();
}
ThrownException = ex ?? new NoExceptionWasThrownException(null);
}
public bool ThrewAnException
{
get { return false == ThrownException is NoExceptionWasThrownException; }
}
public Exception ThrownException { get; private set; }
public bool DoesNothing
{
get { return false == Actions.Any(); }
}
public override string ToString()
{
return ThrewAnException
? ThrownException.Message
: Actions.Aggregate(
new StringBuilder(),
(builder, action) => builder.Append(action).AppendLine(),
builder => builder.ToString());
}
IEnumerable<Message> HasMessages.Messages
{
get { return Actions; }
}
}
#endregion
IEnumerable<Message> HasMessages.Messages
{
get { return Expect; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment