1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
// ****************************************************************
// 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
{
/// <summary>
/// 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.
/// </summary>
public abstract class Constraint
{
#region UnsetObject Class
/// <summary>
/// Class used to detect any derived constraints
/// that fail to set the actual value in their
/// Matches override.
/// </summary>
private class UnsetObject
{
public override string ToString()
{
return "UNSET";
}
}
#endregion
#region Static and Instance Fields
/// <summary>
/// Static UnsetObject used to detect derived constraints
/// failing to set the actual value.
/// </summary>
protected static object UNSET = new UnsetObject();
/// <summary>
/// If true, all string comparisons will ignore case
/// </summary>
protected bool caseInsensitive;
/// <summary>
/// If true, strings in error messages will be clipped
/// </summary>
protected bool clipStrings = true;
/// <summary>
/// If true, arrays will be treated as collections, allowing
/// those of different dimensions to be compared
/// </summary>
protected bool compareAsCollection;
/// <summary>
/// If non-zero, equality comparisons within the specified
/// tolerance will succeed.
/// </summary>
protected object tolerance;
/// <summary>
/// IComparer object used in comparisons for some constraints.
/// </summary>
protected IComparer compareWith;
/// <summary>
/// The actual value being tested against a constraint
/// </summary>
protected object actual = UNSET;
#endregion
#region Properties
/// <summary>
/// Flag the constraint to ignore case and return self.
/// </summary>
public virtual Constraint IgnoreCase
{
get
{
caseInsensitive = true;
return this;
}
}
/// <summary>
/// Flag the constraint to suppress string clipping
/// and return self.
/// </summary>
public Constraint NoClip
{
get
{
clipStrings = false;
return this;
}
}
/// <summary>
/// Flag the constraint to compare arrays as collections
/// and return self.
/// </summary>
public Constraint AsCollection
{
get
{
compareAsCollection = true;
return this;
}
}
/// <summary>
/// Flag the constraint to use a tolerance when determining equality.
/// Currently only used for doubles and floats.
/// </summary>
/// <param name="tolerance">Tolerance to be used</param>
/// <returns>Self.</returns>
public Constraint Within(object tolerance)
{
this.tolerance = tolerance;
return this;
}
/// <summary>
/// Flag the constraint to use the supplied IComparer object.
/// </summary>
/// <param name="comparer">The IComparer object to use.</param>
/// <returns>Self.</returns>
public Constraint Comparer(IComparer comparer)
{
this.compareWith = comparer;
return this;
}
#endregion
#region Public Methods
/// <summary>
/// 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.
/// </summary>
/// <param name="writer">The MessageWriter on which to display the message</param>
public virtual void WriteMessageTo(MessageWriter writer)
{
writer.DisplayDifferences(this);
}
/// <summary>
/// Test whether the constraint is satisfied by a given value
/// </summary>
/// <param name="actual">The value to be tested</param>
/// <returns>True for success, false for failure</returns>
public abstract bool Matches(object actual);
/// <summary>
/// Write the constraint description to a MessageWriter
/// </summary>
/// <param name="writer">The writer on which the description is displayed</param>
public abstract void WriteDescriptionTo(MessageWriter writer);
/// <summary>
/// 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.
/// </summary>
/// <param name="writer">The writer on which the actual value is displayed</param>
public virtual void WriteActualValueTo(MessageWriter writer)
{
writer.WriteActualValue( actual );
}
#endregion
#region Operator Overloads
/// <summary>
/// This operator creates a constraint that is satisfied only if both
/// argument constraints are satisfied.
/// </summary>
public static Constraint operator &(Constraint left, Constraint right)
{
return new AndConstraint(left, right);
}
/// <summary>
/// This operator creates a constraint that is satisfied if either
/// of the argument constraints is satisfied.
/// </summary>
public static Constraint operator |(Constraint left, Constraint right)
{
return new OrConstraint(left, right);
}
/// <summary>
/// This operator creates a constraint that is satisfied if the
/// argument constraint is not satisfied.
/// </summary>
public static Constraint operator !(Constraint m)
{
return new NotConstraint(m == null ? new EqualConstraint(null) : m);
}
#endregion
}
}
|