Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CodeBlocker.Test/CodeBlockerExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ public void AutoGeneratedHeaderWritesABlankCopyrightLineAsABareComment()
codeBlocker.ToString());
}

[TestMethod]
[DataRow("\n", DisplayName = "LF")]
[DataRow("\r\n", DisplayName = "CRLF")]
[DataRow("\r", DisplayName = "CR")]
[DataRow("\u0085", DisplayName = "NEL")]
[DataRow("\u2028", DisplayName = "LINE SEPARATOR")]
[DataRow("\u2029", DisplayName = "PARAGRAPH SEPARATOR")]
public void AutoGeneratedHeaderIgnoresATrailingLineTerminatorOnTheCopyright(string terminator)
{
using CodeBlocker codeBlocker = Create();

codeBlocker.WriteAutoGeneratedHeader($"Copyright (c) X{terminator}");

Assert.AreEqual("// Copyright (c) X\n// <auto-generated />\n\n", codeBlocker.ToString());
}

[TestMethod]
public void AutoGeneratedHeaderKeepsABlankLineBeforeATrailingLineTerminator()
{
using CodeBlocker codeBlocker = Create();

codeBlocker.WriteAutoGeneratedHeader("A\n\nB\n");

Assert.AreEqual("// A\n//\n// B\n// <auto-generated />\n\n", codeBlocker.ToString());
}

[TestMethod]
public void NullableDirectivesAreWrittenVerbatim()
{
Expand Down
24 changes: 24 additions & 0 deletions CodeBlocker.Test/DocCommentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ public void AMultiLineSummaryPrefixesEveryLine()
Render(documentation));
}

[TestMethod]
[DataRow("\n", DisplayName = "LF")]
[DataRow("\r\n", DisplayName = "CRLF")]
[DataRow("\u2028", DisplayName = "LINE SEPARATOR")]
public void ASingleLineSummaryWithATrailingLineTerminatorStaysOnOneLine(string terminator) =>
Assert.AreEqual(
"/// <summary>Hello.</summary>\n",
Render(new DocComment { Summary = $"Hello.{terminator}" }));

[TestMethod]
public void AMultiLineSummaryWithATrailingLineTerminatorHasNoEmptyLine() =>
Assert.AreEqual(
"/// <summary>\n/// A\n/// B\n/// </summary>\n",
Render(new DocComment { Summary = "A\nB\n" }));

[TestMethod]
public void ANamedTagWithATrailingLineTerminatorStaysOnOneLine()
{
DocComment documentation = new();
documentation.Params.Add(new DocTag { Name = "a", Text = "The value.\n" });

Assert.AreEqual("/// <param name=\"a\">The value.</param>\n", Render(documentation));
}

[TestMethod]
public void ABlankLineInsideATagIsWrittenWithoutTrailingWhitespace()
{
Expand Down
18 changes: 15 additions & 3 deletions CodeBlocker/LineTerminators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,21 @@ internal static class LineTerminators
/// the comment and into the code.
/// </summary>
/// <param name="text">The text to split.</param>
/// <returns>The lines, without their terminators. Text with no terminator is a single line.</returns>
internal static string[] Split(string text) =>
text.Replace("\r\n", "\n").Split(Characters);
/// <returns>
/// The lines, without their terminators. Text with no terminator is a single line. A trailing
/// terminator leaves an empty tail, which is not a line of its own, so <c>"A\n"</c> is the one
/// line <c>A</c>; a blank line inside the text, as in <c>"A\n\nB"</c>, is kept.
/// </returns>
internal static string[] Split(string text)
{
string[] lines = text.Replace("\r\n", "\n").Split(Characters);
if (lines.Length > 1 && lines[^1].Length == 0)
{
Array.Resize(ref lines, lines.Length - 1);
}

return lines;
}

/// <summary>
/// Reports whether text contains any line terminator the C# compiler recognises.
Expand Down
Loading