public void HandleException_ValidLog_ExpectedTextIsReturned()
        {
            // Arrange
            var filters      = this.GetDefaultFilters();
            var output       = new ThreadCollectionOutputHandler(filters);
            var ex           = this.GenerateExceptionWithStackTrace();
            var entry        = new ExceptionTrace(ex, DateTime.Parse("2022-10-22 22:22:31.678"));
            var expectedText = String.Concat("".PadLeft(2, output.Formatter.IndentChar), "[Exception] 22:22:31.678 Attempted to divide by zero.");

            int threadId   = 22;
            var threadData = new ThreadData(threadId, "cotton", null);

            output.Initialise();

            // Act
            output.HandleThread(threadData);
            output.HandleException(entry, 1);
            output.Complete();

            // Assert
            var outputText = output.GetThreadEntries();

            Assert.That(outputText.Count, Is.EqualTo(1), "Expected one string entry to be returned");
            Assert.That(outputText[threadId][0], Is.EqualTo(expectedText), "Not the expected output text, you may need to adjust the test if the formatter has been changed.");
        }
        public void SingleLineFormatter_NestedMethodCallsWithSomeMethodsDisabled_ReportDoesNotHaveDisabledLogs()
        {
            // Arrange
            var formatter     = new SingleLineFormatter();
            var startDateTime = DateTime.Now;
            var entries       = new Tuple <bool, BaseEntry>[]
            {
                new Tuple <bool, BaseEntry>(true, new MethodEntry(1, "TopLevelMethod", null, startDateTime)),
                new Tuple <bool, BaseEntry>(true, new MethodExit(1, "TopLevelMethod", 233, true, "blackSheep")),
                new Tuple <bool, BaseEntry>(true, new MethodEntry(1, "FirstMethod", null, startDateTime.AddSeconds(12))),
                new Tuple <bool, BaseEntry>(false, new MethodEntry(2, "SecondMethod", null, startDateTime.AddSeconds(45))),
                new Tuple <bool, BaseEntry>(true, new LogEvent(LogLevel.Info, startDateTime.AddSeconds(47), "Information log message here")),
                new Tuple <bool, BaseEntry>(true, new ExceptionTrace(new ArgumentNullException("lineNo", "Test the log"), startDateTime.AddSeconds(53))),
                new Tuple <bool, BaseEntry>(true, new MethodEntry(3, "ThirdMethod", null, startDateTime.AddSeconds(75))),
                new Tuple <bool, BaseEntry>(true, new MethodExit(3, "ThirdMethod", 100, false, null)),
                new Tuple <bool, BaseEntry>(false, new MethodEntry(3, "FourthMethod", null, startDateTime.AddSeconds(80))),
                new Tuple <bool, BaseEntry>(false, new MethodExit(3, "FourthMethod", 57, false, null)),
                new Tuple <bool, BaseEntry>(false, new MethodExit(2, "SecondMethod", 178, false, null)),
                new Tuple <bool, BaseEntry>(true, new MethodExit(1, "FirstMethod", 200, false, null)),
                new Tuple <bool, BaseEntry>(true, new MethodEntry(1, "TopLevelMethod2", null, startDateTime.AddSeconds(99))),
                new Tuple <bool, BaseEntry>(true, new MethodExit(1, "TopLevelMethod2", 488, true, "whiteSheep")),
            };

            var expectedText = (new string[]
            {
                string.Format("TopLevelMethod(blackSheep) started {0:HH:mm:ss.fff} duration 233ms", startDateTime),
                string.Format("FirstMethod() started {0:HH:mm:ss.fff} duration 200ms", startDateTime.AddSeconds(12)),
                string.Format("    [Log] [Info] Information log message here"),
                string.Format("    [Exception] {0:HH:mm:ss.fff} Test the log\r\nParameter name: lineNo", startDateTime.AddSeconds(53)),
                string.Format("    ThirdMethod() started {0:HH:mm:ss.fff} duration 100ms", startDateTime.AddSeconds(75)),
                string.Format("TopLevelMethod2(whiteSheep) started {0:HH:mm:ss.fff} duration 488ms", startDateTime.AddSeconds(99))
            }
                                ).ToList();

            var filters     = this.GetDefaultFilters();
            var indentLevel = 0;

            int threadId   = 22;
            var threadData = new ThreadData(threadId, "cotton", null);
            var outputter  = new ThreadCollectionOutputHandler(filters, formatter);

            outputter.Initialise();
            outputter.HandleThread(threadData);


            // Act
            foreach (var entry in entries)
            {
                if (entry.Item2 is MethodEntry)
                {
                    outputter.HandleMethodEntry((entry.Item2 as MethodEntry), indentLevel, entry.Item1);
                    ++indentLevel;
                }
                else if (entry.Item2 is MethodExit)
                {
                    --indentLevel;
                    outputter.HandleMethodExit((entry.Item2 as MethodExit), indentLevel, entry.Item1);
                }
                else if (entry.Item2 is LogEvent)
                {
                    outputter.HandleLogEvent((entry.Item2 as LogEvent), indentLevel, entry.Item1);
                }
                else if (entry.Item2 is ExceptionTrace)
                {
                    outputter.HandleException((entry.Item2 as ExceptionTrace), indentLevel);
                }
            }

            outputter.Complete();

            // Assert
            var reportText = outputter.GetThreadEntries();

            Assert.That(reportText.Count, Is.EqualTo(1), "Expected one thread collection");

            var output = reportText[threadId];

            Assert.That(output.Count, Is.EqualTo(expectedText.Count), "Expected {0} output lines, but have {1}\n{2}", expectedText.Count, output.Count, this.CreateComparisonReport(output, expectedText));

            for (int index = 0; index < expectedText.Count; index++)
            {
                Assert.That(output[index], Is.EqualTo(expectedText[index]), "Not the expected text for line {0}\n\n{1}", index + 1, this.CreateComparisonReport(output, expectedText));
            }
        }