Skip to content

Commit

Permalink
Exposes the IMonitor object to extensions methods. (#2010)
Browse files Browse the repository at this point in the history
  • Loading branch information
A-Kjeldgaard committed Oct 14, 2022
1 parent 70a0793 commit f60b49f
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 12 deletions.
27 changes: 15 additions & 12 deletions Src/FluentAssertions/Events/EventAssertions.cs
Expand Up @@ -16,13 +16,16 @@ public class EventAssertions<T> : ReferenceTypeAssertions<T, EventAssertions<T>>
{
private const string PropertyChangedEventName = "PropertyChanged";

private readonly IMonitor<T> monitor;

protected internal EventAssertions(IMonitor<T> monitor)
: base(monitor.Subject)
{
this.monitor = monitor;
this.Monitor = monitor;
}

/// <summary>
/// Gets the <see cref="IMonitor{T}"/> which is being asserted.
/// </summary>
public IMonitor<T> Monitor { get; }

/// <summary>
/// Asserts that an object has raised a particular event at least once.
Expand All @@ -39,12 +42,12 @@ protected internal EventAssertions(IMonitor<T> monitor)
/// </param>
public IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs)
{
IEventRecording recording = monitor.GetRecordingFor(eventName);
IEventRecording recording = Monitor.GetRecordingFor(eventName);
if (!recording.Any())
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Expected object {0} to raise event {1}{reason}, but it did not.", monitor.Subject, eventName);
.FailWith("Expected object {0} to raise event {1}{reason}, but it did not.", Monitor.Subject, eventName);
}

return recording;
Expand All @@ -65,12 +68,12 @@ public IEventRecording Raise(string eventName, string because = "", params objec
/// </param>
public void NotRaise(string eventName, string because = "", params object[] becauseArgs)
{
IEventRecording events = monitor.GetRecordingFor(eventName);
IEventRecording events = Monitor.GetRecordingFor(eventName);
if (events.Any())
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", monitor.Subject, eventName);
.FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", Monitor.Subject, eventName);
}
}

Expand All @@ -93,14 +96,14 @@ public void NotRaise(string eventName, string because = "", params object[] beca
{
string propertyName = propertyExpression?.GetPropertyInfo().Name;

IEventRecording recording = monitor.GetRecordingFor(PropertyChangedEventName);
IEventRecording recording = Monitor.GetRecordingFor(PropertyChangedEventName);

if (!recording.Any())
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.",
monitor.Subject, PropertyChangedEventName, propertyName);
Monitor.Subject, PropertyChangedEventName, propertyName);
}

var actualPropertyNames = recording
Expand All @@ -113,7 +116,7 @@ public void NotRaise(string eventName, string because = "", params object[] beca
.ForCondition(actualPropertyNames.Contains(propertyName))
.BecauseOf(because, becauseArgs)
.FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it was only raised for {3}.",
monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames);
Monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames);

return recording;
}
Expand All @@ -134,7 +137,7 @@ public void NotRaise(string eventName, string because = "", params object[] beca
public void NotRaisePropertyChangeFor(Expression<Func<T, object>> propertyExpression,
string because = "", params object[] becauseArgs)
{
IEventRecording recording = monitor.GetRecordingFor(PropertyChangedEventName);
IEventRecording recording = Monitor.GetRecordingFor(PropertyChangedEventName);

string propertyName = propertyExpression.GetPropertyInfo().Name;

Expand All @@ -143,7 +146,7 @@ public void NotRaise(string eventName, string because = "", params object[] beca
Execute.Assertion
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect object {0} to raise the {1} event for property {2}{reason}, but it did.",
monitor.Subject, PropertyChangedEventName, propertyName);
Monitor.Subject, PropertyChangedEventName, propertyName);
}
}

Expand Down
Expand Up @@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
{
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
protected override string Identifier { get; }
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -1271,6 +1271,7 @@ namespace FluentAssertions.Events
{
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
protected override string Identifier { get; }
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
{
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
protected override string Identifier { get; }
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
{
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
protected override string Identifier { get; }
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
{
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
protected override string Identifier { get; }
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }
Expand Down
14 changes: 14 additions & 0 deletions Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs
Expand Up @@ -629,6 +629,20 @@ public void When_monitoring_an_object_with_invalid_property_expression_it_should
act.Should().Throw<ArgumentException>()
.WithParameterName("expression");
}

[Fact]
public void Event_assertions_should_expose_the_monitor()
{
// Arrange
var subject = new EventRaisingClass();
using var monitor = subject.Monitor();

// Act
var exposedMonitor = monitor.Should().Monitor;

// Assert
((object)exposedMonitor).Should().BeSameAs(monitor);
}
}

public class Metadata
Expand Down
1 change: 1 addition & 0 deletions docs/_pages/releases.md
Expand Up @@ -14,6 +14,7 @@ sidebar:
* Added `NotCompleteWithinAsync` for assertions on `Task` - [#1967](https://github.com/fluentassertions/fluentassertions/pull/1967)
* Added `CompleteWithinAsync` and `NotCompleteWithinAsync` for non-generic `TaskCompletionSource` (.NET 6 and above) - [#1961](https://github.com/fluentassertions/fluentassertions/pull/1961)
* Added a `ParentType` to `IObjectInfo` to help determining the parent in a call to `Using`/`When` constructs - [#1950](https://github.com/fluentassertions/fluentassertions/pull/1950)
* Added a `Monitor` to `EventAssertions` to enable writing extension methods for event assertions. - [#2008](https://github.com/fluentassertions/fluentassertions/pull/2008)
* Updated exception messages to provide suggestions when incorrectly using `Equals()` - [#2006](https://github.com/fluentassertions/fluentassertions/pull/2006)

### Fixes
Expand Down

0 comments on commit f60b49f

Please sign in to comment.