File: DocCommentFormatting\DocCommentFormattingTests.cs
Web Access
Project: src\src\EditorFeatures\Test\Microsoft.CodeAnalysis.EditorFeatures.UnitTests.csproj (Microsoft.CodeAnalysis.EditorFeatures.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using Microsoft.CodeAnalysis.CSharp.DocumentationComments;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.VisualBasic.DocumentationComments;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.UnitTests.DocCommentFormatting;
 
[Trait(Traits.Feature, Traits.Features.DocCommentFormatting)]
public class DocCommentFormattingTests
{
    private readonly CSharpDocumentationCommentFormattingService _csharpService = new CSharpDocumentationCommentFormattingService();
    private readonly VisualBasicDocumentationCommentFormattingService _vbService = new VisualBasicDocumentationCommentFormattingService();
 
    private void TestFormat(string xmlFragment, string expectedCSharp, string expectedVB)
    {
        var csharpFormattedText = _csharpService.Format(xmlFragment);
        var vbFormattedText = _vbService.Format(xmlFragment);
 
        Assert.Equal(expectedCSharp, csharpFormattedText);
        Assert.Equal(expectedVB, vbFormattedText);
    }
 
    private void TestFormat(string xmlFragment, string expected)
        => TestFormat(xmlFragment, expected, expected);
 
    [Fact]
    public void CTag()
    {
        var comment = "Class <c>Point</c> models a point in a two-dimensional plane.";
        var expected = "Class Point models a point in a two-dimensional plane.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void ExampleAndCodeTags()
    {
        var comment = @"This method changes the point's location by the given x- and y-offsets.
            <example>For example:
            <code>
            Point p = new Point(3,5);
            p.Translate(-1,3);
            </code>
            results in <c>p</c>'s having the value (2,8).
            </example>";
 
        var expected = "This method changes the point's location by the given x- and y-offsets. For example:\r\n\r\n            Point p = new Point(3,5);\r\n            p.Translate(-1,3);\r\n            \r\n\r\nresults in p's having the value (2,8).";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void ListTag()
    {
        var comment = @"Here is an example of a bulleted list:
        <list type=""bullet"">
        <item>
        <description>Item 1.</description>
        </item>
        <item>
        <description>Item 2.</description>
        </item>
        </list>";
 
        var expected = "Here is an example of a bulleted list:\r\n\r\n• Item 1.\r\n• Item 2.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void ParaTag()
    {
        var comment = @"This is the entry point of the Point class testing program.
        <para>This program tests each method and operator, and
        is intended to be run after any non-trivial maintenance has
        been performed on the Point class.</para>";
 
        var expected =
@"This is the entry point of the Point class testing program.
 
This program tests each method and operator, and is intended to be run after any non-trivial maintenance has been performed on the Point class.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void TestPermissionTag()
    {
        var comment = @"<permission cref=""System.Security.PermissionSet"">Everyone can access this method.</permission>";
 
        var expected = @"Everyone can access this method.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeTag()
    {
        var comment = @"<see cref=""AnotherFunction""/>";
 
        var expected = @"AnotherFunction";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlsoTag()
    {
        var comment = @"<seealso cref=""AnotherFunction""/>";
 
        var expected = @"AnotherFunction";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void ValueTag()
    {
        var comment = @"<value>Property <c>X</c> represents the point's x-coordinate.</value>";
 
        var expected = @"Property X represents the point's x-coordinate.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void TestParamRefTag()
    {
        var comment =
@"This constructor initializes the new Point to 
(<paramref name=""xor""/>,<paramref name=""yor""/>).";
 
        var expected = "This constructor initializes the new Point to (xor,yor).";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void TestTypeParamRefTag()
    {
        var comment = @"This method fetches data and returns a list of  <typeparamref name=""Z""/>.";
 
        var expected = @"This method fetches data and returns a list of Z.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Whitespace1()
    {
        var comment = "  This has extra whitespace.  ";
 
        var expected = "This has extra whitespace.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Whitespace2()
    {
        var comment =
@"
This has extra
whitespace.
";
 
        var expected = "This has extra whitespace.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Whitespace3()
    {
        var comment = "This  has  extra  whitespace.";
        var expected = "This has extra whitespace.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Paragraphs1()
    {
        var comment =
@"
<para>This is part of a paragraph.</para>
";
        var expected = "This is part of a paragraph.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Paragraphs2()
    {
        var comment =
@"
<para>This is part of a paragraph.</para>
<para>This is also part of a paragraph.</para>
";
 
        var expected =
@"This is part of a paragraph.
 
This is also part of a paragraph.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Paragraphs3()
    {
        var comment =
@"
This is a summary.
<para>This is part of a paragraph.</para>
";
 
        var expected =
@"This is a summary.
 
This is part of a paragraph.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void Paragraphs4()
    {
        var comment =
@"
<para>This is part of a paragraph.</para> This is part of the summary, too.
";
 
        var expected =
@"This is part of a paragraph.
 
This is part of the summary, too.";
 
        TestFormat(comment, expected);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32838")]
    public void Paragraphs5()
    {
        var comment =
@"
<para>This is part of a<br/>paragraph.</para>
<para>This is also part of a paragraph.</para>
";
 
        var expected =
@"This is part of a
paragraph.
 
This is also part of a paragraph.";
 
        TestFormat(comment, expected);
    }
 
    [Theory]
    [InlineData("<br/><br/>")]
    [InlineData("<br/><br/><br/>")]
    [WorkItem("https://github.com/dotnet/roslyn/issues/32838")]
    public void Paragraphs6(string lineBreak)
    {
        var comment =
$@"
<para>This is part of a{lineBreak}paragraph.</para>
<para>This is also part of a paragraph.</para>
";
 
        var expected =
@"This is part of a
 
paragraph.
 
This is also part of a paragraph.";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See1()
    {
        var comment = @"See <see cref=""T:System.Object"" />";
 
        var expected = "See System.Object";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See2()
    {
        var comment = @"See <see />";
 
        var expected = @"See";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See3()
    {
        var comment = @"See <see langword=""true"" />";
 
        var expected = "See true";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See4()
    {
        var comment = @"See <see href=""https://github.com"" />";
 
        var expected = "See https://github.com";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See5()
    {
        var comment = @"See <see href=""https://github.com"">GitHub</see>";
 
        var expected = "See GitHub";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void See6()
    {
        var comment = @"See <see href=""https://github.com""></see>";
 
        var expected = "See https://github.com";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso1()
    {
        var comment = @"See also <seealso cref=""T:System.Object"" />";
 
        var expected = @"See also System.Object";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso2()
    {
        var comment = @"See also <seealso />";
 
        var expected = @"See also";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso3()
    {
        var comment = @"See also <seealso langword=""true"" />";
 
        var expected = "See also true";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso4()
    {
        var comment = @"See also <seealso href=""https://github.com"" />";
 
        var expected = "See also https://github.com";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso5()
    {
        var comment = @"See also <seealso href=""https://github.com"">GitHub</seealso>";
 
        var expected = "See also GitHub";
 
        TestFormat(comment, expected);
    }
 
    [Fact]
    public void SeeAlso6()
    {
        var comment = @"See also <seealso href=""https://github.com""></seealso>";
 
        var expected = "See also https://github.com";
 
        TestFormat(comment, expected);
    }
}