Skip to content
Open
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
24 changes: 24 additions & 0 deletions CodeBlocker.Test/CodeBlockerExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,30 @@ public void NoUsingsWritesNothingIncludingTheBlankLine()
Assert.AreEqual(string.Empty, emptySequence.ToString());
}

[TestMethod]
public void BlankUsingEntriesAreSkipped()
{
// A generator that builds optional usings as `condition ? "Ns" : ""` must not get `using ;`.
using CodeBlocker codeBlocker = Create();

codeBlocker.WriteUsings("System", "", " ", null!, "System.Linq");

Assert.AreEqual("using System;\nusing System.Linq;\n\n", codeBlocker.ToString());
}

[TestMethod]
public void OnlyBlankUsingEntriesWriteNothingIncludingTheBlankLine()
{
using CodeBlocker arrayOverload = Create();
using CodeBlocker sequenceOverload = Create();

arrayOverload.WriteUsings("", " ", "\t");
sequenceOverload.WriteUsings(new List<string> { "", " " });

Assert.AreEqual(string.Empty, arrayOverload.ToString());
Assert.AreEqual(string.Empty, sequenceOverload.ToString());
}

[TestMethod]
public void APreambleComposesWithConsistentSpacing()
{
Expand Down
14 changes: 14 additions & 0 deletions CodeBlocker.Test/TemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,20 @@ private class Inner
public void AnEmptySourceFileWritesNothing() =>
Assert.AreEqual(string.Empty, Render(codeBlocker => codeBlocker.AddSourceFile(new SourceFileTemplate())));

[TestMethod]
public void ASourceFileSkipsBlankUsings()
{
SourceFileTemplate file = new()
{
Namespace = "Contoso",
Usings = { "System", "", "System.Linq" },
};

Assert.AreEqual(
"namespace Contoso;\n\nusing System;\nusing System.Linq;\n\n",
Render(codeBlocker => codeBlocker.AddSourceFile(file)));
}

[TestMethod]
public void ASourceFileWithAnInvalidClassWritesNothing()
{
Expand Down
11 changes: 9 additions & 2 deletions CodeBlocker/CodeBlockerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ public static CodeBlocker WriteFileScopedNamespace(this CodeBlocker codeBlocker,

/// <summary>
/// Writes one <c>using</c> directive per entry followed by a blank line, or nothing at all when
/// the sequence is empty.
/// the sequence has no namespaces in it.
/// </summary>
/// <param name="codeBlocker">The <see cref="CodeBlocker"/> to write to.</param>
/// <param name="usings">
/// The namespaces to import, without the <c>using</c> keyword or the trailing semicolon. An
/// entry may carry a modifier or alias — <c>static System.Math</c>, <c>Alias = System.Text</c> —
/// because it is written verbatim after the keyword.
/// because it is written verbatim after the keyword. Entries that are <see langword="null"/>,
/// empty or whitespace are skipped, so a generator can pass <c>condition ? "Some.Namespace" : ""</c>
/// without producing <c>using ;</c>.
/// </param>
/// <returns>The same <see cref="CodeBlocker"/>, for chaining.</returns>
/// <exception cref="ArgumentNullException">
Expand All @@ -115,6 +117,11 @@ public static CodeBlocker WriteUsings(this CodeBlocker codeBlocker, IEnumerable<
bool wroteAny = false;
foreach (string usingDirective in usings)
{
if (string.IsNullOrWhiteSpace(usingDirective))
{
continue;
}

codeBlocker.WriteLine($"using {usingDirective};");
wroteAny = true;
}
Expand Down
Loading