private static void AppendDiagnosticDescription(StringBuilder sb, DiagnosticDescription d)
 {
     Indent(sb, 1);
     sb.Append(d.ToString());
 }
        public static string GetAssertText(DiagnosticDescription[] expected, IEnumerable<Diagnostic> actual)
        {
            var includeCompilerOutput = false;
            var includeDiagnosticMessagesAsComments = false;

            const int CSharp = 1;
            const int VisualBasic = 2;
            int language = actual.Any() && actual.First().Id.StartsWith("CS", StringComparison.Ordinal) ? CSharp : VisualBasic;

            if (language == CSharp)
            {
                includeDiagnosticMessagesAsComments = true;
            }

            StringBuilder assertText = new StringBuilder();
            assertText.AppendLine();

            // Write out the 'command line compiler output' including squiggles (easy to read debugging info in the case of a failure).
            // This will be useful for VB, because we can't do the inline comments.
            if (includeCompilerOutput)
            {
                assertText.AppendLine("Compiler output:");
                foreach (Diagnostic d in actual)
                {
                    Indent(assertText, 1);
                    assertText.AppendLine(d.ToString());
                    Location location = d.Location;
                    string lineText = location.SourceTree.GetText().Lines.GetLineFromPosition(location.SourceSpan.Start).ToString();
                    assertText.AppendLine(lineText);
                    FileLinePositionSpan span = location.GetMappedLineSpan();
                    LinePosition startPosition = span.StartLinePosition;
                    LinePosition endPosition = span.EndLinePosition;
                    assertText.Append(' ', startPosition.Character);
                    int endCharacter = (startPosition.Line == endPosition.Line) ? endPosition.Character : lineText.Length;
                    assertText.Append('~', endCharacter - startPosition.Character);
                    assertText.AppendLine();
                }
            }

            // write out the error baseline as method calls
            int i;
            assertText.AppendLine("Expected:");
            var expectedText = new StringBuilder();
            for (i = 0; i < expected.Length; i++)
            {
                DiagnosticDescription d = expected[i];

                AppendDiagnosticDescription(expectedText, d);

                if (i < expected.Length - 1)
                {
                    expectedText.Append(",");
                }

                expectedText.AppendLine();
            }
            assertText.Append(expectedText);

            // write out the actual results as method calls (copy/paste this to update baseline)
            assertText.AppendLine("Actual:");
            var actualText = new StringBuilder();
            IEnumerator<Diagnostic> e = actual.GetEnumerator();
            for (i = 0; e.MoveNext(); i++)
            {
                Diagnostic d = e.Current;
                string message = d.ToString();
                if (Regex.Match(message, @"{\d+}").Success)
                {
                    Assert.True(false, "Diagnostic messages should never contain unsubstituted placeholders.\n    " + message);
                }

                if (i > 0)
                {
                    assertText.AppendLine(",");
                    actualText.AppendLine(",");
                }

                if (includeDiagnosticMessagesAsComments)
                {
                    Indent(assertText, 1);
                    assertText.Append("// ");
                    assertText.AppendLine(d.ToString());
                    Location l = d.Location;
                    if (l.IsInSource)
                    {
                        Indent(assertText, 1);
                        assertText.Append("// ");
                        assertText.AppendLine(l.SourceTree.GetText().Lines.GetLineFromPosition(l.SourceSpan.Start).ToString());
                    }
                }

                var description = new DiagnosticDescription(d, errorCodeOnly: false, showPosition: true);
                AppendDiagnosticDescription(assertText, description);
                AppendDiagnosticDescription(actualText, description);
            }
            if (i > 0)
            {
                assertText.AppendLine();
                actualText.AppendLine();
            }

            assertText.AppendLine("Diff:");
            assertText.Append(DiffUtil.DiffReport(expectedText.ToString(), actualText.ToString()));

            return assertText.ToString();
        }