Skip to content

Commit

Permalink
- More documentation around classes and methods.
Browse files Browse the repository at this point in the history
- Added syntactic sugar to support rolling up messages from other outcome objects.
- Removed an exception from Failure.FromOutcome() that threw if the source outcome had Success = True. This was limiting and unecessary.
  • Loading branch information
Brian committed Nov 14, 2014
1 parent 016a47a commit dcd4914
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 7 deletions.
30 changes: 30 additions & 0 deletions Outcomes.Tests/FailureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ public void FailureChaining_MessageTest()
Assert.IsTrue(Outcome.ToString("<br>") == "test1<br>test2<br>test3<br>");
}


[TestMethod]
public void FailureChaining_MessageTest_Syntactic_Sugar()
{
var Messages = new List<string> { "test2", "test3" };

var Outcome = Outcomes.Failure<int>().WithMessage("test1")
.WithMessagesFrom(Messages);

Assert.IsFalse(Outcome.Success);
Assert.IsTrue(Outcome.Value == 0);
Assert.IsTrue(Outcome.Messages.Count == 3);
Assert.IsTrue(Outcome.ToString() == "test1test2test3");
Assert.IsTrue(Outcome.ToString("<br>") == "test1<br>test2<br>test3<br>");
}

[TestMethod]
public void FailureChaining_FromExceptionTest()
{
Expand Down Expand Up @@ -102,5 +118,19 @@ public void FailureChaining_FromOutcome_Chaining_Test()
Assert.IsTrue(Outcome.Messages.Count == 3);
Assert.IsTrue(Outcome.ToString("<br>") == "prefix<br>test<br>suffix<br>");
}

[TestMethod]
public void FailureChaining_Syntactic_Sugar_Test()
{
var PreviousOutcome = Outcomes.Failure("test");

var Outcome = Outcomes.Failure().WithMessage("prefix")
.WithMessagesFrom(PreviousOutcome)
.WithMessage("suffix");

Assert.IsFalse(Outcome.Success);
Assert.IsTrue(Outcome.Messages.Count == 3);
Assert.IsTrue(Outcome.ToString("<br>") == "prefix<br>test<br>suffix<br>");
}
}
}
42 changes: 39 additions & 3 deletions Outcomes/Builder/FailureOutcomeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@

namespace Ether.Outcomes.Builder
{
/// <summary>
/// Uses the builder pattern to create a fluent interface for failure scenarios.
/// </summary>
public class FailureOutcomeBuilder<T> : SuccessOutcomeBuilder<T>, IFailureOutcomeBuilder<T>
{
internal FailureOutcomeBuilder(bool success) : base(success)
{
}

/// <summary>
/// Adds messages from the specified exception. Internally, Outcome.Net calls exception.Message to generate the messages.
/// </summary>
/// <param name="exception">Exception used to generate the message.</param>
/// <param name="message">Optional message that will appear after the exception's messages.</param>
public IFailureOutcomeBuilder<T> FromException(Exception exception, string message = null)
{
if (message != null)
Expand All @@ -18,28 +26,56 @@ public IFailureOutcomeBuilder<T> FromException(Exception exception, string messa
return this;
}

/// <summary>
/// Adds messages from the specified outcome.
/// </summary>
/// <param name="outcome">Source outcome that messages are pulled from. If there are no messages, execution continues.</param>
/// <param name="message">Optional message that will appear after the specified outcome's messages.</param>
public IFailureOutcomeBuilder<T> FromOutcome(IOutcome outcome, string message = null)
{
if(outcome.Success)
throw new InvalidOperationException("When creating a failure outcome, and calling FromOutcome, Outcome.Success was True. This is not allowed.");

if (message != null)
Messages.Add(message);

base.WithMessage(outcome.Messages);
return this;
}

/// <summary>
/// Adds a message to the end of the message list.
/// </summary>
public new IFailureOutcomeBuilder<T> WithMessage(string message)
{
base.WithMessage(message);
return this;
}

/// <summary>
/// Adds a collection of messages to the end of the outcome's message list.
/// </summary>
public new IFailureOutcomeBuilder<T> WithMessage(IEnumerable<string> messages)
{
base.WithMessage(messages);
return this;
}

/// <summary>
/// Alternate syntax for FromOutcome. Adds messages from the specified outcome, if any.
/// </summary>
/// <param name="outcome">Source outcome that messages are pulled from.</param>
/// <param name="message">Optional message that will appear after the specified outcome's messages.</param>
public IFailureOutcomeBuilder<T> WithMessagesFrom(IOutcome outcome, string message = null)
{
FromOutcome(outcome, message);
return this;
}

/// <summary>
/// Alternate syntax for WithMessage. Adds a collection of messages to the end of the outcome's message list.
/// </summary>
public IFailureOutcomeBuilder<T> WithMessagesFrom(IEnumerable<string> messages)
{
base.WithMessage(messages);
return this;
}
}
}
14 changes: 13 additions & 1 deletion Outcomes/Builder/IFailureOutcomeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface IFailureOutcomeBuilder<T> : IOutcome<T>
IFailureOutcomeBuilder<T> FromException(Exception exception, string message = null);

/// <summary>
/// Add an outcome's message to this outcome's message collection.
/// Add an outcome's message to the message list.
/// Useful for unwinding deep calls where several methods have something to add about the failure.
/// </summary>
/// <param name="outcome">A failure outcome.</param>
Expand All @@ -35,5 +35,17 @@ public interface IFailureOutcomeBuilder<T> : IOutcome<T>
/// <param name="messages">The strings to add.</param>
/// <returns></returns>
IFailureOutcomeBuilder<T> WithMessage(IEnumerable<string> messages);

/// <summary>
/// Alternate syntax for FromOutcome. Adds messages from the specified outcome (if any).
/// </summary>
/// <param name="outcome">Source outcome that messages are pulled from.</param>
/// <param name="message">Optional message that will appear after the specified outcome's messages.</param>
IFailureOutcomeBuilder<T> WithMessagesFrom(IOutcome outcome, string message = null);

/// <summary>
/// Alternate syntax for WithMessage. Adds messages to the end of the message collection.
/// </summary>
IFailureOutcomeBuilder<T> WithMessagesFrom(IEnumerable<string> messages);
}
}
5 changes: 4 additions & 1 deletion Outcomes/Builder/SuccessOutcomeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace Ether.Outcomes.Builder
{
/// <summary>
/// Uses the builder pattern to create a fluent interface for success scenarios.
/// </summary>
public class SuccessOutcomeBuilder<T> : OutcomeResult<T>
{
internal SuccessOutcomeBuilder(bool success) : base(success)
Expand Down Expand Up @@ -35,7 +38,7 @@ public SuccessOutcomeBuilder<T> WithMessage(IEnumerable<string> messages)
}

/// <summary>
/// Sets the value for a success outcome. The outcome object is really just a wrapper for the value.
/// Sets the value for a success outcome. The outcome object is just a wrapper for the value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
Expand Down
5 changes: 5 additions & 0 deletions Outcomes/OutcomeResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

namespace Ether.Outcomes
{
/// <summary>
/// OutcomeResult is a generic wrapper. It allows you to wrap your method responses in metadata, eliminating plumbing code.
/// OutcomeResults are generated by calling Outcomes.Success() or Outcomes.Failure()
/// </summary>
/// <typeparam name="T">The type that this OutcomeResult wraps.</typeparam>
public class OutcomeResult<T> : IOutcome<T>
{
public bool Success { get; protected set; }
Expand Down
4 changes: 2 additions & 2 deletions Outcomes/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
Binary file added nuGet/Ether.Outcomes.1.0.5.nupkg
Binary file not shown.
Binary file added nuGet/Ether.Outcomes.1.1.0.nupkg
Binary file not shown.

0 comments on commit dcd4914

Please sign in to comment.