/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                                                                       *
 *   TestCaseExtension Library, Copyright 2015 Bryan Chadwick            *
 *                                                                       *
 *   FILE: .\TestCaseFailureException.cs                                 *
 *                                                                       *
 *   This file is part of TestCaseExtension.                             *
 *                                                                       *
 *   TestCaseExtension is free software: you can redistribute it and/or  *
 *   modify it under the terms of the GNU General Public License         *
 *   as published by the Free Software Foundation, either version        *
 *   3 of the License, or (at your option) any later version.            *
 *                                                                       *
 *   TestCaseExtension is distributed in the hope that it will be useful,*
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of      *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
 *   GNU General Public License for more details.                        *
 *                                                                       *
 *   You should have received a copy of the GNU General Public License   *
 *   along with TestCaseExtension.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *                                                                       *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
using System;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestCaseExtension.Internal;

namespace TestCaseExtension
{
    /// <summary>Exception class for a collection of <c>TestCase</c> failures</summary>
    public class TestCaseFailureException : UnitTestAssertException
    {
        private readonly StringBuilder combinedMessage = new StringBuilder("TestCase Failure(s)\n");
        private int numMessages = 0;

        /// <summary>Log the TestCase failure of the given method and fiailure Exception</summary>
        public void LogFailure(object[] arguments, MethodInfo method, Exception failure)
        {
            numMessages++;
            combinedMessage.AppendLine(FormatMessage(numMessages, arguments, method, failure));
        }

        /// <summary>Have any of the <c>TestCase</c>s failed?</summary>
        public bool HasFailures
        {
            get { return numMessages > 0; }
        }

        /// <summary>A summary of any <c>TestCase</c> failures, e.g., the result message from
        ///        each failing <c>TestCase</c></summary>
        public override string Message
        {
            get { return combinedMessage.ToString(); }
        }

        private const string MESSAGE_FORMAT = "  {0}) {1}.{2} :\n\t{3}\n\t {4}\n";
        private string FormatMessage(int i, object[] arguments, MethodInfo method, Exception failure)
        {
            string typeName = method.DeclaringType.FullName;
            return string.Format(MESSAGE_FORMAT, i, typeName, MethodWithParens(method.Name, arguments),
                failure.Message, failure.StackTrace.Replace("\n", "\n\t "));
        }

        private string MethodWithParens(string methodName, object[] arguments)
        {
            return string.Format("{0}({1})", methodName, arguments.StringJoin(", "));
        }
    }
}