// **************************************************************** // 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.Collections; namespace NUnit.Framework.Constraints { #region PrefixConstraint /// /// Abstract base class used for prefixes /// public abstract class PrefixConstraint : Constraint { /// /// The base constraint /// protected Constraint baseConstraint; /// /// Construct given a base constraint /// /// protected PrefixConstraint( Constraint baseConstraint ) { this.baseConstraint = baseConstraint; } /// /// Set all modifiers applied to the prefix into /// the base constraint before matching /// protected void PassModifiersToBase() { if ( this.caseInsensitive ) baseConstraint = baseConstraint.IgnoreCase; if (!this.clipStrings) baseConstraint = baseConstraint.NoClip; if ( this.tolerance != null ) baseConstraint = baseConstraint.Within( tolerance ); if ( this.compareAsCollection ) baseConstraint = baseConstraint.AsCollection; if ( this.compareWith != null ) baseConstraint = baseConstraint.Comparer( compareWith ); } } #endregion #region NotConstraint /// /// NotConstraint negates the effect of some other constraint /// public class NotConstraint : PrefixConstraint { /// /// Initializes a new instance of the class. /// /// The base constraint to be negated. public NotConstraint(Constraint baseConstraint) : base( baseConstraint ) { } /// /// Test whether the constraint is satisfied by a given value /// /// The value to be tested /// True for if the base constraint fails, false if it succeeds public override bool Matches(object actual) { this.actual = actual; this.PassModifiersToBase(); return !baseConstraint.Matches(actual); } /// /// Write the constraint description to a MessageWriter /// /// The writer on which the description is displayed public override void WriteDescriptionTo( MessageWriter writer ) { writer.WritePredicate( "not" ); baseConstraint.WriteDescriptionTo( writer ); } /// /// Write the actual value for a failing constraint test to a MessageWriter. /// /// The writer on which the actual value is displayed public override void WriteActualValueTo(MessageWriter writer) { baseConstraint.WriteActualValueTo (writer); } } #endregion #region AllItemsConstraint /// /// AllItemsConstraint applies another constraint to each /// item in a collection, succeeding if they all succeed. /// public class AllItemsConstraint : PrefixConstraint { /// /// Construct an AllItemsConstraint on top of an existing constraint /// /// public AllItemsConstraint(Constraint itemConstraint) : base( itemConstraint ) { } /// /// Apply the item constraint to each item in the collection, /// failing if any item fails. /// /// /// public override bool Matches(object actual) { this.actual = actual; PassModifiersToBase(); if ( !(actual is ICollection) ) throw new ArgumentException( "The actual value must be a collection", "actual" ); foreach(object item in (ICollection)actual) if (!baseConstraint.Matches(item)) return false; return true; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("all items"); baseConstraint.WriteDescriptionTo(writer); } } #endregion #region SomeItemsConstraint /// /// SomeItemsConstraint applies another constraint to each /// item in a collection, succeeding if any of them succeeds. /// public class SomeItemsConstraint : PrefixConstraint { /// /// Construct a SomeItemsConstraint on top of an existing constraint /// /// public SomeItemsConstraint(Constraint itemConstraint) : base( itemConstraint ) { } /// /// Apply the item constraint to each item in the collection, /// failing if any item fails. /// /// /// public override bool Matches(object actual) { this.actual = actual; PassModifiersToBase(); if ( !(actual is ICollection) ) throw new ArgumentException( "The actual value must be a collection", "actual" ); foreach(object item in (ICollection)actual) if (baseConstraint.Matches(item)) return true; return false; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("some item"); baseConstraint.WriteDescriptionTo(writer); } } #endregion #region NoItemConstraint /// /// SomeItemsConstraint applies another constraint to each /// item in a collection, succeeding if any of them succeeds. /// public class NoItemConstraint : PrefixConstraint { /// /// Construct a SomeItemsConstraint on top of an existing constraint /// /// public NoItemConstraint(Constraint itemConstraint) : base( itemConstraint ) { } /// /// Apply the item constraint to each item in the collection, /// failing if any item fails. /// /// /// public override bool Matches(object actual) { this.actual = actual; PassModifiersToBase(); if ( !(actual is ICollection) ) throw new ArgumentException( "The actual value must be a collection", "actual" ); foreach(object item in (ICollection)actual) if (baseConstraint.Matches(item)) return false; return true; } /// /// Write a description of this constraint to a MessageWriter /// /// public override void WriteDescriptionTo(MessageWriter writer) { writer.WritePredicate("no item"); baseConstraint.WriteDescriptionTo(writer); } } #endregion }