// **************************************************************** // Copyright 2007, Charlie Poole // This is free software licensed under the NUnit license. You may // obtain a copy of the license at http://nunit.org/?p=license&r=2.4 // **************************************************************** using System; using System.IO; using System.Collections; namespace NUnit.Framework.Constraints { /// /// The Constraint class is the base of all built-in or /// user-defined constraints in NUnit. It provides the operator /// overloads used to combine constraints. /// public abstract class Constraint { #region UnsetObject Class /// /// Class used to detect any derived constraints /// that fail to set the actual value in their /// Matches override. /// private class UnsetObject { public override string ToString() { return "UNSET"; } } #endregion #region Static and Instance Fields /// /// Static UnsetObject used to detect derived constraints /// failing to set the actual value. /// protected static object UNSET = new UnsetObject(); /// /// If true, all string comparisons will ignore case /// protected bool caseInsensitive; /// /// If true, strings in error messages will be clipped /// protected bool clipStrings = true; /// /// If true, arrays will be treated as collections, allowing /// those of different dimensions to be compared /// protected bool compareAsCollection; /// /// If non-zero, equality comparisons within the specified /// tolerance will succeed. /// protected object tolerance; /// /// IComparer object used in comparisons for some constraints. /// protected IComparer compareWith; /// /// The actual value being tested against a constraint /// protected object actual = UNSET; #endregion #region Properties /// /// Flag the constraint to ignore case and return self. /// public virtual Constraint IgnoreCase { get { caseInsensitive = true; return this; } } /// /// Flag the constraint to suppress string clipping /// and return self. /// public Constraint NoClip { get { clipStrings = false; return this; } } /// /// Flag the constraint to compare arrays as collections /// and return self. /// public Constraint AsCollection { get { compareAsCollection = true; return this; } } /// /// Flag the constraint to use a tolerance when determining equality. /// Currently only used for doubles and floats. /// /// Tolerance to be used /// Self. public Constraint Within(object tolerance) { this.tolerance = tolerance; return this; } /// /// Flag the constraint to use the supplied IComparer object. /// /// The IComparer object to use. /// Self. public Constraint Comparer(IComparer comparer) { this.compareWith = comparer; return this; } #endregion #region Public Methods /// /// Write the failure message to the MessageWriter provided /// as an argument. The default implementation simply passes /// the constraint and the actual value to the writer, which /// then displays the constraint description and the value. /// /// Constraints that need to provide additional details, /// such as where the error occured can override this. /// /// The MessageWriter on which to display the message public virtual void WriteMessageTo(MessageWriter writer) { writer.DisplayDifferences(this); } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for success, false for failure public abstract bool Matches(object actual); /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public abstract void WriteDescriptionTo(MessageWriter writer); /// /// Write the actual value for a failing constraint test to a /// MessageWriter. The default implementation simply writes /// the raw value of actual, leaving it to the writer to /// perform any formatting. /// /// The writer on which the actual value is displayed public virtual void WriteActualValueTo(MessageWriter writer) { writer.WriteActualValue( actual ); } #endregion #region Operator Overloads /// /// This operator creates a constraint that is satisfied only if both /// argument constraints are satisfied. /// public static Constraint operator &(Constraint left, Constraint right) { return new AndConstraint(left, right); } /// /// This operator creates a constraint that is satisfied if either /// of the argument constraints is satisfied. /// public static Constraint operator |(Constraint left, Constraint right) { return new OrConstraint(left, right); } /// /// This operator creates a constraint that is satisfied if the /// argument constraint is not satisfied. /// public static Constraint operator !(Constraint m) { return new NotConstraint(m == null ? new EqualConstraint(null) : m); } #endregion } }