view SilverlightValidation/SilverlightValidation.Tests/TestSupport/NotifyPropertyChangedEventWatcher.cs @ 97:1adc1ae981ea

Tests added to SilverlightValidation.Tests
author stevenhollidge <stevenhollidge@hotmail.com>
date Sat, 05 May 2012 16:39:00 +0100
parents
children
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq.Expressions;

namespace SilverlightValidation.Tests.TestSupport
{
    /// <summary>
    ///   A helper class used by NotifyPropertyChangedAssertHelper to monitor PropertyChangedEvent notifications.
    /// </summary>
    public class NotifyPropertyChangedEventWatcher : Disposable
    {
        private readonly Dictionary<string, int> _raisedCounts = new Dictionary<string, int>();

        // A reference to the instance of the class implementing INotifyPropertyChanged
        private INotifyPropertyChanged _model;

        /// <summary>
        ///   Initializes a new instance of the <see cref = "NotifyPropertyChangedEventWatcher" /> class.
        /// </summary>
        /// <param name = "model">The model.</param>
        public NotifyPropertyChangedEventWatcher(INotifyPropertyChanged model)
        {
            if (model == null) throw new ArgumentNullException("model");

            _model = model;
            _model.PropertyChanged += OnPropertyChanged;
        }

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"),
         SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public int GetRaisedCount<T>(Expression<Func<T>> propertyExpression)
        {
            return GetRaisedCount(PropertySupport.ExtractPropertyName(propertyExpression));
        }

        public int GetRaisedCount(string propertyName)
        {
            propertyName = string.IsNullOrEmpty(propertyName) ? string.Empty : propertyName;

            PropertySupport.VerifyPropertyName(_model, propertyName);

            return _raisedCounts.ContainsKey(propertyName) ? _raisedCounts[propertyName] : 0;
        }

        private void RecordPropertyChanged(string propertyName)
        {
            if (_raisedCounts.ContainsKey(propertyName))
            {
                _raisedCounts[propertyName]++;
            }
            else
            {
                _raisedCounts[propertyName] = 1;
            }
        }

        /// <summary>
        ///   The OnPropertyChanged event handler.
        /// </summary>
        /// <remarks>
        ///   Records how many times the monitored property name has changed.
        /// </remarks>
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
        {
            // If PropertyName is null or string.Empty then it's the 'all properties' changed event.
            RecordPropertyChanged(string.IsNullOrEmpty(eventArgs.PropertyName) ? string.Empty : eventArgs.PropertyName);
        }

        /// <summary>
        ///   Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name = "disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (null != _model)
            {
                var model = _model;
                _model = null;
                model.PropertyChanged -= OnPropertyChanged;
            }
        }

        /// <summary>
        ///   Traces the event counts.
        /// </summary>
        [Conditional("DEBUG")]
        public void TraceEventCounts()
        {
            foreach (var pair in _raisedCounts)
            {
                string name = string.IsNullOrEmpty(pair.Key) ? "all properties" : pair.Key;
                int value = pair.Value;

                Debug.WriteLine(string.Format(
                    CultureInfo.InvariantCulture, @"Property '{0}' raised {1} times.", name, value));
            }
        }
    }
}