back

asserto.cs - c# assert counter and suppressor

For those who like their asserts plentiful, but do not seeing the same assert over and over during execution.

Note: the displayed stackframe will include asserto.

Asserto.cs

/// Asserto.cs
/// Copyright (c) 2013 Eric Itomura
///
/// This software is provided 'as-is', without any express or implied
/// warranty. In no event will the authors be held liable for any damages
/// arising from the use of this software.
///
/// Permission is granted to anyone to use this software for any purpose,
/// including commercial applications, and to alter it and redistribute it
/// freely.  

using System;
using System.Diagnostics;
using System.Collections.Generic;

namespace ProjectB
{
    /// <summary>
    /// Asserto is an assert wrapper which tracks calls to the same assert
    /// and total asserts hit, and will ignore assert calls beyond the specified threshold.
    /// </summary>
    public class Asserto
    {
        /// <summary>
        ///  Total number of asserts to trigger before ignoring all subsequent asserts.
        /// </summary>
        const int TotalAssertsMax = 1;
        /// <summary>
        ///  Number of asserts to trigger before ignoring subsequent unique asserts.
        /// </summary>
        const int RepeatUniqueAssertsMax = 1;

        static Dictionary<string, int> m_keyAndCount = new Dictionary<string, int>();
        static int m_totalAssertCount = 0;

        /// <summary>
        /// Tracked assert, checks if object is null.
        /// </summary>
        /// <param name="obj">asserts if obj is null</param>
        [Conditional("DEBUG")]
        static public void Assert(object obj)
        {
            Assert(obj!=null, obj+" was null.");
        }

        /// <summary>
        /// Tracked assert with no message.
        /// </summary>
        /// <param name="cond">conditional will assert if false</param>
        [Conditional("DEBUG")]
        static public void Assert(bool cond)
        {
            Assert(cond, "");
        }

        /// <summary>
        /// Tracked assert with message.
        /// </summary>
        /// <param name="cond">conditional will assert if false</param>
        /// <param name="msg">message to display upon assert</param>
        [Conditional("DEBUG")]
        static public void Assert(bool cond, string msg)
        {
            if (!cond)
            {
                var shouldAssert = false;
                if (m_totalAssertCount < TotalAssertsMax)
                {
                    StackFrame stack = new StackFrame(1, true);
                    if (stack != null)
                    {
                        string key = stack.GetFileName() != null
                            ? stack.GetFileName().ToString() : "";
                        key += stack.GetFileLineNumber().ToString();

                        if (!m_keyAndCount.ContainsKey(key))
                        {
                            if (1 <= RepeatUniqueAssertsMax)
                            {
                                shouldAssert = true;
                                m_keyAndCount.Add(key, 1);
                            }
                        }
                        else
                        {
                            var count = m_keyAndCount[key];
                            if (count <= RepeatUniqueAssertsMax)
                            {
                                shouldAssert = true;
                                m_keyAndCount[key] = count + 1;
                            }
                        }
                    }
                    else
                    {
                        shouldAssert = true;
                    }

                    if (shouldAssert)
                    {
                        Debug.Assert(cond, msg);
                        ++m_totalAssertCount;
                    }
                }
            }
        }

        /// <summary>
        /// Flag always asserts upon call with a message.
        /// </summary>
        /// <param name="msg">message to display when asserting</param>
        [Conditional("DEBUG")]
        static public void Flag(string msg)
        {
            bool shouldAssert = false;
            if (m_totalAssertCount < TotalAssertsMax)
            {
                StackFrame stack = new StackFrame(1, true);
                if (stack != null)
                {
                    string key = stack.GetFileName() != null
                        ? stack.GetFileName().ToString() : "";
                    key += stack.GetFileLineNumber().ToString();

                    if (!m_keyAndCount.ContainsKey(key))
                    {
                        if (1 <= RepeatUniqueAssertsMax)
                        {
                            shouldAssert = true;
                            m_keyAndCount.Add(key, 1);
                        }
                    }
                    else
                    {
                        var count = m_keyAndCount[key];
                        if (count <= RepeatUniqueAssertsMax)
                        {
                            shouldAssert = true;
                            m_keyAndCount[key] = count + 1;
                        }
                    }
                }
                else
                {
                    shouldAssert = true;
                }
            }

            if (shouldAssert)
            {
                Debug.Assert(false, msg);
                ++m_totalAssertCount;
            }
        }

        /// <summary>
        /// Debug printing.
        /// </summary>
        /// <param name="msg">message to print</param>
        [Conditional("DEBUG")]
        static public void Print(string msg)
        {
            Console.Write(msg);
        }
    }
}