Skip to content

Commit 24dedcb

Browse files
authored
FastMoq v4: introduce provider-first architecture, package split, and migration docs (#65)
his PR captures the FastMoq v4 release line relative to tag 3.0.0. Compared to 3.0.0, FastMoq now moves from Moq-centric internals to a provider-first architecture, introduces a clearer package split, adds provider-neutral verification and scenario-building APIs, and expands the migration and release documentation needed to adopt the new model. What changed introduced provider-first abstractions and registry support through IMockingProvider, IMockingProviderCapabilities, IFastMock<T>, and MockingProviderRegistry added the built-in reflection provider plus provider packages for Moq and NSubstitute split the package layout so provider contracts live in FastMoq.Abstractions, EF/DbContext helpers live in FastMoq.Database, and provider-specific adapters live in FastMoq.Provider.* moved DbContext-specific implementation details out of core while preserving the main FastMoq namespace call shape for end users added provider-neutral verification and logging helpers, including Verify(...), VerifyLogged(...), and TimesSpec added fluent scenario-building support with Scenario.With(...).When(...).Then(...).Verify(...) replaced older coupled option flows with more explicit creation, invocation, and policy surfaces such as InstanceCreationFlags, InvocationOptions, BuiltInTypeResolutionFlags, and known-type registration support narrowed compatibility behavior around Strict, kept MockOptional as an obsolete bridge, and moved Moq-specific HTTP compatibility helpers into FastMoq.Provider.Moq expanded test coverage, executable examples, generated API documentation, migration guidance, and release notes for the v4 line Breaking / migration notes Strict is no longer the old all-in-one strictness switch; broader preset behavior should use the explicit preset APIs strict IFileSystem behavior now stays enriched through FastMoq's built-in known-type pipeline instead of behaving like a raw empty Moq mock older Moq-oriented HTTP setup helpers remain available for migration, but now come from FastMoq.Provider.Moq existing suites can stay on the compatibility path, while new or actively refactored tests can move toward GetOrCreateMock(...), provider-neutral verification, and explicit provider selection
1 parent a74e0f5 commit 24dedcb

1,041 files changed

Lines changed: 337564 additions & 213814 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/dotnet-tools.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"docfx": {
6+
"version": "2.78.5",
7+
"commands": [
8+
"docfx"
9+
]
10+
}
11+
}
12+
}

.copilotignore

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Ignore build artifacts and binaries
2+
bin/
3+
obj/
4+
*.dll
5+
*.exe
6+
*.pdb
7+
*.lib
8+
*.obj
9+
10+
# Ignore user-specific and temp files
11+
*.user
12+
*.suo
13+
*.cache
14+
*.log
15+
.vs/
16+
*.DotSettings.user
17+
18+
# Ignore test snapshots and coverage
19+
__snapshots__/
20+
coverage/
21+
*.testresults
22+
TestResults/
23+
24+
# Ignore generated files and intermediate outputs
25+
*.g.cs
26+
*.designer.cs
27+
*.generated.cs
28+
AssemblyInfo.cs
29+
30+
# Ignore large or noisy folders
31+
node_modules/
32+
packages/
33+
wwwroot/lib/
34+
dist/
35+
36+
# Ignore specific config files not relevant to code suggestions
37+
Web.Config
38+
*.DotSettings
39+
packages.lock.json
40+
41+
# Ignore NuGet packaging artifacts
42+
*.nupkg
43+
*.snupkg
44+
45+
# Ignore documentation artifacts that may be large/noisy
46+
Help/
47+
docs/benchmarks/
48+
*.GhostDoc.xml
49+
50+
# Additional IDE files
51+
.idea/
52+
*.sln.docstates
53+
*.sln.cache
54+
*.csproj.user
55+
56+
# Documentation and design files
57+
docs/architecture/
58+
docs/diagrams/
59+
*.vsdx
60+
*.drawio
61+
*.md.backup
62+
*.sln.GhostDoc.xml
63+
64+
# Blazor test assets
65+
FastMoq.Tests.Blazor/wwwroot/
66+
67+
# Copilot-specific files
68+
.copilot/
69+
copilot.log
70+
copilot_suggestions/

.github/copilot-instructions.md

Lines changed: 163 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ It wraps and extends mocking providers (currently Moq, with planned provider‑a
2626
## 🧩 Coding Guidelines for Copilot
2727
When generating code:
2828
1. **Provider‑agnostic first**
29-
- Use `IMockingProvider` methods for verification and mock creation.
29+
- Use `IMockingProvider` methods for mock creation, setup, verification, etc.
3030
- Only use Moq APIs inside `MoqProvider` or Moq‑specific test code.
3131
2. **Reuse shared helpers**
3232
- For component creation, always call `MockerConstructionHelper.CreateInstance`.
@@ -38,15 +38,38 @@ When generating code:
3838
4. **Keep tests self‑contained**
3939
- Use `Component` or `ComponentAs<T>()` from base classes.
4040
- Prefer `Scenario.With(Component)` for new tests.
41-
5. **Document new APIs**
42-
- Add XML doc comments for public methods.
41+
5. **Use proper using statements**
42+
- Always add appropriate `using` statements at the top of files instead of fully qualified names.
43+
- Example: Use `using System.Runtime;` then reference `AmbiguousImplementationException` instead of `System.Runtime.AmbiguousImplementationException`.
44+
- Keep using statements organized and remove unused ones.
45+
6. **Document new APIs**
46+
- Add XML doc comments for all public, protected, and protected internal members you touch, including obsolete compatibility APIs that still appear in the public surface.
47+
- When doing a documentation cleanup pass, finish by re-checking the touched file for any remaining undocumented public, protected, or protected internal members instead of assuming the patch caught them all.
4348
- Include usage examples in Milestone docs.
49+
7. **Static Analysis (Sonar) Compliance**
50+
- Honor the rules in the "Static Analysis Rules" section below (S121, S122, S6608) when generating or refactoring code.
51+
8. **Keep edits and updates task-bound**
52+
- Progress updates must stay grounded in the current task, files, and findings. Do not insert speculative filler, unrelated examples, or generic brainstorming text.
53+
- When a patch is too broad, split it into smaller targeted edits and complete local formatting cleanup before stopping.
54+
- If you touch a large partial class, preserve the surrounding style and fix any indentation or malformed XML introduced in the edited region before considering the work done.
55+
56+
## 🔐 Static Analysis Rules (Sonar)
57+
Apply these consistently in generated code (and prefer refactoring existing code toward them when touched):
58+
- S121: Always use curly braces for control structures (`if/else`, `for`, `foreach`, `while`, `do`, `using`, `lock`, `switch` sections). No single-line implicit blocks.
59+
- S122: One statement per line. Avoid multiple statements separated by semicolons on the same line. Keep declarations and executable statements clearly separated for readability.
60+
- S6608: Prefer modern, clear C# constructs (pattern matching / expression forms) when it improves readability and safety, without sacrificing clarity. Do not apply micro-optimizations that reduce clarity. (If applicability is ambiguous, prefer the most readable form and add a brief comment if deviating.)
61+
62+
Notes:
63+
- Do not introduce breaking changes solely to satisfy these rules. Apply them opportunistically or in newly generated code.
64+
- If a rule conflicts with existing public API shape or widely-used patterns in the repository, prefer backward compatibility and add a TODO comment.
4465

4566
## 🚫 Avoid
4667
- Hard‑coding Moq calls in shared/core code.
4768
- Duplicating constructor resolution logic — always centralize in `MockerConstructionHelper`.
4869
- Adding provider‑specific logic to `MockerTestBase` classes.
4970
- Breaking existing public API signatures.
71+
- Leaving touched public, protected, or protected internal members undocumented because they are obsolete or compatibility-only.
72+
- Posting unrelated status text while working; every progress update should reflect the active task.
5073

5174
## 📚 Reference Examples
5275
- See `FastMoq.Tests` for usage of `MockerTestBase<T>` and `VerifyLogger`.
@@ -60,6 +83,142 @@ When generating code:
6083

6184
---
6285

86+
## 🎯 V2 Refactor Roadmap & Milestones
87+
88+
### **Objective**
89+
Refactor FastMoq to support a **provider-agnostic mocking architecture**, a **fluent scenario builder**, and **structured logging**, while preserving developer experience and minimizing migration friction from v1 to v2.
90+
91+
### 🧭 **Summary of Changes**
92+
- Introduce a **plugin-based provider model** to support Moq, NSubstitute, FakeItEasy, and custom mocking engines.
93+
- Build a **strongly-typed fluent API** for expressive, chainable test scenarios.
94+
- Add **structured logging and diagnostics** for mock setup, execution, and verification.
95+
- Ensure **backward compatibility** by preserving public interface names or providing migration shims.
96+
- Design for **extensibility** and **session-resilient refactoring**, so work can continue across sessions.
97+
98+
### 🛠️ **Milestone 1: Core Provider Architecture**
99+
**Goal:** Decouple FastMoq from specific mocking libraries and enable provider swapping.
100+
101+
#### Key Tasks:
102+
- Define `IMockingProvider` interface with methods for mock creation, setup, verification, etc.
103+
- Implement a **reflection-based default provider** (no Moq/NSubstitute dependency).
104+
- Add `MockingProviderRegistry` for global or per-test provider selection.
105+
- Create `MockWrapper<T>` with:
106+
- Strongly-typed API (`Setup`, `Verify`, etc.)
107+
- `NativeMock` property for direct access to underlying mock object.
108+
- Support developer-supplied providers via `IMockingProvider`.
109+
- Ensure provider packages use **minimum version dependencies** or reflection-only logic.
110+
- Document provider registration and extensibility patterns.
111+
112+
### 🛠️ **Milestone 2: Fluent Scenario Builder**
113+
**Goal:** Provide a fluent, expressive API for building test scenarios.
114+
115+
#### Key Tasks:
116+
- Design chainable methods: `.With()`, `.When()`, `.Then()`, `.Verify()`, `.LogScenario()`.
117+
- Ensure fluent API routes through `IMockingProvider` abstraction.
118+
- Maintain full IntelliSense via strongly-typed wrappers.
119+
- Support both Arrange/Act/Assert and fluent styles.
120+
- Preserve public method names from v1 where possible.
121+
- Document fluent usage with side-by-side comparisons to Moq.
122+
123+
### 🛠️ **Milestone 3: Expanded Logging & Diagnostics**
124+
**Goal:** Add structured logging for visibility and debugging.
125+
126+
#### Key Tasks:
127+
- Log mock setups, executions, verifications, and outcomes in structured format (JSON or key-value).
128+
- Support dependency graph dumps and call traces.
129+
- Integrate with `ILogger<T>` and test framework outputs.
130+
- Allow per-test or global logging configuration.
131+
- Document logging patterns and integration examples.
132+
133+
### 🔄 **Migration Strategy & Session Continuity**
134+
- **Preserve public interface names** from v1 wherever possible to reduce friction.
135+
- If breaking changes are unavoidable, provide:
136+
- **Migration guide** with before/after examples.
137+
- **Converter utilities** or shims to bridge v1 to v2.
138+
- **Encapsulate existing logic** during refactor:
139+
- Move current implementations into `Legacy` or `V1` namespaces.
140+
- Store them in a dedicated module or branch for reference.
141+
- **Session continuity**:
142+
- Save intermediate refactor state in a persistent location (e.g., `RefactorNotes.md`, `RefactorStaging.cs`).
143+
- Annotate TODOs and partial implementations clearly for pickup in future sessions.
144+
- When working on milestones, always check for existing work-in-progress files before starting.
145+
- Use clear naming conventions for milestone-related files (e.g., `Milestone1_IMockingProvider.cs`).
146+
147+
### 🧩 **Refactor Guidelines for Copilot**
148+
When working on v2 refactor tasks:
149+
1. **Check milestone progress** - Look for existing milestone-related files and progress indicators.
150+
2. **Follow provider-first approach** - All new mocking functionality should go through `IMockingProvider`.
151+
3. **Preserve backward compatibility** - Keep existing public APIs working or provide clear migration paths.
152+
4. **Document refactor state** - Update progress files and leave clear notes for continuation.
153+
5. **Test incrementally** - Ensure existing tests continue to pass as refactoring progresses.
154+
6. **Use staging approach** - Create new implementations alongside existing ones before swapping.
155+
156+
### 📂 **Milestone File Mapping**
157+
158+
#### **Milestone 1: Core Provider Architecture**
159+
**Current Files (✅ Existing):**
160+
- `FastMoq.Core\Providers\IMockingProvider.cs` - Main provider interface
161+
- `FastMoq.Core\Providers\IMockingProviderCapabilities.cs` - Provider capability detection
162+
- `FastMoq.Core\Providers\MockingProviderRegistry.cs` - Registry for provider management
163+
- `FastMoq.Core\Providers\MockCreationOptions.cs` - Options for mock creation
164+
- `FastMoq.Core\Providers\TimesSpec.cs` - Provider-agnostic verification times
165+
- `FastMoq.Core\Providers\ProviderBootstrap.cs` - Provider initialization
166+
- `FastMoq.Core\Providers\MoqFastMockFactory.cs` - Moq-specific factory
167+
- `FastMoq.Core\Providers\IMock.cs` - Basic mock interface
168+
169+
**Expected Files (⏳ To Create/Complete):**
170+
- `FastMoq.Core\Providers\MockWrapper.cs` - Strongly-typed wrapper with `Setup`, `Verify`, `NativeMock`
171+
- `FastMoq.Core\Providers\ReflectionProvider.cs` - Default reflection-based provider
172+
- `FastMoq.Core\Providers\MoqProvider.cs` - Full Moq implementation
173+
- `FastMoq.Providers.NSubstitute\NSubstituteProvider.cs` - NSubstitute provider package
174+
- `FastMoq.Providers.FakeItEasy\FakeItEasyProvider.cs` - FakeItEasy provider package
175+
176+
#### **Milestone 2: Fluent Scenario Builder**
177+
**Current Files (✅ Existing):**
178+
- `FastMoq.Core\ScenarioBuilder.cs` - Initial fluent API scaffold
179+
180+
**Expected Files (⏳ To Create/Complete):**
181+
- `FastMoq.Core\ScenarioBuilderExtensions.cs` - Extension methods for fluent API
182+
- `FastMoq.Core\Scenarios\ArrangePhase.cs` - `.With()` implementation
183+
- `FastMoq.Core\Scenarios\ActPhase.cs` - `.When()` implementation
184+
- `FastMoq.Core\Scenarios\AssertPhase.cs` - `.Then()` implementation
185+
- `FastMoq.Core\Scenarios\VerifyPhase.cs` - `.Verify()` implementation
186+
- `FastMoq.Core\MockerTestBase_Scenarios.cs` - Integration with existing test base
187+
188+
#### **Milestone 3: Expanded Logging & Diagnostics**
189+
**Current Files (✅ Existing):**
190+
- `FastMoq.Core\Extensions\TestClassExtensions.cs` - Contains current `VerifyLogger` methods
191+
192+
**Expected Files (⏳ To Create/Complete):**
193+
- `FastMoq.Core\Logging\MockingLogger.cs` - Structured logging implementation
194+
- `FastMoq.Core\Logging\DiagnosticsCollector.cs` - Dependency graph and call tracing
195+
- `FastMoq.Core\Logging\LoggingConfiguration.cs` - Per-test and global logging config
196+
- `FastMoq.Core\Extensions\LoggingExtensions.cs` - Enhanced logging extensions
197+
- `FastMoq.Core\Diagnostics\CallTrace.cs` - Call tracing and verification logging
198+
- `FastMoq.Core\Diagnostics\DependencyGraphDumper.cs` - Dependency visualization
199+
200+
#### **Shared/Legacy Files:**
201+
**Current Files (✅ Existing):**
202+
- `FastMoq.Core\Mocker.cs` - Core mock registry (to be refactored)
203+
- `FastMoq.Core\MockerTestBase.cs` - Test base classes (to extend)
204+
- `FastMoq.Core\Extensions\MockerCreationExtensions.cs` - Contains `CreateInstance` methods
205+
- `FastMoq.Core\Models\MockModel.cs` - Mock model classes
206+
207+
**Expected Files (⏳ To Create/Complete):**
208+
- `FastMoq.Core\Legacy\V1Mocker.cs` - Preserved v1 implementation
209+
- `FastMoq.Core\Migration\V1ToV2Converter.cs` - Migration utilities
210+
- `RefactorNotes.md` - Session continuity notes (workspace root)
211+
- `RefactorStaging.cs` - Temporary staging implementations (workspace root)
212+
213+
#### **Test Files:**
214+
**Expected Test Coverage:**
215+
- `FastMoq.Tests\Providers\ProviderTests.cs` - Provider abstraction tests
216+
- `FastMoq.Tests\Scenarios\ScenarioBuilderTests.cs` - Fluent API tests
217+
- `FastMoq.Tests\Logging\MockingLoggerTests.cs` - Logging functionality tests
218+
- `FastMoq.Tests\Migration\V1ToV2Tests.cs` - Migration compatibility tests
219+
220+
---
221+
63222
# ✅ FastMoq Test Authoring Guidelines
64223

65224
## 📚 Getting Started
@@ -118,7 +277,7 @@ public void SaveEntity_ShouldCallRepository_WithCorrectParameters()
118277
var entity = new TestEntity { Id = 123 };
119278

120279
// Act
121-
Mocks.CallMethod(Component.SaveEntity, entity);
280+
Component.SaveEntity(entity);
122281

123282
// Assert
124283
Mocks.GetMock<IRepository>()

.github/workflows/ci_master.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ jobs:
1414
uses: ./.github/workflows/template_ci.yml
1515
with:
1616
projects: "FastMoq.Tests/FastMoq.Tests.csproj FastMoq.Tests.Web/FastMoq.Tests.Web.csproj"
17-
frameworks: '["8.0.x","9.0.x"]'
17+
frameworks: '["8.0.x","9.0.x","10.0.x"]'

.github/workflows/ci_pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ jobs:
1010
uses: ./.github/workflows/template_ci.yml
1111
with:
1212
projects: "FastMoq.Tests/FastMoq.Tests.csproj FastMoq.Tests.Web/FastMoq.Tests.Web.csproj"
13-
frameworks: '["8.0.x","9.0.x"]'
13+
frameworks: '["8.0.x","9.0.x","10.0.x"]'

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
if: matrix.language == 'csharp'
6767
run: |
6868
set -euo pipefail
69-
# Use the release solution (excludes test projects) to avoid building test SDK under net6.0
69+
# Use the release solution (excludes test projects) for cleaner builds
7070
if [ -f FastMoq-Release.sln ]; then
7171
echo "Restoring FastMoq-Release.sln"
7272
dotnet restore FastMoq-Release.sln

.github/workflows/publish_FastMoq.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
uses: ./.github/workflows/template_ci.yml
5353
with:
5454
projects: "FastMoq.Tests/FastMoq.Tests.csproj FastMoq.Tests.Web/FastMoq.Tests.Web.csproj"
55-
frameworks: '["8.0.x","9.0.x"]'
55+
frameworks: '["8.0.x","9.0.x","10.0.x"]'
5656

5757
package:
5858
name: Build & Pack (multi-TFM)
@@ -71,9 +71,9 @@ jobs:
7171
- uses: actions/setup-dotnet@v4
7272
with:
7373
dotnet-version: |
74-
6.0.x
7574
8.0.x
7675
9.0.x
76+
10.0.x
7777
cache: true
7878
- name: Restore
7979
run: dotnet restore FastMoq-Release.sln

0 commit comments

Comments
 (0)