Thunder.DocSnippets 0.1.3

dotnet add package Thunder.DocSnippets --version 0.1.3
                    
NuGet\Install-Package Thunder.DocSnippets -Version 0.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Thunder.DocSnippets" Version="0.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Thunder.DocSnippets" Version="0.1.3" />
                    
Directory.Packages.props
<PackageReference Include="Thunder.DocSnippets" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Thunder.DocSnippets --version 0.1.3
                    
#r "nuget: Thunder.DocSnippets, 0.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Thunder.DocSnippets@0.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Thunder.DocSnippets&version=0.1.3
                    
Install as a Cake Addin
#tool nuget:?package=Thunder.DocSnippets&version=0.1.3
                    
Install as a Cake Tool

DocSnippets

Make your C# XML doc <code> examples runnable as unit tests — the Rust doctest experience for .NET.

DocSnippets is a Roslyn source generator. Add the package, and every <code> block in your XML documentation becomes a compiled, executable NUnit/xUnit/MSTest test method. No extra tooling, no checked-in generated files.

<PackageReference Include="Thunder.DocSnippets" Version="..." />

Quick start

  1. Add DocSnippets to your test project:

    <PackageReference Include="Thunder.DocSnippets" Version="..." />
    
  2. Run dotnet test. Done.

DocSnippets ships an MSBuild .targets file that automatically wires up the adjacent source project's .cs files as AdditionalFiles — no manual <ItemGroup> configuration required.


Writing snippets

Any <code> block in an XML doc comment is picked up automatically:

/// <summary>Adds two integers.</summary>
/// <example>
/// <code>
/// var result = calculator.Add(1, 2); // => 3
/// </code>
/// </example>
public int Add(int a, int b) => a + b;

The assertion comment is transformed into a framework-appropriate equality check at generation time. No assertion library is required in the snippet itself.

Inline assertion patterns

All four comment styles work on both declaration lines and expression lines:

Pattern Example Meaning
// => VALUE var x = f(); // => 42 Assert x equals 42
// result: VALUE var x = f(); // result: 42 Assert x equals 42
// VARNAME: VALUE DoSetup(); // myVar: 42 Assert myVar equals 42
// VALUE (bare literal) var x = f(); // 42 Assert x equals 42

On a declaration line (var x = f(); // => 3), the generator splits the line into the declaration statement and a separate assertion using the declared variable name. On an expression line (f(); // => 3), the entire expression becomes the assertion subject.

Bare literal comments (// 42, // true, // "hello") are only treated as assertions when the comment contains an unambiguous C# literal. Non-literal comments (// sum of values, // see above) are left unchanged.

Excluding a snippet

Add // doctest-ignore on the first line of any <code> block to skip it:

/// <code>
/// // doctest-ignore
/// // This example is illustrative — not executable.
/// var x = SomeExternalCall();
/// </code>

Compile-only snippets

Some examples are valid documentation but not self-contained — they reference live objects (GraphicsDevice, SpriteBatch, etc.) that can't be instantiated in a test without boilerplate that would pollute the rendered docs. Mark these with // doctest-compile-only:

/// <code>
/// // doctest-compile-only
/// spriteBatch.Begin();
/// spriteBatch.Draw(texture, position, Color.White);
/// spriteBatch.End();
/// </code>

The generated test is compiled (so rename refactors and API breakages are caught) but skipped at runtime. DocSnippets automatically stubs any undeclared identifiers (spriteBatch, texture, position) by looking them up in the project's symbol table — no manual stub declarations needed. The skip attribute varies by framework:

Framework Attribute
NUnit [Test, Ignore("compile-only")]
xUnit [Fact(Skip = "compile-only")]
MSTest [TestMethod, Ignore]

Assertion comments (// => VALUE) are not transformed in compile-only snippets — they are emitted verbatim as comments.


Configuration (docsnippets.json)

Add a docsnippets.json file alongside the source files (it is picked up automatically as an AdditionalFile by the shipped MSBuild targets) to configure the generator:

{
  "snippetMode": "opt-out",
  "assertionStyle": "NUnit",
  "implicitUsings": ["MyLib", "MyLib.Models"]
}
Key Values Default Description
snippetMode "opt-out", "opt-in" "opt-out" opt-out: all <code> blocks run. opt-in: only blocks containing // doctest run.
assertionStyle "NUnit", "XUnit", "MSTest" (auto-detect) Override the auto-detected test framework.
implicitUsings Array of namespace strings [] Namespaces added as using to every generated test class.

Opt-in mode

Mark individual snippets with // doctest to include them when snippetMode is "opt-in":

/// <code>
/// // doctest
/// var x = Multiply(3, 4); // => 12
/// </code>

InternalsVisibleTo

If your snippets reference internal types, add this to your source project:

[assembly: InternalsVisibleTo("YourTestProject")]

Without it, snippets referencing internal members produce CS0122 errors that can be hard to diagnose.


Known limitations

  • Tuple deconstructionvar (a, b) = f(); // => ... is not supported. Use a separate assertion line.
  • Async snippets — snippets containing await are not supported. The emitted test method is synchronous; await will produce a compile error.
  • Single-assembly scanning — only direct ProjectReference source projects are scanned. Transitive references are not.

What's new in v0.1.2

  • // doctest-compile-only — compile-checked-but-skipped snippets with automatic stub inference for undeclared identifiers

What's new in v0.1.1

  • Approximate float assertions// => ~3.14 (one decimal place tolerance), // => ~3.14 (2dp) for explicit precision
  • Compile-only snippets — see above

What's in v0.1.0

  • Inline assertion patterns — four comment styles on both declaration and expression lines: // => VALUE, // result: VALUE, // VARNAME: VALUE, bare literal // 42
  • #line diagnostics — build errors in generated test methods now point to the original source line, not the generated file
  • assertionStyle config override — override auto-detected framework via docsnippets.json
  • //=> arrow alias//=> accepted as shorthand for // =>
  • Assert value in test method nameAdd_ShouldBe_3 naming from // => assertions
  • Overload disambiguation — param-type suffix on overloaded method test names
  • Operator and destructor name sanitization — valid C# identifiers for operator +, ~MyClass, etc.
  • snippetMode: opt-in — only run explicitly marked snippets
  • MSBuild auto-wiringAdditionalFiles glob injected via shipped .targets file
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.3 99 4/30/2026
0.1.2 87 4/30/2026
0.1.1 104 4/28/2026
0.1.1-preview9 109 4/27/2026
0.1.1-preview8 97 4/27/2026
0.1.0 99 4/26/2026
0.1.0-preview7.1 57 4/26/2026
0.1.0-preview7 94 4/26/2026
0.1.0-preview6 92 4/25/2026