Skip to content

Commit f60b49f

Browse files
authored
Exposes the IMonitor object to extensions methods. (#2010)
1 parent 70a0793 commit f60b49f

File tree

8 files changed

+35
-12
lines changed

8 files changed

+35
-12
lines changed

Src/FluentAssertions/Events/EventAssertions.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ public class EventAssertions<T> : ReferenceTypeAssertions<T, EventAssertions<T>>
1616
{
1717
private const string PropertyChangedEventName = "PropertyChanged";
1818

19-
private readonly IMonitor<T> monitor;
20-
2119
protected internal EventAssertions(IMonitor<T> monitor)
2220
: base(monitor.Subject)
2321
{
24-
this.monitor = monitor;
22+
this.Monitor = monitor;
2523
}
24+
25+
/// <summary>
26+
/// Gets the <see cref="IMonitor{T}"/> which is being asserted.
27+
/// </summary>
28+
public IMonitor<T> Monitor { get; }
2629

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

5053
return recording;
@@ -65,12 +68,12 @@ public IEventRecording Raise(string eventName, string because = "", params objec
6568
/// </param>
6669
public void NotRaise(string eventName, string because = "", params object[] becauseArgs)
6770
{
68-
IEventRecording events = monitor.GetRecordingFor(eventName);
71+
IEventRecording events = Monitor.GetRecordingFor(eventName);
6972
if (events.Any())
7073
{
7174
Execute.Assertion
7275
.BecauseOf(because, becauseArgs)
73-
.FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", monitor.Subject, eventName);
76+
.FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", Monitor.Subject, eventName);
7477
}
7578
}
7679

@@ -93,14 +96,14 @@ public IEventRecording RaisePropertyChangeFor(Expression<Func<T, object>> proper
9396
{
9497
string propertyName = propertyExpression?.GetPropertyInfo().Name;
9598

96-
IEventRecording recording = monitor.GetRecordingFor(PropertyChangedEventName);
99+
IEventRecording recording = Monitor.GetRecordingFor(PropertyChangedEventName);
97100

98101
if (!recording.Any())
99102
{
100103
Execute.Assertion
101104
.BecauseOf(because, becauseArgs)
102105
.FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.",
103-
monitor.Subject, PropertyChangedEventName, propertyName);
106+
Monitor.Subject, PropertyChangedEventName, propertyName);
104107
}
105108

106109
var actualPropertyNames = recording
@@ -113,7 +116,7 @@ public IEventRecording RaisePropertyChangeFor(Expression<Func<T, object>> proper
113116
.ForCondition(actualPropertyNames.Contains(propertyName))
114117
.BecauseOf(because, becauseArgs)
115118
.FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it was only raised for {3}.",
116-
monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames);
119+
Monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames);
117120

118121
return recording;
119122
}
@@ -134,7 +137,7 @@ public IEventRecording RaisePropertyChangeFor(Expression<Func<T, object>> proper
134137
public void NotRaisePropertyChangeFor(Expression<Func<T, object>> propertyExpression,
135138
string because = "", params object[] becauseArgs)
136139
{
137-
IEventRecording recording = monitor.GetRecordingFor(PropertyChangedEventName);
140+
IEventRecording recording = Monitor.GetRecordingFor(PropertyChangedEventName);
138141

139142
string propertyName = propertyExpression.GetPropertyInfo().Name;
140143

@@ -143,7 +146,7 @@ public void NotRaisePropertyChangeFor(Expression<Func<T, object>> propertyExpres
143146
Execute.Assertion
144147
.BecauseOf(because, becauseArgs)
145148
.FailWith("Did not expect object {0} to raise the {1} event for property {2}{reason}, but it did.",
146-
monitor.Subject, PropertyChangedEventName, propertyName);
149+
Monitor.Subject, PropertyChangedEventName, propertyName);
147150
}
148151
}
149152

Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
12581258
{
12591259
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
12601260
protected override string Identifier { get; }
1261+
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
12611262
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
12621263
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
12631264
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }

Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ namespace FluentAssertions.Events
12711271
{
12721272
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
12731273
protected override string Identifier { get; }
1274+
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
12741275
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
12751276
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
12761277
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }

Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
12581258
{
12591259
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
12601260
protected override string Identifier { get; }
1261+
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
12611262
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
12621263
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
12631264
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }

Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
12581258
{
12591259
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
12601260
protected override string Identifier { get; }
1261+
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
12611262
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
12621263
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
12631264
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }

Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ namespace FluentAssertions.Events
12581258
{
12591259
protected EventAssertions(FluentAssertions.Events.IMonitor<T> monitor) { }
12601260
protected override string Identifier { get; }
1261+
public FluentAssertions.Events.IMonitor<T> Monitor { get; }
12611262
public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { }
12621263
public void NotRaisePropertyChangeFor(System.Linq.Expressions.Expression<System.Func<T, object>> propertyExpression, string because = "", params object[] becauseArgs) { }
12631264
public FluentAssertions.Events.IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { }

Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,20 @@ public void When_monitoring_an_object_with_invalid_property_expression_it_should
629629
act.Should().Throw<ArgumentException>()
630630
.WithParameterName("expression");
631631
}
632+
633+
[Fact]
634+
public void Event_assertions_should_expose_the_monitor()
635+
{
636+
// Arrange
637+
var subject = new EventRaisingClass();
638+
using var monitor = subject.Monitor();
639+
640+
// Act
641+
var exposedMonitor = monitor.Should().Monitor;
642+
643+
// Assert
644+
((object)exposedMonitor).Should().BeSameAs(monitor);
645+
}
632646
}
633647

634648
public class Metadata

docs/_pages/releases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ sidebar:
1414
* Added `NotCompleteWithinAsync` for assertions on `Task` - [#1967](https://github.com/fluentassertions/fluentassertions/pull/1967)
1515
* Added `CompleteWithinAsync` and `NotCompleteWithinAsync` for non-generic `TaskCompletionSource` (.NET 6 and above) - [#1961](https://github.com/fluentassertions/fluentassertions/pull/1961)
1616
* 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)
17+
* Added a `Monitor` to `EventAssertions` to enable writing extension methods for event assertions. - [#2008](https://github.com/fluentassertions/fluentassertions/pull/2008)
1718
* Updated exception messages to provide suggestions when incorrectly using `Equals()` - [#2006](https://github.com/fluentassertions/fluentassertions/pull/2006)
1819

1920
### Fixes

0 commit comments

Comments
 (0)