/// <summary> /// Asserts that at least one occurrence of the event had arguments matching all predicates. /// </summary> public static IEventRecorder WithArgs <T>(this IEventRecorder eventRecorder, params Expression <Func <T, bool> >[] predicates) { Func <T, bool>[] compiledPredicates = predicates.Select(p => p?.Compile()).ToArray(); if (!eventRecorder.First().Parameters.OfType <T>().Any()) { throw new ArgumentException("No argument of event " + eventRecorder.EventName + " is of type <" + typeof(T) + ">."); } bool expected = eventRecorder.Any(recordedEvent => { T[] parameters = recordedEvent.Parameters.OfType <T>().ToArray(); int parametersToCheck = Math.Min(parameters.Length, predicates.Length); bool isMatch = true; for (int i = 0; i < parametersToCheck && isMatch; i++) { isMatch = compiledPredicates[i]?.Invoke(parameters[i]) ?? true; } return(isMatch); }); if (!expected) { Execute.Assertion .FailWith("Expected at least one event with arguments matching {0}, but found none.", string.Join(" | ", predicates.Where(p => p != null).Select(p => p.Body.ToString()))); } return(eventRecorder); }
/// <summary> /// Asserts that an object has not raised a particular event. /// </summary> /// <param name="eventName"> /// The name of the event that should not be raised. /// </param> /// <param name="because"> /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not /// start with the word <i>because</i>, it is prepended to the message. /// </param> /// <param name="becauseArgs"> /// Zero or more values to use for filling in any <see cref="string.Format(string,object[])"/> compatible placeholders. /// </param> /// <remarks> /// You must call <see cref="MonitorEvents"/> on the same object prior to this call so that Fluent Assertions can /// subscribe for the events of the object. /// </remarks> public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { IEventRecorder eventRecorder = monitor.GetEventRecorder(eventName); if (eventRecorder.Any()) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", monitor.Subject, eventName); } }
/// <summary> /// Asserts that an object has not raised a particular event. /// </summary> /// <param name="eventSource">The object exposing the event.</param> /// <param name="eventName"> /// The name of the event that should not be raised. /// </param> /// <param name="because"> /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not /// start with the word <i>because</i>, it is prepended to the message. /// </param> /// <param name="becauseArgs"> /// Zero or more values to use for filling in any <see cref="string.Format(string,object[])"/> compatible placeholders. /// </param> /// <remarks> /// You must call <see cref="MonitorEvents"/> on the same object prior to this call so that Fluent Assertions can /// subscribe for the events of the object. /// </remarks> public static void ShouldNotRaise( this object eventSource, string eventName, string because, params object[] becauseArgs) { IEventRecorder eventRecorder = EventMonitor.Get(eventSource).GetEventRecorder(eventName); if (eventRecorder.Any()) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected object {0} to not raise event {1}{reason}, but it did.", eventSource, eventName); } }
/// <summary> /// Asserts that an object has not raised the <see cref="INotifyPropertyChanged.PropertyChanged"/> event for a particular property. /// </summary> /// <param name="propertyExpression"> /// A lambda expression referring to the property for which the property changed event should have been raised. /// </param> /// <param name="because"> /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not /// start with the word <i>because</i>, it is prepended to the message. /// </param> /// <param name="becauseArgs"> /// Zero or more values to use for filling in any <see cref="string.Format(string,object[])"/> compatible placeholders. /// </param> /// <remarks> /// You must call <see cref="AssertionExtensions.Monitor"/> on the same object prior to this call so that Fluent Assertions can /// subscribe for the events of the object. /// </remarks> public void NotRaisePropertyChangeFor(Expression <Func <T, object> > propertyExpression, string because = "", params object[] becauseArgs) { IEventRecorder eventRecorder = monitor.GetEventRecorder(PropertyChangedEventName); string propertyName = propertyExpression.GetPropertyInfo().Name; if (eventRecorder.Any(@event => GetAffectedPropertyName(@event) == propertyName)) { 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); } }
/// <summary> /// Asserts that an object has raised the <see cref="INotifyPropertyChanged.PropertyChanged"/> event for a particular property. /// </summary> /// <param name="propertyExpression"> /// A lambda expression referring to the property for which the property changed event should have been raised, or /// <c>null</c> to refer to all properties. /// </param> /// <param name="because"> /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not /// start with the word <i>because</i>, it is prepended to the message. /// </param> /// <param name="becauseArgs"> /// Zero or more values to use for filling in any <see cref="string.Format(string,object[])"/> compatible placeholders. /// </param> /// <remarks> /// You must call <see cref="AssertionExtensions.Monitor"/> on the same object prior to this call so that Fluent Assertions can /// subscribe for the events of the object. /// </remarks> public IEventRecorder RaisePropertyChangeFor(Expression <Func <T, object> > propertyExpression, string because = "", params object[] becauseArgs) { IEventRecorder eventRecorder = monitor.GetEventRecorder(PropertyChangedEventName); string propertyName = propertyExpression?.GetPropertyInfo().Name; if (!eventRecorder.Any()) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it did not.", monitor.Subject, PropertyChangedEventName, propertyName); } return(eventRecorder.WithArgs <PropertyChangedEventArgs>(args => args.PropertyName == propertyName)); }
/// <summary> /// Asserts that at least one occurrence of the event had an <see cref="EventArgs"/> object matching a predicate. /// </summary> public static IEventRecorder WithArgs <T>(this IEventRecorder eventRecorder, Expression <Func <T, bool> > predicate) where T : EventArgs { Func <T, bool> compiledPredicate = predicate.Compile(); if (!eventRecorder.First().Parameters.OfType <T>().Any()) { throw new ArgumentException("No argument of event " + eventRecorder.EventName + " is of type <" + typeof(T) + ">."); } if (!eventRecorder.Any(@event => compiledPredicate(@event.Parameters.OfType <T>().Single()))) { Execute.Assertion .FailWith("Expected at least one event with arguments matching {0}, but found none.", predicate.Body); } return(eventRecorder); }
/// <summary> /// Asserts that an object has raised the <see cref="INotifyPropertyChanged.PropertyChanged"/> event for a particular property. /// </summary> /// <param name="eventSource">The object exposing the event.</param> /// <param name="propertyExpression"> /// A lambda expression referring to the property for which the property changed event should have been raised, or /// <c>null</c> to refer to all properties. /// </param> /// <param name="because"> /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not /// start with the word <i>because</i>, it is prepended to the message. /// </param> /// <param name="becauseArgs"> /// Zero or more values to use for filling in any <see cref="string.Format(string,object[])"/> compatible placeholders. /// </param> /// <remarks> /// You must call <see cref="AssertionExtensions.MonitorEvents"/> on the same object prior to this call so that Fluent Assertions can /// subscribe for the events of the object. /// </remarks> public static IEventRecorder ShouldRaisePropertyChangeFor <T>( this T eventSource, Expression <Func <T, object> > propertyExpression, string because, params object[] becauseArgs) { IEventRecorder eventRecorder = EventMonitor.Get(eventSource).GetEventRecorder(PropertyChangedEventName); string propertyName = (propertyExpression != null) ? propertyExpression.GetPropertyInfo().Name : null; if (!eventRecorder.Any()) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it did not.", eventSource, PropertyChangedEventName, propertyName); } return(eventRecorder.WithArgs <PropertyChangedEventArgs>(args => args.PropertyName == propertyName)); }