PageRenderTime 17ms CodeModel.GetById 9ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NUnit/framework/Constraints/PropertyConstraint.cs

#
C# | 168 lines | 82 code | 22 blank | 64 comment | 14 complexity | 1bb7f2e3989fd74eb02854f10a66f8d6 MD5 | raw file
  1// ****************************************************************
  2// Copyright 2007, Charlie Poole
  3// This is free software licensed under the NUnit license. You may
  4// obtain a copy of the license at http://nunit.org
  5// ****************************************************************
  6
  7using System;
  8using System.Collections;
  9using System.Reflection;
 10
 11namespace NUnit.Framework.Constraints
 12{
 13    /// <summary>
 14    /// PropertyExistsConstraint tests that a named property
 15    /// exists on the object provided through Match.
 16    /// 
 17    /// Originally, PropertyConstraint provided this feature
 18    /// in addition to making optional tests on the vaue
 19    /// of the property. The two constraints are now separate.
 20    /// </summary>
 21    public class PropertyExistsConstraint : Constraint
 22    {
 23        private string name;
 24
 25        Type actualType;
 26
 27        /// <summary>
 28        /// Initializes a new instance of the <see cref="T:PropertyExistConstraint"/> class.
 29        /// </summary>
 30        /// <param name="name">The name of the property.</param>
 31        public PropertyExistsConstraint(string name) : base(name)
 32        {
 33            this.name = name;
 34        }
 35
 36        /// <summary>
 37        /// Test whether the property exists for a given object
 38        /// </summary>
 39        /// <param name="actual">The object to be tested</param>
 40        /// <returns>True for success, false for failure</returns>
 41        public override bool Matches(object actual)
 42        {
 43            this.actual = actual;
 44            
 45            if (actual == null)
 46                throw new ArgumentNullException("actual");
 47
 48            this.actualType = actual as Type;
 49            if (actualType == null)
 50                actualType = actual.GetType();
 51
 52            PropertyInfo property = actualType.GetProperty(name,
 53                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
 54
 55            return property != null;
 56        }
 57
 58        /// <summary>
 59        /// Write the constraint description to a MessageWriter
 60        /// </summary>
 61        /// <param name="writer">The writer on which the description is displayed</param>
 62        public override void WriteDescriptionTo(MessageWriter writer)
 63        {
 64            writer.Write("property " + name);
 65        }
 66
 67        /// <summary>
 68        /// Write the actual value for a failing constraint test to a
 69        /// MessageWriter.
 70        /// </summary>
 71        /// <param name="writer">The writer on which the actual value is displayed</param>
 72        public override void WriteActualValueTo(MessageWriter writer)
 73        {
 74            writer.WriteActualValue(actualType);
 75        }
 76
 77        /// <summary>
 78        /// Returns the string representation of the constraint.
 79        /// </summary>
 80        /// <returns></returns>
 81        protected override string GetStringRepresentation()
 82        {
 83            return string.Format("<propertyexists {0}>", name);
 84        }
 85    }
 86
 87	/// <summary>
 88	/// PropertyConstraint extracts a named property and uses
 89    /// its value as the actual value for a chained constraint.
 90	/// </summary>
 91	public class PropertyConstraint : PrefixConstraint
 92	{
 93		private string name;
 94		private object propValue;
 95
 96        /// <summary>
 97        /// Initializes a new instance of the <see cref="T:PropertyConstraint"/> class.
 98        /// </summary>
 99        /// <param name="name">The name.</param>
100        /// <param name="baseConstraint">The constraint to apply to the property.</param>
101        public PropertyConstraint(string name, Constraint baseConstraint)
102			: base( baseConstraint ) 
103		{ 
104			this.name = name;
105		}
106
107        /// <summary>
108        /// Test whether the constraint is satisfied by a given value
109        /// </summary>
110        /// <param name="actual">The value to be tested</param>
111        /// <returns>True for success, false for failure</returns>
112        public override bool Matches(object actual)
113		{
114            this.actual = actual;
115            if (actual == null) 
116                throw new ArgumentNullException("actual");
117
118            Type actualType = actual as Type;
119            if ( actualType == null )
120                actualType = actual.GetType();
121
122            PropertyInfo property = actualType.GetProperty(name,
123                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
124
125            if (property == null)
126                throw new ArgumentException(string.Format("Property {0} was not found",name), "name");
127
128			propValue = property.GetValue( actual, null );
129			return baseConstraint.Matches( propValue );
130		}
131
132		/// <summary>
133		/// Write the constraint description to a MessageWriter
134		/// </summary>
135		/// <param name="writer">The writer on which the description is displayed</param>
136		public override void WriteDescriptionTo(MessageWriter writer)
137		{
138			writer.WritePredicate( "property " + name );
139            if (baseConstraint != null)
140            {
141                if (baseConstraint is EqualConstraint)
142                    writer.WritePredicate("equal to");
143                baseConstraint.WriteDescriptionTo(writer);
144            }
145        }
146
147		/// <summary>
148		/// Write the actual value for a failing constraint test to a
149		/// MessageWriter. The default implementation simply writes
150		/// the raw value of actual, leaving it to the writer to
151		/// perform any formatting.
152		/// </summary>
153		/// <param name="writer">The writer on which the actual value is displayed</param>
154		public override void WriteActualValueTo(MessageWriter writer)
155		{
156            writer.WriteActualValue(propValue);
157		}
158
159        /// <summary>
160        /// Returns the string representation of the constraint.
161        /// </summary>
162        /// <returns></returns>
163        protected override string GetStringRepresentation()
164        {
165            return string.Format("<property {0} {1}>", name, baseConstraint);
166        }
167	}
168}