// ****************************************************************
// 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
}
}