/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
// Conditional to use more aggressive fail-fast behaviors when debugging.
#define DEV_DEBUG
// This file contains general utilities to aid in development.
// It is distinct from unit test Assert classes.
// Classes here generally shouldn't be exposed publicly since
// they're not particular to any library functionality.
// Because the classes here are internal, it's likely this file
// might be included in multiple assemblies.
namespace Standard
{
using System;
using System.Diagnostics;
using System.Threading;
/// A static class for verifying assumptions.
internal static class Assert
{
private static void _Break()
{
#if DEV_DEBUG
Debugger.Break();
#else
Debug.Assert(false);
#endif
}
/// A function signature for Assert.Evaluate.
public delegate void EvaluateFunction();
/// A function signature for Assert.Implies.
/// Returns the truth of a predicate.
public delegate bool ImplicationFunction();
///
/// Executes the specified argument.
///
/// The function to execute.
[Conditional( "DEBUG" )]
public static void Evaluate( EvaluateFunction argument )
{
IsNotNull( argument );
argument();
}
/// Obsolete: Use Standard.Assert.AreEqual instead of Assert.Equals
/// The generic type to compare for equality.
/// The first generic type data to compare. This is is the expected value.
/// The second generic type data to compare. This is the actual value.
[
Obsolete( "Use Assert.AreEqual instead of Assert.Equals", false ),
Conditional( "DEBUG" )
]
public static void Equals( T expected, T actual )
{
AreEqual( expected, actual );
}
///
/// Verifies that two generic type data are equal. The assertion fails if they are not.
///
/// The generic type to compare for equality.
/// The first generic type data to compare. This is is the expected value.
/// The second generic type data to compare. This is the actual value.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void AreEqual( T expected, T actual )
{
if( null == expected )
{
// Two nulls are considered equal, regardless of type semantics.
if( null != actual && !actual.Equals( expected ) )
{
_Break();
}
}
else if( !expected.Equals( actual ) )
{
_Break();
}
}
///
/// Verifies that two generic type data are not equal. The assertion fails if they are.
///
/// The generic type to compare for inequality.
/// The first generic type data to compare. This is is the value that's not expected.
/// The second generic type data to compare. This is the actual value.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void AreNotEqual( T notExpected, T actual )
{
if( null == notExpected )
{
// Two nulls are considered equal, regardless of type semantics.
if( null == actual || actual.Equals( notExpected ) )
{
_Break();
}
}
else if( notExpected.Equals( actual ) )
{
_Break();
}
}
///
/// Verifies that if the specified condition is true, then so is the result.
/// The assertion fails if the condition is true but the result is false.
///
/// if set to true [condition].
///
/// A second Boolean statement. If the first was true then so must this be.
/// If the first statement was false then the value of this is ignored.
///
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void Implies( bool condition, bool result )
{
if( condition && !result )
{
_Break();
}
}
///
/// Lazy evaluation overload. Verifies that if a condition is true, then so is a secondary value.
///
/// The conditional value.
/// A function to be evaluated for truth if the condition argument is true.
///
/// This overload only evaluates the result if the first condition is true.
///
[Conditional( "DEBUG" )]
public static void Implies( bool condition, ImplicationFunction result )
{
if( condition && !result() )
{
_Break();
}
}
///
/// Verifies that a string has content. I.e. it is not null and it is not empty.
///
/// The string to verify.
[Conditional( "DEBUG" )]
public static void IsNeitherNullNorEmpty( string value )
{
IsFalse( string.IsNullOrEmpty( value ) );
}
///
/// Verifies that a string has content. I.e. it is not null and it is not purely whitespace.
///
/// The string to verify.
[Conditional( "DEBUG" )]
public static void IsNeitherNullNorWhitespace( string value )
{
if( string.IsNullOrEmpty( value ) )
{
_Break();
}
if( value.Trim().Length == 0 )
{
_Break();
}
}
///
/// Verifies the specified value is not null. The assertion fails if it is.
///
/// The generic reference type.
/// The value to check for nullness.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsNotNull( T value ) where T : class
{
if( null == value )
{
_Break();
}
}
[Conditional( "DEBUG" )]
public static void IsDefault( T value ) where T : struct
{
if( !value.Equals( default( T ) ) )
{
Assert.Fail();
}
}
[Conditional( "DEBUG" )]
public static void IsNotDefault( T value ) where T : struct
{
if( value.Equals( default( T ) ) )
{
Assert.Fail();
}
}
///
/// Verifies that the specified condition is false. The assertion fails if it is true.
///
/// The expression that should be false.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsFalse( bool condition )
{
if( condition )
{
_Break();
}
}
///
/// Verifies that the specified condition is false. The assertion fails if it is true.
///
/// The expression that should be false.
/// The message to display if the condition is true.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsFalse( bool condition, string message )
{
if( condition )
{
_Break();
}
}
///
/// Verifies that the specified condition is true. The assertion fails if it is not.
///
/// A condition that is expected to be true.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsTrue( bool condition )
{
if( !condition )
{
_Break();
}
}
///
/// Verifies that the specified condition is true. The assertion fails if it is not.
///
/// A condition that is expected to be true.
/// The message to write in case the condition is false.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsTrue( bool condition, string message )
{
if( !condition )
{
_Break();
}
}
///
/// This line should never be executed. The assertion always fails.
///
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void Fail()
{
_Break();
}
///
/// This line should never be executed. The assertion always fails.
///
/// The message to display if this function is executed.
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void Fail( string message )
{
_Break();
}
///
/// Verifies that the specified object is null. The assertion fails if it is not.
///
/// The item to verify is null.
[Conditional( "DEBUG" )]
public static void IsNull( T item ) where T : class
{
if( null != item )
{
_Break();
}
}
///
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
///
/// The lower bound inclusive value.
/// The value to verify.
/// The upper bound inclusive value.
[Conditional( "DEBUG" )]
public static void BoundedDoubleInc( double lowerBoundInclusive, double value, double upperBoundInclusive )
{
if( value < lowerBoundInclusive || value > upperBoundInclusive )
{
_Break();
}
}
///
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
///
/// The lower bound inclusive value.
/// The value to verify.
/// The upper bound exclusive value.
[Conditional( "DEBUG" )]
public static void BoundedInteger( int lowerBoundInclusive, int value, int upperBoundExclusive )
{
if( value < lowerBoundInclusive || value >= upperBoundExclusive )
{
_Break();
}
}
///
/// Verify the current thread's apartment state is what's expected. The assertion fails if it isn't
///
///
/// The expected apartment state for the current thread.
///
/// This breaks into the debugger in the case of a failed assertion.
[Conditional( "DEBUG" )]
public static void IsApartmentState( ApartmentState expectedState )
{
if( Thread.CurrentThread.GetApartmentState() != expectedState )
{
_Break();
}
}
[Conditional( "DEBUG" )]
public static void NullableIsNotNull( T? value ) where T : struct
{
if( null == value )
{
_Break();
}
}
[Conditional( "DEBUG" )]
public static void NullableIsNull( T? value ) where T : struct
{
if( null != value )
{
_Break();
}
}
[Conditional( "DEBUG" )]
public static void IsNotOnMainThread()
{
if( System.Windows.Application.Current.Dispatcher.CheckAccess() )
{
_Break();
}
}
}
}