Skip to content

Commit

Permalink
Applied patch for ordered AAA syntax from Kenneth Xu (part two - enha…
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Ländle committed Mar 7, 2012
1 parent 011cd9c commit 4087bed
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 32 deletions.
93 changes: 93 additions & 0 deletions Rhino.Mocks.Tests/OrderingExpectationTest.cs
@@ -0,0 +1,93 @@
using Rhino.Mocks.Exceptions;
using Xunit;

namespace Rhino.Mocks.Tests
{
public class OrderingExpectationTest
{
public interface IBefore { void MethodBefore(); }

public interface IAfter { void MethodAfter(); }

private readonly IBefore mockBefore;
private readonly IAfter mockAfter;

public OrderingExpectationTest()
{
this.mockBefore = MockRepository.GenerateStub<IBefore>();
this.mockAfter = MockRepository.GenerateStub<IAfter>();
}

[Fact]
public void Before_and_After_succeeds_if_all_beforeCalls_occurred_before_afterCalls()
{
this.AllBeforeThenAllAfter();

this.mockBefore.AssertWasCalled(b => b.MethodBefore())
.Before(this.mockAfter.AssertWasCalled(a => a.MethodAfter()));

this.mockAfter.AssertWasCalled(a => a.MethodAfter())
.After(this.mockBefore.AssertWasCalled(b => b.MethodBefore()));
}

[Fact]
public void Before_and_After_succeeds_if_before_occurred_before_after()
{
this.BeforeAfterInterlaced();

this.mockBefore.AssertWasCalled(b => b.MethodBefore()).First()
.Before(this.mockAfter.AssertWasCalled(a => a.MethodAfter()).First())
.Before(this.mockBefore.AssertWasCalled(b => b.MethodBefore()).Last());

this.mockAfter.AssertWasCalled(a => a.MethodAfter()).Last()
.After(this.mockBefore.AssertWasCalled(b => b.MethodBefore()).Last())
.After(this.mockAfter.AssertWasCalled(a => a.MethodAfter()).First());
}

[Fact]
public void Before_and_After_chokes_if_one_of_beforeCalls_occurred_after_any_of_afterCalls()
{
this.BeforeAfterInterlaced();

Throws.Exception<ExpectationViolationException>(
() => this.mockBefore.AssertWasCalled(b => b.MethodBefore())
.Before(this.mockAfter.AssertWasCalled(a => a.MethodAfter())));

Throws.Exception<ExpectationViolationException>(
() => this.mockAfter.AssertWasCalled(a => a.MethodAfter())
.After(this.mockBefore.AssertWasCalled(b => b.MethodBefore())));
}

[Fact]
public void Before_and_After_chokes_if_before_occurred_after_after()
{
this.BeforeAfterInterlaced();

Throws.Exception<ExpectationViolationException>(
() => this.mockBefore.AssertWasCalled(b => b.MethodBefore()).Last()
.Before(this.mockAfter.AssertWasCalled(a => a.MethodAfter()).First()));

Throws.Exception<ExpectationViolationException>(
() => this.mockAfter.AssertWasCalled(a => a.MethodAfter()).First()
.After(this.mockBefore.AssertWasCalled(b => b.MethodBefore()).Last()));
}

private void AllBeforeThenAllAfter()
{
this.mockBefore.MethodBefore();
this.mockBefore.MethodBefore();
this.mockAfter.MethodAfter();
this.mockAfter.MethodAfter();
this.mockAfter.MethodAfter();
}

private void BeforeAfterInterlaced()
{
this.mockBefore.MethodBefore();
this.mockAfter.MethodAfter();
this.mockBefore.MethodBefore();
this.mockAfter.MethodAfter();
this.mockAfter.MethodAfter();
}
}
}
1 change: 1 addition & 0 deletions Rhino.Mocks.Tests/Rhino.Mocks.Tests.csproj
Expand Up @@ -170,6 +170,7 @@
<Compile Include="FieldsProblem\FieldProblem_Andreas2.cs" /> <Compile Include="FieldsProblem\FieldProblem_Andreas2.cs" />
<Compile Include="FieldsProblem\FieldProblem_Norbi.cs" /> <Compile Include="FieldsProblem\FieldProblem_Norbi.cs" />
<Compile Include="FieldsProblem\FieldProblem_Ted.cs" /> <Compile Include="FieldsProblem\FieldProblem_Ted.cs" />
<Compile Include="OrderingExpectationTest.cs" />
<Compile Include="PartialStubTestsAAA.cs" /> <Compile Include="PartialStubTestsAAA.cs" />
<Compile Include="PartialStubTests.cs" /> <Compile Include="PartialStubTests.cs" />
<Compile Include="FieldsProblem\FieldProblem_Alex.cs" /> <Compile Include="FieldsProblem\FieldProblem_Alex.cs" />
Expand Down
118 changes: 86 additions & 32 deletions Rhino.Mocks/RhinoMocksExtensions.cs
Expand Up @@ -453,47 +453,101 @@ public static void Raise<TEventSource>(this TEventSource mockObject, Action<TEve


/// <summary> /// <summary>
/// Assert that all calls specified by <paramref name="beforeCalls"/> /// Assert that all calls specified by <paramref name="beforeCalls"/>
/// happened before all calls specified by <paramref name="afterCalls"/> /// occurred before all calls specified by <paramref name="afterCalls"/>
/// </summary> /// </summary>
/// <param name="beforeCalls"> /// <param name="beforeCalls">
/// Calls that happens before <paramref name="afterCalls"/> /// Calls that happens before <paramref name="afterCalls"/>
/// </param> /// </param>
/// <param name="afterCalls"> /// <param name="afterCalls">
/// Calls that happens after <paramref name="beforeCalls"/> /// Calls that happens after <paramref name="beforeCalls"/>
/// </param> /// </param>
public static void Before(this IList<CallRecord> beforeCalls, IList<CallRecord> afterCalls) public static IList<CallRecord> Before(this IList<CallRecord> beforeCalls, IList<CallRecord> afterCalls)
{ {
long maxBefore = long.MinValue; Ordered(Last(beforeCalls), First(afterCalls));
CallRecord latestBeforeCall = null; return afterCalls;
foreach (var call in beforeCalls) }
{
var sequence = call.Sequence;
if (sequence > maxBefore)
{
maxBefore = sequence;
latestBeforeCall = call;
}
}


long minAfter = long.MaxValue; /// <summary>
CallRecord earliestAfterCall = null; /// Assert that all calls specified by <paramref name="afterCalls"/>
foreach (var call in afterCalls) /// occurred after all calls specified by <paramref name="beforeCalls"/>
{ /// </summary>
var sequence = call.Sequence; /// <param name="afterCalls">
if (sequence < minAfter) /// Calls that happens after <paramref name="beforeCalls"/>
{ /// </param>
minAfter = sequence; /// <param name="beforeCalls">
earliestAfterCall = call; /// Calls that happens before <paramref name="afterCalls"/>
} /// </param>
} public static IList<CallRecord> After(this IList<CallRecord> afterCalls, IList<CallRecord> beforeCalls)
if (maxBefore>minAfter) {
{ Ordered(Last(beforeCalls), First(afterCalls));
throw new ExpectationViolationException( return beforeCalls;
"Expected that calls to " + latestBeforeCall.Method + }
" occurs before " + earliestAfterCall.Method +
", but the expectation is not satisfied."); /// <summary>
} /// Assert that the call specified by <paramref name="before"/>
} /// occurred before the call specified by <paramref name="after"/>
/// </summary>
/// <param name="before">
/// Call that occurred before <paramref name="after"/>
/// </param>
/// <param name="after">
/// Call that occurred after <paramref name="before"/>
/// </param>
public static CallRecord Before(this CallRecord before, CallRecord after)
{
Ordered(before, after);
return after;
}

/// <summary>
/// Assert that the call specified by <paramref name="after"/>
/// occurred after the call specified by <paramref name="before"/>
/// </summary>
/// <param name="after">
/// Call that occurred after <paramref name="before"/>
/// </param>
/// <param name="before">
/// Call that occurred before <paramref name="after"/>
/// </param>
public static CallRecord After(this CallRecord after, CallRecord before)
{
Ordered(before, after);
return before;
}

/// <summary>
/// Returns the last executed call in the <paramref name="callRecords"/>.
/// </summary>
/// <param name="callRecords">
/// A list of call records ordered by the time they were executed.
/// </param>
/// <returns>The last call executed in <paramref name="callRecords"/></returns>
public static CallRecord Last(this IList<CallRecord> callRecords)
{
return callRecords[callRecords.Count - 1];
}

/// <summary>
/// Returns the first executed call in the <paramref name="callRecords"/>.
/// </summary>
/// <param name="callRecords">
/// A list of call records ordered by the time they were executed.
/// </param>
/// <returns>The first call executed in <paramref name="callRecords"/></returns>
public static CallRecord First(this IList<CallRecord> callRecords)
{
return callRecords[0];
}
private static void Ordered(CallRecord before, CallRecord after)
{
if (before.Sequence > after.Sequence)
{
throw new ExpectationViolationException(
"Expected that call " + before.Method +
" occurs before call " + after.Method +
", but the expectation is not satisfied.");
}
}


/// <summary>TODO: Make this better! It currently breaks down when mocking classes or /// <summary>TODO: Make this better! It currently breaks down when mocking classes or
/// ABC's that call other virtual methods which are getting intercepted too. I wish /// ABC's that call other virtual methods which are getting intercepted too. I wish
Expand Down

0 comments on commit 4087bed

Please sign in to comment.