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
16 changes: 0 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,6 @@ jobs:
- name: Test
run: dotnet test -f ${{ matrix.framework }} --no-build --no-restore

test-documentation:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
8.0.x

- name: Build documentation
run: dotnet run --project 'build/build.fsproj'

format-verify:
runs-on: ubuntu-latest
steps:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [UPDATE] Migrate documentation to docfx platform. https://github.com/dotnet/docfx
* [UPDATE][BREAKING] Nullability is enabled for public api for .NET Core TFMs
* [UPDATE] Migrate to slnx format for solution file
* [UPDATE] Migrate documentation validation from build.fsproj to Roslyn code generator

### 5.3.0 (October 2024)

Expand Down
4 changes: 0 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,4 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<PropertyGroup>
<OutputPath>$(MSBuildThisFileDirectory)\bin\$(Configuration)\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>

</Project>
6 changes: 2 additions & 4 deletions NSubstitute.slnx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<Solution>
<Folder Name="/build/">
<File Path="build/build.fs" />
<File Path="build/ExtractDocs.fs" />
</Folder>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path="BreakingChanges.md" />
Expand All @@ -16,5 +12,7 @@
<Folder Name="/tests/">
<Project Path="tests/NSubstitute.Acceptance.Specs/NSubstitute.Acceptance.Specs.csproj" />
<Project Path="tests/NSubstitute.Benchmarks/NSubstitute.Benchmarks.csproj" />
<Project Path="tests/NSubstitute.Documentation.Tests.Generator/NSubstitute.Documentation.Tests.Generator.csproj" Id="d031abb6-0702-4eee-89f6-dd3e9af0573b" />
<Project Path="tests/NSubstitute.Documentation.Tests/NSubstitute.Documentation.Tests.csproj" Id="ed043d85-3df4-4878-ab35-ce5e533f1a30" />
</Folder>
</Solution>
63 changes: 0 additions & 63 deletions build/ExtractDocs.fs

This file was deleted.

71 changes: 0 additions & 71 deletions build/build.fs

This file was deleted.

20 changes: 0 additions & 20 deletions build/build.fsproj

This file was deleted.

25 changes: 0 additions & 25 deletions build/build.sln

This file was deleted.

2 changes: 1 addition & 1 deletion src/NSubstitute/NSubstitute.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<AssemblyOriginatorKeyFile>nsubstitute.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<DocumentationFile>..\..\bin\$(Configuration)\NSubstitute\$(TargetFramework)\NSubstitute.xml</DocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
Expand Down
2 changes: 1 addition & 1 deletion tests/NSubstitute.Benchmarks/NSubstitute.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Text;
using System.Text.RegularExpressions;

namespace NSubstitute.Documentation.Tests.Generator;

[Generator]
public sealed class DocumentationTestsGenerator : IIncrementalGenerator
{
private static readonly Regex markdownCodeRegex = new("```(?<tag>\\w+)(?<contents>(?s:.*?))```?");
private static readonly Regex typeOrTestDeclarationRegex = new(@"(\[Test\]|(public |private |protected )?(class |interface )\w+\s*\{)");

public void Initialize(IncrementalGeneratorInitializationContext context)
{
var markdownFiles = context.AdditionalTextsProvider
.Where(static file => Path.GetExtension(file.Path) == ".md");

context.RegisterSourceOutput(markdownFiles, static (context, markdownFile) =>
{
var testsClassName = GenerateTestsClassName(markdownFile);
var testClassContent = GenerateTestClassContent(testsClassName, markdownFile);
var formattedTestClassContent = FormatCode(testClassContent);
context.AddSource($"{testsClassName}.g.cs", formattedTestClassContent);
});
}

public static string FormatCode(string code)
{
return CSharpSyntaxTree.ParseText(code)
.GetRoot()
.NormalizeWhitespace()
.SyntaxTree
.GetText()
.ToString();
}

private static string GenerateTestsClassName(AdditionalText markdownFile)
{
return $"Tests_{Path.GetFileNameWithoutExtension(markdownFile.Path).Replace("-", "_")}";
}

private static string GenerateTestClassContent(string testsClassName, AdditionalText markdownFile)
{
ParseMarkdownCodeBlocks(markdownFile, out var declarations, out var snippets);

var testClassContent = new StringBuilder();

testClassContent.AppendLine(
$$"""
using NUnit.Framework;
using System.ComponentModel;
using NSubstitute.Extensions;
using NSubstitute.Compatibility;
using NSubstitute.ExceptionExtensions;

namespace NSubstitute.Documentation.Tests.Generated;

public sealed class {{testsClassName}}
{
""");

foreach (var declaration in declarations)
{
testClassContent.AppendLine(declaration);
}

for (int testCaseNumber = 0; testCaseNumber < snippets.Count; testCaseNumber++)
{
testClassContent.AppendLine(
$$"""
[Test]
public void Test{{testCaseNumber}}()
{
{{snippets[testCaseNumber]}}
}
""");
}

testClassContent.AppendLine("}");

return testClassContent.ToString();
}

private static void ParseMarkdownCodeBlocks(AdditionalText markdownFile, out List<string> declarations, out List<string> snippets)
{
var markdownContent = markdownFile.GetText().ToString();

declarations = [];
snippets = [];

foreach (Match match in markdownCodeRegex.Matches(markdownContent))
{
var codeBlockTitle = match.Groups[1].Value;
var codeBlockContent = match.Groups[2].Value;

if (codeBlockTitle == "csharp")
{
if (typeOrTestDeclarationRegex.IsMatch(codeBlockContent))
{
declarations.Add(codeBlockContent);
}
else
{
snippets.Add(codeBlockContent);
}
}
else if (codeBlockTitle == "requiredcode")
{
declarations.Add(codeBlockContent);
}
}
}

}
Loading
Loading