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
2 changes: 1 addition & 1 deletion .github/workflows/actions-audit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
go-version: 'stable'

- name: Install actionlint
run: go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.7
run: go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.12

- name: Run actionlint
run: actionlint -color
Expand Down
34 changes: 34 additions & 0 deletions tests/Wolfgang.TryPattern.Tests.Unit/CompileFailureMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#if NET8_0_OR_GREATER
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;

namespace Wolfgang.TryPattern.Tests.Unit;

/// <summary>
/// Builds the assertion message the snippet-compilation tests
/// (<see cref="DocExampleCompilationTests"/>, <see cref="ReadmeExampleCompilationTests"/>)
/// fail with: the compiler errors, the offending snippet indented for
/// copy-paste reproduction, and a repo-specific hint on where to fix it.
/// </summary>
internal static class CompileFailureMessage
{
internal static string Format
(
string header,
IEnumerable<Diagnostic> errors,
string snippet,
string hint
)
{
string errorList = string.Join(Environment.NewLine, errors.Select(e => $" {e}"));
string reproHint = string.Join(Environment.NewLine, snippet.Split('\n').Select(l => $" {l.TrimEnd()}"));
return
$"{header}{Environment.NewLine}" +
$"Errors:{Environment.NewLine}{errorList}{Environment.NewLine}" +
$"Snippet:{Environment.NewLine}{reproHint}{Environment.NewLine}" +
hint;
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#if NET8_0_OR_GREATER
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;

namespace Wolfgang.TryPattern.Tests.Unit;

public class CompileFailureMessageTests
{
[Fact]
public void Format_lists_every_error_then_the_indented_snippet_then_the_hint()
{
const string snippet = "class C\n{\n void M() { int x = ; } \n}";
var errors = CSharpSyntaxTree.ParseText(snippet)
.GetDiagnostics()
.Where(d => d.Severity == DiagnosticSeverity.Error)
.ToList();
Assert.NotEmpty(errors);

string message = CompileFailureMessage.Format("Fence #3 failed to compile.", errors, snippet, "Fix the fence.");

string[] lines = message.Split(Environment.NewLine);
Assert.Equal("Fence #3 failed to compile.", lines[0]);
Assert.Equal("Errors:", lines[1]);
Assert.All(errors, e => Assert.Contains($" {e}", lines));
Assert.Contains("Snippet:", lines);
Assert.Contains(" void M() { int x = ; }", lines); // 4-space indent added, trailing whitespace trimmed
Assert.Equal("Fix the fence.", lines[^1]);
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,11 @@ private static void Process(int item) { }

if (errors.Count > 0)
{
string errorList = string.Join(Environment.NewLine, errors.Select(e => $" {e}"));
string reproHint = string.Join(Environment.NewLine, snippet.Split('\n').Select(l => $" {l.TrimEnd()}"));
Assert.Fail(
$"XML doc example on `{memberName}` (example index {index}) failed to compile.{Environment.NewLine}" +
$"Errors:{Environment.NewLine}{errorList}{Environment.NewLine}" +
$"Snippet:{Environment.NewLine}{reproHint}{Environment.NewLine}" +
$"Fix the snippet in the source XML doc, or if it needs an additional using, add it inline in the `<code>` block.");
Assert.Fail(CompileFailureMessage.Format(
$"XML doc example on `{memberName}` (example index {index}) failed to compile.",
errors,
snippet,
"Fix the snippet in the source XML doc, or if it needs an additional using, add it inline in the `<code>` block."));
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions tests/Wolfgang.TryPattern.Tests.Unit/FuzzTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
// pulled from the test output.

using System;
using System.Diagnostics.CodeAnalysis;
using FsCheck;
using FsCheck.Xunit;
using Xunit;

namespace Wolfgang.TryPattern.Tests.Unit;

// Never executed by the PR gate (`--filter "Category!=Fuzz"`), only by the
// scheduled fuzz.yaml run, so the instrumented test assembly would score it
// at 0% on every PR. The same properties ARE measured through PropertyTests.
[ExcludeFromCodeCoverage]
[Trait("Category", "Fuzz")]
public class FuzzTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,7 @@ public static IEnumerable<object[]> AllReadmeFences()
[MemberData(nameof(AllReadmeFences))]
public void Readme_fence_compiles(int index, string snippet)
{
if (snippet is null)
{
throw new ArgumentNullException(nameof(snippet));
}
_ = snippet ?? throw new ArgumentNullException(nameof(snippet));

// Wrap in an async method body so `await` / free-standing
// statements both compile. Async is superset — synchronous
Expand Down Expand Up @@ -165,13 +162,11 @@ private static void Process(int item) { }

if (errors.Count > 0)
{
string errorList = string.Join(Environment.NewLine, errors.Select(e => $" {e}"));
string reproHint = string.Join(Environment.NewLine, snippet.Split('\n').Select(l => $" {l.TrimEnd()}"));
Assert.Fail(
$"README fence #{index} failed to compile.{Environment.NewLine}" +
$"Errors:{Environment.NewLine}{errorList}{Environment.NewLine}" +
$"Snippet:{Environment.NewLine}{reproHint}{Environment.NewLine}" +
$"Fix the fence in README.md, or if it uses framework types the test project doesn't reference (SqlConnection, ASP.NET Core, EF dbContext), add a marker string to ReadmeExampleCompilationTests.SkipMarkers.");
Assert.Fail(CompileFailureMessage.Format(
$"README fence #{index} failed to compile.",
errors,
snippet,
"Fix the fence in README.md, or if it uses framework types the test project doesn't reference (SqlConnection, ASP.NET Core, EF dbContext), add a marker string to ReadmeExampleCompilationTests.SkipMarkers."));
}
}

Expand Down
Loading