Пример #1
0
        /// <summary>
        /// Construct given a base constraint
        /// </summary>
        /// <param name="baseConstraint"></param>
        protected PrefixConstraint(IResolveConstraint baseConstraint)
            : base(baseConstraint)
        {
            Guard.ArgumentNotNull(baseConstraint, "baseConstraint");

            this.baseConstraint = baseConstraint.Resolve();
        }
Пример #2
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <param name="expression">A Constraint to be applied</param>
        /// <param name="actual">The actual value to test</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        static public void That(object actual, IResolveConstraint expression, string message, params object[] args)
        {
            Constraint constraint = expression.Resolve();

            Assert.IncrementAssertCount();
            if (!constraint.Matches(actual))
            {
                MessageWriter writer = new TextMessageWriter(message, args);
                constraint.WriteMessageTo(writer);
                throw new AssertionException(writer.ToString());
            }
        }
Пример #3
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an InconclusiveException on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void That <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr, string message, params object[] args)
        {
            CheckMultipleAssertLevel();

            var constraint = expr.Resolve();
            var result     = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                ReportFailure(result, message, args);
            }
        }
Пример #4
0
        public static void Unless <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr, string?message, params object?[]?args)
        {
            var constraint = expr.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                IssueWarning(result, message, args);
            }
        }
Пример #5
0
        public static void If <TActual>(TActual actual, IResolveConstraint expression, string?message, params object?[]?args)
        {
            var constraint = new NotConstraint(expression.Resolve());

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                IssueWarning(result, message, args);
            }
        }
Пример #6
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void That <TActual>(TActual actual, IResolveConstraint expression, string message, params object[] args)
        {
            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                ReportFailure(result, message, args);
            }
        }
Пример #7
0
        private static void PerformAssertWithConstraint <T>(IResolveConstraint constraint, object actual, Func <string> getExceptionMessage = null, string message = null, object[] args = null)
        {
            using (var messageWitter = new TextMessageWriter())
            {
                var resolveConstraint = constraint.Resolve();

                TestExecutionContext.CurrentContext.IncrementAssertCount();

                var result = actual is ActualValueDelegate <T>?resolveConstraint.ApplyTo <T>(actual as ActualValueDelegate <T>) : resolveConstraint.ApplyTo(actual);

                var expectedValue = result.Description;
                result.WriteActualValueTo(messageWitter);
                var actualValue = messageWitter.ToString();

                if (!result.IsSuccess)
                {
                    if (IsSkipBug())
                    {
                        TestExecutionContext.CurrentContext.CurrentResult.RecordAssertion(AssertionStatus.Warning, "Triaged test case failure", StackFilter.DefaultFilter.Filter(SystemEnvironmentFilter.Filter(Environment.StackTrace)));
                    }
                    else
                    {
                        TestExecutionContext.CurrentContext.CurrentResult.RecordAssertion(AssertionStatus.Failed, message, StackFilter.DefaultFilter.Filter(SystemEnvironmentFilter.Filter(Environment.StackTrace)));

                        AssertionException exceptiopn = null;
                        if (getExceptionMessage != null)
                        {
                            exceptiopn = new AssertionException(getExceptionMessage());
                        }
                        else
                        {
                            using (var errorMessageWritter = new TextMessageWriter(message, args))
                            {
                                result.WriteMessageTo(errorMessageWritter);
                                exceptiopn = new AssertionException(errorMessageWritter.ToString());
                            }
                        }
                        LogHelper.LoggerForCurrentTest.Assert(FormatAssertFailMessage(getExceptionMessage, message, args), false, actual, expectedValue, actualValue, exceptiopn.ToString());
                        throw exceptiopn ?? new AssertionException($"Assert.That() failed.{Environment.NewLine} Expected {expectedValue}.{Environment.NewLine} Actual {actualValue}.");
                    }
                }
                if (IsSkipBug() && result.IsSuccess)
                {
                    TestExecutionContext.CurrentContext.CurrentResult.RecordAssertion(AssertionStatus.Failed, "Test Cases Marked as Bug, but passed.", StackFilter.DefaultFilter.Filter(SystemEnvironmentFilter.Filter(Environment.StackTrace)));
                    LogHelper.LoggerForCurrentTest.Assert("Test Cases Marked as Bug, but passed.", false, actual, expectedValue, actualValue);
                }
                else
                {
                    LogHelper.LoggerForCurrentTest.Assert("Asserting expression -- success.", true, actual, expectedValue, actualValue);
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an InconclusiveException on failure.
        /// </summary>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        static public void That <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr, string message, params object[] args)
        {
            var constraint = expr.Resolve();

            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                MessageWriter writer = new TextMessageWriter(message, args);
                result.WriteMessageTo(writer);
                throw new InconclusiveException(writer.ToString());
            }
        }
Пример #9
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// fails and issuing a warning on success.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void If <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr, string message, params object[] args)
        {
            CheckMultipleAssertLevel();

            var constraint = new NotConstraint(expr.Resolve());

            IncrementAssertCount();
            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                IssueWarning(result, message, args);
            }
        }
Пример #10
0
 /// <summary>
 ///     Apply a constraint to an actual value, succeeding if the constraint
 ///     is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="stepName">The Step Name to Allure report</param>
 /// <typeparam name="TActual">The Type being compared.</typeparam>
 /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
 /// <param name="expr">A Constraint expression to be applied</param>
 /// <param name="message">The message that will be displayed on failure</param>
 /// <param name="args">Arguments to be used in formatting the message</param>
 public bool That <TActual>(string stepName, ActualValueDelegate <TActual> del, IResolveConstraint expr,
                            string message, params object[] args)
 {
     return(VerifyRunner(stepName, () =>
     {
         var constraint = expr.Resolve();
         TestExecutionContext.CurrentContext.IncrementAssertCount();
         var result = constraint.ApplyTo(del);
         if (!result.IsSuccess)
         {
             ReportFailure(result, message, args);
         }
     }, Status.failed));
 }
Пример #11
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and issuing a warning on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void Unless <TActual>(TActual actual, IResolveConstraint expression, string message, params object[] args)
        {
            CheckMultipleAssertLevel();

            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                IssueWarning(result, message, args);
            }
        }
Пример #12
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="actual">The actual value to test</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        static public void That <TActual>(TActual actual, IResolveConstraint expression, string message, params object[] args)
        {
            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                MessageWriter writer = new TextMessageWriter(message, args);
                result.WriteMessageTo(writer);
                throw new AssertionException(writer.ToString());
            }
        }
Пример #13
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an InconclusiveException on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void That <TActual>(
            TActual actual,
            IResolveConstraint expression,
            Func <string> getExceptionMessage)
        {
            var constraint = expression.Resolve();

            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                throw new InconclusiveException(getExceptionMessage());
            }
        }
Пример #14
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an InconclusiveException on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void That <TActual>(
            ActualValueDelegate <TActual> del,
            IResolveConstraint expr,
            Func <string> getExceptionMessage)
        {
            var constraint = expr.Resolve();

            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                throw new InconclusiveException(getExceptionMessage());
            }
        }
Пример #15
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and issuing a warning on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void Unless <TActual>(
            ActualValueDelegate <TActual> del,
            IResolveConstraint expr,
            Func <string> getExceptionMessage)
        {
            var constraint = expr.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                IssueWarning(result, getExceptionMessage(), null);
            }
        }
Пример #16
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void That <TActual>(
            TActual actual,
            IResolveConstraint expression,
            Func <ConstraintResult, string> getExceptionMessage)
        {
            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                throw new AssertionException(getExceptionMessage(result));
            }
        }
Пример #17
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and issuing a warning on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void If <TActual>(
            TActual actual,
            IResolveConstraint expression,
            Func <string> getExceptionMessage)
        {
            var constraint = new NotConstraint(expression.Resolve());

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                IssueWarning(result, getExceptionMessage(), null);
            }
        }
Пример #18
0
        public static void That(this IAssert assert, ActualValueDelegate actual, IResolveConstraint expression, string message = null)
        {
            Constraint constraint = expression.Resolve();

            if (constraint.Matches(actual))
            {
                assert.Okay();
                return;
            }
            using (MessageWriter writer = new TextMessageWriter(message))
            {
                constraint.WriteMessageTo(writer);
                assert.Fail(writer.ToString(), ExcludeFromStack);
            }
        }
Пример #19
0
        public static void That <TActual>(
            TActual actual,
            IResolveConstraint expression,
            Func <string?> getExceptionMessage)
        {
            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                ReportFailure(result, getExceptionMessage());
            }
        }
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void That <TActual>(
            ActualValueDelegate <TActual> del,
            IResolveConstraint expr,
            Func <string> getExceptionMessage)
        {
            var constraint = expr.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                ReportFailure(result, getExceptionMessage());
            }
        }
Пример #21
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an InconclusiveException on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void That <TActual>(TActual actual, IResolveConstraint expression, string message, params object[] args)
        {
            CheckMultipleAssertLevel();

            var constraint = expression.Resolve();

            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                MessageWriter writer = new TextMessageWriter(message, args);
                result.WriteMessageTo(writer);
                throw new InconclusiveException(writer.ToString());
            }
        }
Пример #22
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
        /// <param name="expr">A Constraint expression to be applied</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static void That <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr, string message, params object[] args)
        {
            var constraint = expr.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(del);

            if (!result.IsSuccess)
            {
                ReportFailure(result, message, args);
            }
            else
            {
                ReportSuccess(result, args);
            }
        }
Пример #23
0
        /// <summary>
        ///     Apply a constraint to an actual value, succeeding if the constraint
        ///     is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <param name="stepName">The Step Name to Allure report</param>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint expression to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public bool That <TActual>(string stepName,
                                   TActual actual,
                                   IResolveConstraint expression,
                                   Func <string> getExceptionMessage, params object[] stepParams)
        {
            return(VerifyRunner(stepName, () =>
            {
                var constraint = expression.Resolve();

                TestExecutionContext.CurrentContext.IncrementAssertCount();
                var result = constraint.ApplyTo(actual);
                if (!result.IsSuccess)
                {
                    ReportFailure(result, getExceptionMessage());
                }
            }, Status.failed, stepParams));
        }
Пример #24
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and issuing a warning on failure.
        /// </summary>
        /// <typeparam name="TActual">The Type being compared.</typeparam>
        /// <param name="actual">The actual value to test</param>
        /// <param name="expression">A Constraint to be applied</param>
        /// <param name="getExceptionMessage">A function to build the message included with the Exception</param>
        public static void Unless <TActual>(
            TActual actual,
            IResolveConstraint expression,
            Func <string> getExceptionMessage)
        {
            CheckMultipleAssertLevel();

            var constraint = expression.Resolve();

            IncrementAssertCount();
            var result = constraint.ApplyTo(actual);

            if (!result.IsSuccess)
            {
                IssueWarning(result, getExceptionMessage(), null);
            }
        }
Пример #25
0
 /// <summary>
 /// Apply a constraint to an actual value, succeeding if the constraint
 /// is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="expr">A Constraint expression to be applied</param>
 /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
 public void Expect(ActualValueDelegate del, IResolveConstraint expr)
 {
     Assert.That(del, expr.Resolve(), null, null);
 }
Пример #26
0
 /// <summary>
 /// Apply a constraint to a referenced value, succeeding if the constraint
 /// is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="constraint">A Constraint to be applied</param>
 /// <param name="actual">The actual value to test</param>
 /// <param name="message">The message that will be displayed on failure</param>
 public void Expect(ref bool actual, IResolveConstraint constraint, string message)
 {
     Assert.That(ref actual, constraint.Resolve(), message, null);
 }
Пример #27
0
 /// <summary>
 /// Apply a constraint to a referenced boolean, succeeding if the constraint
 /// is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="constraint">A Constraint to be applied</param>
 /// <param name="actual">The actual value to test</param>
 public void Expect(ref bool actual, IResolveConstraint constraint)
 {
     Assert.That(ref actual, constraint.Resolve(), null, null);
 }
Пример #28
0
 /// <summary>
 /// Apply a constraint to an actual value, succeeding if the constraint
 /// is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="expr">A Constraint expression to be applied</param>
 /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
 /// <param name="message">The message that will be displayed on failure</param>
 public void Expect(ActualValueDelegate del, IResolveConstraint expr, string message)
 {
     Assert.That(del, expr.Resolve(), message, null);
 }
 /// <summary>
 /// Returns the constraint provided as an argument - used to allow custom
 /// custom constraints to easily participate in the syntax.
 /// </summary>
 public Constraint Matches(IResolveConstraint constraint)
 {
     return(this.Append((Constraint)constraint.Resolve()));
 }
Пример #30
0
 /// <summary>
 ///     Apply a constraint to a referenced value, succeeding if the constraint
 ///     is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="actual">The actual value to test</param>
 /// <param name="constraint">A Constraint to be applied</param>
 /// <param name="message">The message that will be displayed on failure</param>
 internal static void That(ref bool actual, IResolveConstraint constraint, string message)
 {
     That(ref actual, constraint.Resolve(), message, null);
 }
Пример #31
0
 /// <summary>
 /// Construct a ReusableConstraint from a constraint expression
 /// </summary>
 /// <param name="c">The expression to be resolved and reused</param>
 public ReusableConstraint(IResolveConstraint c)
 {
     this.constraint = c.Resolve();
 }
 public NodeForTypeConstraint(Type type, IResolveConstraint constraint)
 {
     this.type = type;
     this.constraint = constraint.Resolve();
 }
 private static Constraint OperatorAndImplementation(IResolveConstraint left, IResolveConstraint right)
 {
     return new AndConstraint(left.Resolve(), right.Resolve());
 }
Пример #34
0
 /// <summary>
 /// Apply a constraint to an actual value, succeeding if the constraint
 /// is satisfied and throwing an InconclusiveException on failure.
 /// </summary>
 /// <param name="expr">A Constraint expression to be applied</param>
 /// <param name="del">An ActualValueDelegate returning the value to be tested</param>
 static public void That <TActual>(ActualValueDelegate <TActual> del, IResolveConstraint expr)
 {
     Assume.That(del, expr.Resolve(), null, null);
 }
Пример #35
0
 /// <summary>
 ///     Apply a constraint to a referenced boolean, succeeding if the constraint
 ///     is satisfied and throwing an assertion exception on failure.
 /// </summary>
 /// <param name="actual">The actual value to test</param>
 /// <param name="constraint">A Constraint to be applied</param>
 internal static void That(ref bool actual, IResolveConstraint constraint)
 {
     That(ref actual, constraint.Resolve(), null, null);
 }
		public static void WithBody(this RequestHandler handler, IResolveConstraint constraint)
		{
			Assert.That(handler.GetBody(), constraint.Resolve());
		}
Пример #37
0
 /// <summary>
 /// Construct given a base constraint
 /// </summary>
 /// <param name="resolvable"></param>
 protected PrefixConstraint(IResolveConstraint resolvable) : base(resolvable)
 {
     if ( resolvable != null )
         this.baseConstraint = resolvable.Resolve();
 }
Пример #38
0
 /// <summary>
 /// Construct a ReusableConstraint from a constraint expression
 /// </summary>
 /// <param name="c">The expression to be resolved and reused</param>
 public ReusableConstraint(IResolveConstraint c)
 {
     this.constraint = c.Resolve();
 }
Пример #39
0
        /// <summary>
        /// Apply a constraint to an actual value, succeeding if the constraint
        /// is satisfied and throwing an assertion exception on failure.
        /// </summary>
        /// <param name="expression">A Constraint to be applied</param>
        /// <param name="actual">The actual value to test</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        static public void That(object actual, IResolveConstraint expression, string message, params object[] args)
        {
            Constraint constraint = expression.Resolve();

            Assert.IncrementAssertCount();
            if (!constraint.Matches(actual))
            {
                MessageWriter writer = new TextMessageWriter(message, args);
                constraint.WriteMessageTo(writer);
                throw new AssertionException(writer.ToString());
            }
        }