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