/************************************************************************************* 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(); } } } }