Skip to content

Add generator groundwork and document generated-test settings#163

Merged
cwinland merged 6 commits into
feature/122-graph-metadata-slicefrom
feature/162-settings-platform-targeting
May 6, 2026
Merged

Add generator groundwork and document generated-test settings#163
cwinland merged 6 commits into
feature/122-graph-metadata-slicefrom
feature/162-settings-platform-targeting

Conversation

@cwinland
Copy link
Copy Markdown
Owner

@cwinland cwinland commented May 4, 2026

Summary

Validation

  • dotnet test "C:\Users\chriswin\source\repos\FastMoq\FastMoq.Tests\FastMoq.Tests.csproj"
  • dotnet test "C:\Users\chriswin\source\repos\FastMoq\FastMoq.Analyzers.Tests\FastMoq.Analyzers.Tests.csproj"
  • dotnet test "C:\Users\chriswin\source\repos\FastMoq\FastMoq.Analyzers.Tests\FastMoq.Analyzers.Tests.csproj" --filter FullyQualifiedName~GeneratedHarnessSourceGeneratorTests

Issue Links

Copilot AI review requested due to automatic review settings May 4, 2026 16:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR lays the first end-to-end groundwork for FastMoq’s explicit generated-harness path by introducing a new source generator project, adding runtime constructor-planning/graph metadata APIs the generator can target, and documenting the emerging generated-test settings + targeting contract.

Changes:

  • Add FastMoq.Generators with an incremental generator that emits MockerTestBase<T> constructor-signature metadata for explicit [FastMoqGeneratedTestTarget] partial harnesses.
  • Add public constructor-planning models (InstanceConstructionRequest/InstanceConstructionPlan) plus internal graph/bootstrap descriptor plumbing to support runtime + generated harness parity.
  • Introduce/expand analyzer-side package-layout + target-shape matrix support and document the generated-test settings direction (#162), plus add benchmark evidence for the generated harness setup path.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
FastMoq/packages.lock.json Locks updated transitive dependencies (incl. EFCore patch, Castle.Core, DurableTask-related deps).
FastMoq/FastMoq.csproj Packs generator artifacts and references FastMoq.Generators as an analyzer-style asset.
FastMoq.Tests/MockerTestBaseConstructionPlanTests.cs Adds tests for MockerTestBase<T> construction-plan + bootstrap descriptor behavior.
FastMoq.Tests/InternalSampleServiceTests.cs Removes FluentAssertions using in favor of the repo’s assertion setup.
FastMoq.Tests/InstanceConstructionPlanTests.cs Adds tests for Mocker.CreateConstructionPlan(...) parameter-source and selection outcomes.
FastMoq.Tests/InstanceConstructionGraphTests.cs Adds tests for construction graph projection and harness hook mapping.
FastMoq.Tests/GlobalUsings.cs Switches test assertions to AwesomeAssertions global usings.
FastMoq.Tests/FastMoq.Tests.csproj Updates test dependencies to use AwesomeAssertions (drops FluentAssertions).
FastMoq.Tests.Web/GlobalUsings.cs Switches web test project global usings to AwesomeAssertions.
FastMoq.sln Adds the new FastMoq.Generators project to the main solution.
FastMoq.Generators/GeneratedHarnessSourceGenerator.cs New incremental generator emitting constructor-signature metadata for explicit harness targets.
FastMoq.Generators/FastMoq.Generators.csproj New generator project configuration + packing under analyzers/dotnet/cs.
FastMoq.Core/Models/InstanceConstructionRequest.cs New public request model for constructor-selection intent.
FastMoq.Core/Models/InstanceConstructionPlan.cs New public resolved plan model + parameter plan + parameter-source enum.
FastMoq.Core/Models/InstanceConstructionGraph.cs Internal graph model projecting plan + ordered dependency nodes/edges.
FastMoq.Core/Models/ComponentHarnessBootstrapDescriptor.cs Internal descriptor for harness bootstrap knobs + graph projection.
FastMoq.Core/MockerTestBase_Constructors.cs Adds component construction request/plan helpers + graph/bootstrap descriptor projection.
FastMoq.Core/Mocker.cs Renames internal constructor-selection request struct to avoid collision with new public API model.
FastMoq.Core/Mocker.ConstructionPlan.cs Implements CreateConstructionPlan(...), internal graph creation, and request-mapping helpers.
FastMoq.Core/KnownTypeRegistry.cs Adds query helpers to detect known-type / managed-instance resolution for planning decisions.
FastMoq.Benchmarks/GeneratedHarnessSetupBenchmarks.cs Adds benchmark comparing generated harness bootstrap projection vs runtime fallback.
FastMoq.Benchmarks/FastMoq.Benchmarks.csproj References generator as analyzer for benchmarks + adds Abstractions reference.
FastMoq.Analyzers/GeneratedTestTargetShapeRules.cs Adds shared package-layout + target-shape rule model for analyzers/generators.
FastMoq.Analyzers/FastMoqAnalysisHelpers.cs Adds package matrix computation helpers and supporting constants.
FastMoq.Analyzers/Analyzers/MissingHelperPackageAnalyzer.cs Refactors to compilation-start analysis using the shared package matrix.
FastMoq.Analyzers.Tests/GlobalUsings.cs Adds AwesomeAssertions global usings for analyzer/generator tests.
FastMoq.Analyzers.Tests/GeneratorPackageMatrixTests.cs Adds tests for package layout classification (core-only/split/aggregate).
FastMoq.Analyzers.Tests/GeneratedHarnessSourceGeneratorTests.cs Adds generator-driver + representative compilation/parity tests for harness generation.
FastMoq.Analyzers.Tests/FastMoq.Analyzers.Tests.csproj Adds references needed for generator + package-matrix testing.
FastMoq.Analyzers.Tests/AnalyzerTestHelpers.cs Extends test project builder to model more package-layout combinations (aggregate/web/db/azure).
FastMoq.Abstractions/Generators/FastMoqGeneratedTestTargetAttribute.cs Adds the explicit opt-in attribute used to mark harness targets for generation.
FastMoq-Release.sln Adds FastMoq.Generators to the release solution topology.
docs/roadmap/README.md Updates roadmap narrative to reflect shipped generator MVP + #162 settings gate.
docs/roadmap/generator-roadmap.md Updates generator roadmap baseline/status to reflect the new generator slice and sequencing.
docs/roadmap/generated-test-settings.md New design doc capturing the intended shared generated-test settings contract for #162.
docs/benchmarks/results/generated-harness-setup-net8.md New benchmark results doc for generated harness bootstrap projection.
docs/benchmarks/README.md Documents how to run and where to find the generated harness benchmark results.
Directory.Packages.props Removes FluentAssertions central package entry (tests now use AwesomeAssertions).

Comment thread FastMoq.Analyzers.Tests/GlobalUsings.cs
Copilot AI review requested due to automatic review settings May 4, 2026 19:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 40 out of 40 changed files in this pull request and generated 2 comments.

Comment thread FastMoq.sln
Comment thread FastMoq-Release.sln Outdated
@cwinland cwinland changed the base branch from master to feature/122-graph-metadata-slice May 6, 2026 19:31
* Expand generated scenario scaffold executors

* Add generated shared setup scaffold hooks

* Strengthen generated shared setup hook ordering test

* Document generated scenario scaffold members

* docs: align generator roadmap with current scope

* Widen generated harness smoke test coverage (#165)

* Widen generated harness smoke test coverage

* Fix: Escape C# keywords in generated method invocations

When component methods are named with C# keywords (e.g., @Class, @return),
the unescaped IMethodSymbol.Name resulted in invalid emitted code like
'component.class()' instead of 'component.@Class()'.

- Add EscapeIdentifierIfKeyword helper using SyntaxFacts.GetKeywordKind
- Apply escaping in CreateGeneratedTestMethodModel to all method references
- Add [Fact] test covering keyword methods (@Class, @interface, @return)

Addresses code review comment on GeneratedHarnessSourceGenerator.cs

* feat(generators): wire FastMoqGeneratedTestFramework MSBuild property into generator pipeline (#123 slice 2) (#166)

Wire FastMoqGeneratedTestFramework MSBuild property into generator pipeline

- Add CompilerVisibleProperty for FastMoqGeneratedTestFramework to generator csproj
- Read build_property.FastMoqGeneratedTestFramework in incremental pipeline via AnalyzerConfigOptionsProvider
- Combine frameworkSetting with targets pipeline; pass to EmitSource
- When value is 'none' (case-insensitive), suppress xUnit smoke-test emission regardless of metadata
- Add TestAnalyzerConfigOptionsProvider / TestAnalyzerConfigOptions nested helpers for test isolation
- Add 3 new [Fact] tests covering none suppression, explicit xunit enable, and case-insensitive none

Part of #123
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Comment on lines +494 to +497
private static void EmitSource(SourceProductionContext context, GeneratedHarnessTargetModel target, string frameworkSetting)
{
var emitXUnitSmokeTests = target.EmitXUnitSmokeTests &&
!string.Equals(frameworkSetting, FrameworkSettingNone, StringComparison.OrdinalIgnoreCase);
Comment on lines +555 to +574
AppendIndentedLine(sourceBuilder, 2, "/// <summary>");
AppendIndentedLine(sourceBuilder, 2, "/// Executes the generated arrange, act, assert, and verify scaffold synchronously.");
AppendIndentedLine(sourceBuilder, 2, "/// </summary>");
AppendIndentedLine(sourceBuilder, 2, "public void ExecuteGeneratedScenarioScaffold() => CreateGeneratedScenarioScaffold().Execute();");
AppendIndentedLine(sourceBuilder, 2, "/// <summary>");
AppendIndentedLine(sourceBuilder, 2, "/// Executes the generated arrange, act, assert, and verify scaffold asynchronously.");
AppendIndentedLine(sourceBuilder, 2, "/// </summary>");
AppendIndentedLine(sourceBuilder, 2, "/// <returns>A task that completes when the generated scaffold finishes running.</returns>");
AppendIndentedLine(sourceBuilder, 2, "public global::System.Threading.Tasks.Task ExecuteGeneratedScenarioScaffoldAsync() => CreateGeneratedScenarioScaffold().ExecuteAsync();");
AppendIndentedLine(sourceBuilder, 2, "/// <summary>");
AppendIndentedLine(sourceBuilder, 2, "/// Executes the generated scaffold with an act phase that expects the specified exception type.");
AppendIndentedLine(sourceBuilder, 2, "/// </summary>");
AppendIndentedLine(sourceBuilder, 2, "/// <typeparam name=\"TException\">The exception type expected from the generated act phase.</typeparam>");
AppendIndentedLine(sourceBuilder, 2, "public void ExecuteGeneratedExpectedExceptionScenarioScaffold<TException>() where TException : global::System.Exception => CreateGeneratedExpectedExceptionScenarioScaffold<TException>().Execute();");
AppendIndentedLine(sourceBuilder, 2, "/// <summary>");
AppendIndentedLine(sourceBuilder, 2, "/// Executes the generated scaffold asynchronously with an act phase that expects the specified exception type.");
AppendIndentedLine(sourceBuilder, 2, "/// </summary>");
AppendIndentedLine(sourceBuilder, 2, "/// <typeparam name=\"TException\">The exception type expected from the generated act phase.</typeparam>");
AppendIndentedLine(sourceBuilder, 2, "/// <returns>A task that completes when the generated scaffold finishes running.</returns>");
AppendIndentedLine(sourceBuilder, 2, "public global::System.Threading.Tasks.Task ExecuteGeneratedExpectedExceptionScenarioScaffoldAsync<TException>() where TException : global::System.Exception => CreateGeneratedExpectedExceptionScenarioScaffold<TException>().ExecuteAsync();");
- `GeneratedHarnessSourceGenerator` currently hard-codes the target attribute metadata name, the `MockerTestBase<TComponent>` requirement, the generated metadata type name, the `ComponentConstructorParameterTypes` override, the auto-generated header, `#nullable enable`, the `.FastMoq.GeneratedHarness.g.cs` hint-name suffix, and the current xUnit-gated smoke-test naming and placeholder strategy.
- `GeneratedTestTargetShapeRule` and `FastMoqAnalysisHelpers` currently own the package matrix, target-shape list, required package per shape, default base type name, and default namespaces for each supported generated test shape.
- `Directory.Packages.props` currently carries `xunit` `2.9.3` and `xunit.runner.visualstudio` `3.0.2`, while the repo documentation remains framework-agnostic. That mixed baseline is one reason syntax targeting and runner or bootstrap targeting must stay separate settings.
- `FastMoq.Generators.csproj` does not currently declare `CompilerVisibleProperty`, `CompilerVisibleItemMetadata`, or any equivalent custom bridge for generated-test authoring settings.

JSON or `AdditionalFiles` manifests are explicitly deferred. They should only be introduced if the structured settings shape demonstrably outgrows practical MSBuild properties or simple semicolon-delimited list values.

Implementation note: although Roslyn analyzers and generators can observe `build_property.*` values through generated analyzer config, this repo does not currently expose any custom generated-test settings bridge in `FastMoq.Generators.csproj`. A future implementation slice must add the required compiler-visible-property or equivalent build plumbing before any custom settings can flow into analyzer or generator code. The current `#136` scaffold implementation and the first narrow `#123` smoke-test slice therefore consume the `#162` vocabulary as fixed generator-owned defaults rather than as user-configurable settings values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Define generated-test settings and test-platform targeting for later generation flows

2 participants