#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2014 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
#if UNITTEST
using System;
using System.ComponentModel;
using NUnit.Framework;
using NMock;
namespace Nuclex.Support {
/// Unit tests for observable class
[TestFixture]
internal class ObservableTest {
#region class TestObservable
/// Example class on which unit test generates change notifications
public class TestObservable : Observable {
/// Triggers the property changed event for the specified property
///
/// Name of the property that will be reported as changed
///
public void FirePropertyChanged(string propertyName) {
OnPropertyChanged(propertyName);
}
/// Fires the property changed event for the 'SomePropety' property
public void FireSomePropertyChanged() {
OnPropertyChanged(() => SomeProperty);
}
/// Example property that will be reported to have changed
public int SomeProperty { get; set; }
}
#endregion // class TestObservable
#region class MockedSubscriber
/// Mocked change notification subscriber
public class MockedSubscriber {
/// Called when the value of a property has changed
/// Object of which a property has changed
/// Contains the name of the changed property
public void PropertyChanged(object sender, PropertyChangedEventArgs arguments) {
this.wasNotified = true;
this.changedPropertyName = arguments.PropertyName;
}
/// Whether the subscriber was notified of a property change
public bool WasNotified {
get { return this.wasNotified; }
}
///
/// Checks whether a change notification for the specified property was received
///
/// Name of the property that will be checked for
///
/// True if a change notification for the specified property was received
///
public bool WasNotifiedOfChangeTo(string propertyName) {
if(!this.wasNotified) {
return false;
}
if(string.IsNullOrEmpty(propertyName)) {
return string.IsNullOrEmpty(this.changedPropertyName);
}
return (propertyName == this.changedPropertyName);
}
/// Whether a change notification was received
private bool wasNotified;
/// Name of the property for which a change notification was received
private string changedPropertyName;
}
#endregion // class MockedSubscriber
/// Called before each unit test is run
[SetUp]
public void Setup() {
this.testObservable = new TestObservable();
this.subscriber = new MockedSubscriber();
this.testObservable.PropertyChanged += this.subscriber.PropertyChanged;
}
///
/// Verifies that the name of the changed property can be specified manually
/// when triggering the PropertyChanged event
///
[Test]
public void PropertyNameCanBeSpecifiedManually() {
this.testObservable.FirePropertyChanged("SomeProperty");
Assert.IsTrue(this.subscriber.WasNotifiedOfChangeTo("SomeProperty"));
}
#if DEBUG // The check is conditionally performed only in debug mode
///
/// Verifies that specifying the name of a property that doesn't exist
/// causes an ArgumentException to be thrown
///
[Test]
public void SpecifyingInvalidPropertyNameThrowsArgumentException() {
Assert.Throws(
delegate() { this.testObservable.FirePropertyChanged("DoesntExist"); }
);
}
#endif
///
/// Verifies that the observable is capable of deducing the name of the property
/// from a lambda expression
///
[Test]
public void PropertyNameCanBeDeducedFromLambdaExpression() {
this.testObservable.FireSomePropertyChanged();
Assert.IsTrue(this.subscriber.WasNotifiedOfChangeTo("SomeProperty"));
}
///
/// Verifies that change notifications for all properties of a type can
/// be generated
///
[Test]
public void WildcardChangeNotificationsCanBeSent() {
this.testObservable.FirePropertyChanged(string.Empty);
Assert.IsTrue(this.subscriber.WasNotifiedOfChangeTo(null));
this.testObservable.FirePropertyChanged(null);
Assert.IsTrue(this.subscriber.WasNotifiedOfChangeTo(string.Empty));
}
/// Observable object being tested
private TestObservable testObservable;
/// Subscriber to the observable object being tested
private MockedSubscriber subscriber;
}
} // namespace Nuclex.Support
#endif // UNITTEST