diff --git a/README.md b/README.md
index 029bc5bcc..308307444 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# RSCG - 245 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
+# RSCG - 246 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
-The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 245 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.
+The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 246 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.
This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem
-## Latest Update : 2025-12-12 => 12 December 2025
+## Latest Update : 2025-12-13 => 13 December 2025
If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)***
@@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt
## Content
-Those are the 245 Roslyn Source Code Generators that I have tested you can see and download source code example.
+Those are the 246 Roslyn Source Code Generators that I have tested you can see and download source code example.
( including 16 from Microsoft )
+### 246. [Imposter](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter) , in the [Tests](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#tests) category
+
+Generated on : 2025-12-13 => 13 December 2025
+
+
+ Expand
+
+
+
+Author: Bitchiko Tchelidze
+
+Imposter — Source-generated test doubles, zero runtime overhead. A high-performance Roslyn incremental source generator that produces imposters (mocks/stubs) for interfaces and overridable class members via GenerateImposterAttribute. Ships analyzer + runtime in a single package.
+
+Nuget: [https://www.nuget.org/packages/Imposter/](https://www.nuget.org/packages/Imposter/)
+
+
+Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter)
+
+Source: [https://github.com/themidnightgospel/Imposter](https://github.com/themidnightgospel/Imposter)
+
+
+
### 245. [Monify](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Monify) , in the [PrimitiveObsession](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#primitiveobsession) category
Generated on : 2025-12-12 => 12 December 2025
diff --git a/later.md b/later.md
index 557055f51..d79c96437 100644
--- a/later.md
+++ b/later.md
@@ -1,6 +1,6 @@
# Just later
-## Latest Update : 2025-12-12 => 12 December 2025
+## Latest Update : 2025-12-13 => 13 December 2025
diff --git a/v2/.tours/Imposter.tour b/v2/.tours/Imposter.tour
new file mode 100644
index 000000000..22ff1589d
--- /dev/null
+++ b/v2/.tours/Imposter.tour
@@ -0,0 +1,36 @@
+
+{
+ "$schema": "https://aka.ms/codetour-schema",
+ "title": "Imposter",
+ "steps":
+ [
+ {
+ "file": "rscg_examples/Imposter/src/TestClock/TestClock.csproj",
+ "description": "First, we add Nuget [Imposter](https://www.nuget.org/packages/Imposter/) in csproj ",
+ "pattern": "Imposter"
+ }
+
+ ,{
+ "file": "rscg_examples/Imposter/src/TestClock/Usings.cs",
+ "description": "File Usings.cs ",
+ "pattern": "this is the code"
+ }
+
+ ,{
+ "file": "rscg_examples/Imposter/src/TestClock/TestClock.cs",
+ "description": "File TestClock.cs ",
+ "pattern": "this is the code"
+ }
+
+
+ ,{
+ "file": "rscg_examples/Imposter/src/TestClock/obj/GX/Imposter.CodeGenerator/Imposter.CodeGenerator.CodeGenerator.ImposterGenerator/IMyClockImposter.g.cs",
+ "description": "Generated File 1 from 1 : IMyClockImposter.g.cs ",
+ "line": 1
+ }
+
+ ],
+
+ "ref": "main"
+
+}
\ No newline at end of file
diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv
index 297951b95..0b6a54964 100644
--- a/v2/Generator/all.csv
+++ b/v2/Generator/all.csv
@@ -244,3 +244,4 @@ Nr,Key,Source,Category
243,RSCG_MCP2File, https://github.com/ignatandrei/RSCG_OpenApi2MCP,MCP
244,BoolParameterGenerator, https://github.com/9swampy/BoolEnumGenerator,Bool
245,Monify, https://github.com/MooVC/monify,PrimitiveObsession
+246,Imposter, https://github.com/themidnightgospel/Imposter,Tests
diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json
index 279942ef3..463324801 100644
--- a/v2/RSCGExamplesData/GeneratorDataRec.json
+++ b/v2/RSCGExamplesData/GeneratorDataRec.json
@@ -1485,5 +1485,11 @@
"dtStart": "2025-12-12T00:00:00",
"show": true
-}
+},
+{
+ "ID": "Imposter",
+ "Category": 13,
+ "dtStart": "2025-12-13T00:00:00",
+ "show": true
+ },
]
\ No newline at end of file
diff --git a/v2/book/examples/Imposter.html b/v2/book/examples/Imposter.html
new file mode 100644
index 000000000..f6200a4e0
--- /dev/null
+++ b/v2/book/examples/Imposter.html
@@ -0,0 +1,59 @@
+
+
RSCG nr 246 : Imposter
+
+Info
+Nuget : https://www.nuget.org/packages/Imposter/
+
+You can find more details at : https://github.com/themidnightgospel/Imposter
+
+Author :Bitchiko Tchelidze
+
+Source: https://github.com/themidnightgospel/Imposter
+
+About
+
+Generate classes from interfaces and allows return of mock data.Useful for testing and prototyping.
+
+
+ How to use
+
+
+ Add reference to the Imposter in the csproj
+
+
+
+This was for me the starting code
+
+
+ I have coded the file TestClock.cs
+
+
+
+
+
+ I have coded the file Usings.cs
+
+
+
+ And here are the generated files
+
+
+ The file generated is IMyClockImposter.g.cs
+
+
+
+
+ You can download the code and this page as pdf from
+
+ https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter
+
+
+
+
+
+ You can see the whole list at
+
+ https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG
+
+
+
diff --git a/v2/book/list.html b/v2/book/list.html
index eaf4e0e70..e8ea72657 100644
--- a/v2/book/list.html
+++ b/v2/book/list.html
@@ -17,7 +17,7 @@
-This is the list of 245 RSCG with examples =>
+This is the list of 246 RSCG with examples =>
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml
index a8707b432..9b22bc4b3 100644
--- a/v2/book/pandocHTML.yaml
+++ b/v2/book/pandocHTML.yaml
@@ -259,6 +259,7 @@ input-files:
- examples/RSCG_MCP2File.html
- examples/BoolParameterGenerator.html
- examples/Monify.html
+- examples/Imposter.html
# or you may use input-file: with a single value
# defaults:
diff --git a/v2/rscg_examples/Imposter/description.json b/v2/rscg_examples/Imposter/description.json
new file mode 100644
index 000000000..853fed480
--- /dev/null
+++ b/v2/rscg_examples/Imposter/description.json
@@ -0,0 +1,22 @@
+{
+ "generator":{
+ "name":"Imposter",
+ "nuget":[
+ "https://www.nuget.org/packages/Imposter/"
+ ],
+ "link":"https://github.com/themidnightgospel/Imposter",
+ "author":"Bitchiko Tchelidze",
+ "source":"https://github.com/themidnightgospel/Imposter"
+ },
+ "data":{
+ "goodFor":["Generate classes from interfaces and allows return of mock data.","Useful for testing and prototyping."],
+ "csprojDemo":"TestClock.csproj",
+ "csFiles":["TestClock.cs","Usings.cs"],
+ "excludeDirectoryGenerated":[""],
+ "includeAdditionalFiles":[""]
+ },
+ "links":{
+ "blog":"",
+ "video":""
+ }
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/Imposter/nuget.txt b/v2/rscg_examples/Imposter/nuget.txt
new file mode 100644
index 000000000..f1984309b
--- /dev/null
+++ b/v2/rscg_examples/Imposter/nuget.txt
@@ -0,0 +1 @@
+Imposter — Source-generated test doubles, zero runtime overhead. A high-performance Roslyn incremental source generator that produces imposters (mocks/stubs) for interfaces and overridable class members via GenerateImposterAttribute. Ships analyzer + runtime in a single package.
\ No newline at end of file
diff --git a/v2/rscg_examples/Imposter/readme.txt b/v2/rscg_examples/Imposter/readme.txt
new file mode 100644
index 000000000..fbe15833f
--- /dev/null
+++ b/v2/rscg_examples/Imposter/readme.txt
@@ -0,0 +1,154 @@
+
+
+
+
+
+ Fast and Memory-Efficient Mocking Library
+
+
+[](https://github.com/themidnightgospel/Imposter/actions/workflows/build-and-test.yml)
+[](https://www.nuget.org/packages/Imposter)
+
+Imposter is a mocking library that's using roslyn source generators to achieve high performance and low memory footprint.
+
+Visit the [Docs](https://themidnightgospel.github.io/Imposter/) for more information
+
+## 🚀 Quick Start
+
+Add nuget package reference:
+
+```bash
+dotnet add package Imposter
+```
+
+Pick an interface or non-sealed class that you would like to generate an imposter for.
+
+Say we have a below interface
+
+```csharp
+
+namespace Application.Domain;
+
+public interface ICalculator
+{
+ int Add(int a, int b);
+}
+```
+
+Use `[GenerateImposter]` attribute in your **tests** project, this will generate an imoster
+
+```csharp
+[assembly: GenerateImposter(typeof(Application.Domain.ICalculator))]
+```
+
+Then use can use the generated imposter in your tests
+
+```csharp
+using System.Threading.Tasks;
+using Imposter.Abstractions;
+
+// c# 14
+var imposter = ICalculator.Imposter();
+
+// c# 9 - 13
+// var imposter = new ICalculatorImposter();
+
+imposter.Add(Arg.Any(), Arg.Any())
+ .Returns(1)
+ .Then()
+ .Returns(2);
+
+var calculator = imposter.Instance();
+
+calculator.Add(1, 2); // 1
+calculator.Add(1, 2); // 2
+```
+
+Learn more: https://themidnightgospel.github.io/Imposter/
+
+## ✨ Feature-Rich
+
+ - [Method Impersonation](https://themidnightgospel.github.io/Imposter/latest/methods/)
+ - [Property Impersonation](https://themidnightgospel.github.io/Imposter/latest/properties/)
+ - [Indexer Impersonation](https://themidnightgospel.github.io/Imposter/latest/indexers/)
+ - [Event Impersonation](https://themidnightgospel.github.io/Imposter/latest/events/)
+ - [Class Impersonation](https://themidnightgospel.github.io/Imposter/latest/base-implementation/)
+ - [Generics](https://themidnightgospel.github.io/Imposter/latest/generics/)
+ - [Implicit & Explicit Modes](https://themidnightgospel.github.io/Imposter/latest/implicit-vs-explicit/)
+ - [Use Base implementation](https://themidnightgospel.github.io/Imposter/latest/base-implementation/)
+ - [Async Support](https://themidnightgospel.github.io/Imposter/latest/methods/#async-methods)
+ - [Protected members Impersonation](https://themidnightgospel.github.io/Imposter/latest/methods/protected-members/)
+
+## ⏱️ Benchmark
+
+We benchmarked the simple method-impersonation scenario: we set up a `Square` method to return `input * input` and ran it for 1, 10, 100, and 1000 iterations.
+
+```csharp
+public interface ICalculator
+{
+ int Square(int input);
+}
+```
+
+Mean execution time
+
+| Method | Iteration | Mean |
+|-------------|-----------|----------------:|
+| Moq | 1 | 69,346.1 ns |
+| NSubstitute | 1 | 1,976.2 ns |
+| FakItEasy | 1 | 2,006.7 ns |
+| Imposter | 1 | **194.3 ns** |
+| Moq | 10 | 686,282.9 ns |
+| NSubstitute | 10 | 11,201.6 ns |
+| FakItEasy | 10 | 12,399.0 ns |
+| Imposter | 10 | **1,896.7 ns** |
+| Moq | 100 | 6,804,897.3 ns |
+| NSubstitute | 100 | 335,390.6 ns |
+| FakItEasy | 100 | 258,220.2 ns |
+| Imposter | 100 | **34,011.7 ns** |
+| Moq | 1000 | 99,710,929.5 ns |
+| NSubstitute | 1000 | 26,986,939.0 ns |
+| FakItEasy | 1000 | 18,997,374.5 ns |
+| Imposter | 1000 | **2,452,970.7 ns** |
+
+
+Allocated Memory
+
+| Method | Iteration | Allocated |
+|-------------|-----------|------------:|
+| Moq | 1 | 13.05 KB |
+| NSubstitute | 1 | 7.84 KB |
+| FakeItEasy | 1 | 5.84 KB |
+| Imposter | 1 | **2.4 KB** |
+| Moq | 10 | 115.73 KB |
+| NSubstitute | 10 | 29.29 KB |
+| FakeItEasy | 10 | 38.81 KB |
+| Imposter | 10 | **22.37 KB** |
+| Moq | 100 | 1416.91 KB |
+| NSubstitute | 100 | 247.26 KB |
+| FakeItEasy | 100 | 1033.38 KB |
+| Imposter | 100 | **222.05 KB** |
+| Moq | 1000 | 42275.19 KB |
+| NSubstitute | 1000 | 2420.82 KB |
+| FakeItEasy | 1000 | 77101.74 KB |
+| Imposter | 1000 | **2218.93 KB** |
+
+
+Benchmark Environment
+
+```
+BenchmarkDotNet v0.15.6, Windows 11 (10.0.26200.6899)
+13th Gen Intel Core i9-13900HX 2.20GHz, 1 CPU, 32 logical and 24 physical cores
+.NET SDK 10.0.100
+[Host] : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3
+DefaultJob : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3
+```
+
+See other benchmarks [benchmark](https://github.com/themidnightgospel/Imposter/blob/3172c333603fd2d76031b20be39753a9b62f31c3/benchmarks/Imposter.Benchmarks/ImposterVsMoqVsNSubstitute/SimpleMethodMockingBenchmarks.cs#L12)
+
+## Docs
+Docs: https://themidnightgospel.github.io/Imposter/
+
+## License
+
+Licensed under the MIT License. See LICENSE.txt for details.
diff --git a/v2/rscg_examples/Imposter/src/MockData/IMyClock.cs b/v2/rscg_examples/Imposter/src/MockData/IMyClock.cs
new file mode 100644
index 000000000..36d416543
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/MockData/IMyClock.cs
@@ -0,0 +1,7 @@
+namespace MockData;
+public interface IMyClock
+{
+ public DateTime GetNow();
+ public DateTime GetUtcNow();
+
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/Imposter/src/MockData/MockData.csproj b/v2/rscg_examples/Imposter/src/MockData/MockData.csproj
new file mode 100644
index 000000000..f095b6dfa
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/MockData/MockData.csproj
@@ -0,0 +1,10 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
diff --git a/v2/rscg_examples/Imposter/src/MockTest.slnx b/v2/rscg_examples/Imposter/src/MockTest.slnx
new file mode 100644
index 000000000..7e4c29ad0
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/MockTest.slnx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/v2/rscg_examples/Imposter/src/TestClock/TestClock.cs b/v2/rscg_examples/Imposter/src/TestClock/TestClock.cs
new file mode 100644
index 000000000..70af1a05c
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/TestClock/TestClock.cs
@@ -0,0 +1,17 @@
+
+using MockData;
+namespace TestClock;
+
+[TestClass]
+public class TestClock
+{
+ [TestMethod]
+ public void TestMyClock()
+ {
+ var mock = new IMyClockImposter();
+ mock.GetUtcNow().Returns(DateTime.Now.AddYears(-1));
+ mock.GetNow().Returns(DateTime.Now.AddYears(-1));
+ IMyClock clock = mock.Instance();
+ Assert.AreEqual(DateTime.Now.AddYears(-1).Year, clock.GetNow().Year);
+ }
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/Imposter/src/TestClock/TestClock.csproj b/v2/rscg_examples/Imposter/src/TestClock/TestClock.csproj
new file mode 100644
index 000000000..2c4eb63a2
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/TestClock/TestClock.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
diff --git a/v2/rscg_examples/Imposter/src/TestClock/Usings.cs b/v2/rscg_examples/Imposter/src/TestClock/Usings.cs
new file mode 100644
index 000000000..906943495
--- /dev/null
+++ b/v2/rscg_examples/Imposter/src/TestClock/Usings.cs
@@ -0,0 +1,5 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
+global using Imposter.Abstractions;
+
+[assembly: GenerateImposter(typeof(MockData.IMyClock))]
+
diff --git a/v2/rscg_examples/Imposter/video.json b/v2/rscg_examples/Imposter/video.json
new file mode 100644
index 000000000..94966c034
--- /dev/null
+++ b/v2/rscg_examples/Imposter/video.json
@@ -0,0 +1,39 @@
+{
+ "scriptName": "Imposter",
+ "steps":
+[
+ {"typeStep":"exec","arg":"clipchamp.exe launch"},
+ {"typeStep":"text","arg": "Welcome to Roslyn Examples"},
+ {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"},
+ {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"},
+ {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "},
+
+{"typeStep":"text","arg": "Today I will present Imposter . Generate classes from interfaces and allows return of mock data.Useful for testing and prototyping. ."},
+{"typeStep":"browser","arg":"https://www.nuget.org/packages/Imposter/"},
+{"typeStep":"text","arg": "The whole example is here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter"},
+{"typeStep":"text","arg": "You can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter#download-example-net--c-"},
+{"typeStep":"text","arg":"Here is the code downloaded "},
+{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"},
+{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "},
+{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"},
+
+{"typeStep":"text","arg": "To use it ,you will put the Nuget Imposter into the csproj "},
+
+{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Imposter\\src\\TestClock\\TestClock.csproj"},
+
+{"typeStep":"text","arg": "And now I will show you an example of using Imposter"},
+
+{"typeStep":"hide","arg": "now execute the tour in VSCode"},
+{"typeStep":"tour", "arg": "src/.tours/"},
+{"typeStep":"text","arg":" And I will execute the project"},
+{"typeStep":"showproj", "arg":"TestClock.csproj"},
+{"typeStep":"text","arg":" This concludes the project"},
+{"typeStep":"waitseconds","arg":"30"},
+{"typeStep":"text","arg": "Remember, you can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter#download-example-net--c-",
+SpeakTest=" "},
+{"typeStep":"waitseconds","arg":"30"},
+]
+}
diff --git a/v2/rscg_examples_site/docs/Authors/Bitchiko_Tchelidze.md b/v2/rscg_examples_site/docs/Authors/Bitchiko_Tchelidze.md
new file mode 100644
index 000000000..50109a292
--- /dev/null
+++ b/v2/rscg_examples_site/docs/Authors/Bitchiko_Tchelidze.md
@@ -0,0 +1,7 @@
+# Author : Bitchiko Tchelidze
+
+Number RSCG: 1
+
+
+ 1 [Imposter](/docs/Imposter) [](https://www.nuget.org/packages/Imposter/)  2025-12-13
+
diff --git a/v2/rscg_examples_site/docs/Categories/Tests.md b/v2/rscg_examples_site/docs/Categories/Tests.md
index e3a14794b..11c4931b8 100644
--- a/v2/rscg_examples_site/docs/Categories/Tests.md
+++ b/v2/rscg_examples_site/docs/Categories/Tests.md
@@ -1,16 +1,18 @@
Tests
-Number RSCG: 6
+Number RSCG: 7
- 1 [mocklis](/docs/mocklis) [](https://www.nuget.org/packages/mocklis/)  2024-01-03
+ 1 [Imposter](/docs/Imposter) [](https://www.nuget.org/packages/Imposter/)  2025-12-13
- 2 [MockMe](/docs/MockMe) [](https://www.nuget.org/packages/MockMe/)  2025-02-10
+ 2 [mocklis](/docs/mocklis) [](https://www.nuget.org/packages/mocklis/)  2024-01-03
- 3 [MSTest](/docs/MSTest) [](https://www.nuget.org/packages/MSTest.SourceGeneration/)  2024-04-04
+ 3 [MockMe](/docs/MockMe) [](https://www.nuget.org/packages/MockMe/)  2025-02-10
- 4 [Ridge](/docs/Ridge) [](https://www.nuget.org/packages/Ridge/)  2023-08-20
+ 4 [MSTest](/docs/MSTest) [](https://www.nuget.org/packages/MSTest.SourceGeneration/)  2024-04-04
- 5 [Rocks](/docs/Rocks) [](https://www.nuget.org/packages/Rocks/)  2023-04-16
+ 5 [Ridge](/docs/Ridge) [](https://www.nuget.org/packages/Ridge/)  2023-08-20
- 6 [TUnit](/docs/TUnit) [](https://www.nuget.org/packages/TUnit/)  2025-11-08
+ 6 [Rocks](/docs/Rocks) [](https://www.nuget.org/packages/Rocks/)  2023-04-16
+
+ 7 [TUnit](/docs/TUnit) [](https://www.nuget.org/packages/TUnit/)  2025-11-08
\ No newline at end of file
diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveTests.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveTests.mdx
index e818cd88e..816acc669 100644
--- a/v2/rscg_examples_site/docs/Categories/_PrimitiveTests.mdx
+++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveTests.mdx
@@ -1,16 +1,18 @@
### Category "Tests" has the following generators:
- 1 [mocklis](/docs/mocklis) [](https://www.nuget.org/packages/mocklis/)  2024-01-03
+ 1 [Imposter](/docs/Imposter) [](https://www.nuget.org/packages/Imposter/)  2025-12-13
- 2 [MockMe](/docs/MockMe) [](https://www.nuget.org/packages/MockMe/)  2025-02-10
+ 2 [mocklis](/docs/mocklis) [](https://www.nuget.org/packages/mocklis/)  2024-01-03
- 3 [MSTest](/docs/MSTest) [](https://www.nuget.org/packages/MSTest.SourceGeneration/)  2024-04-04
+ 3 [MockMe](/docs/MockMe) [](https://www.nuget.org/packages/MockMe/)  2025-02-10
- 4 [Ridge](/docs/Ridge) [](https://www.nuget.org/packages/Ridge/)  2023-08-20
+ 4 [MSTest](/docs/MSTest) [](https://www.nuget.org/packages/MSTest.SourceGeneration/)  2024-04-04
- 5 [Rocks](/docs/Rocks) [](https://www.nuget.org/packages/Rocks/)  2023-04-16
+ 5 [Ridge](/docs/Ridge) [](https://www.nuget.org/packages/Ridge/)  2023-08-20
- 6 [TUnit](/docs/TUnit) [](https://www.nuget.org/packages/TUnit/)  2025-11-08
+ 6 [Rocks](/docs/Rocks) [](https://www.nuget.org/packages/Rocks/)  2023-04-16
+
+ 7 [TUnit](/docs/TUnit) [](https://www.nuget.org/packages/TUnit/)  2025-11-08
### See category
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/Imposter.md b/v2/rscg_examples_site/docs/RSCG-Examples/Imposter.md
new file mode 100644
index 000000000..97ea7d746
--- /dev/null
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/Imposter.md
@@ -0,0 +1,1093 @@
+---
+sidebar_position: 2460
+title: 246 - Imposter
+description: Generate classes from interfaces and allows return of mock data.
+slug: /Imposter
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import TOCInline from '@theme/TOCInline';
+import SameCategory from '../Categories/_PrimitiveTests.mdx';
+
+# Imposter by Bitchiko Tchelidze
+
+
+
+
+## NuGet / site data
+[](https://www.nuget.org/packages/Imposter/)
+[](https://github.com/themidnightgospel/Imposter)
+
+
+## Details
+
+### Info
+:::info
+
+Name: **Imposter**
+
+Imposter — Source-generated test doubles, zero runtime overhead. A high-performance Roslyn incremental source generator that produces imposters (mocks/stubs) for interfaces and overridable class members via GenerateImposterAttribute. Ships analyzer + runtime in a single package.
+
+Author: Bitchiko Tchelidze
+
+NuGet:
+*https://www.nuget.org/packages/Imposter/*
+
+
+You can find more details at https://github.com/themidnightgospel/Imposter
+
+Source: https://github.com/themidnightgospel/Imposter
+
+:::
+
+### Author
+:::note
+Bitchiko Tchelidze
+
+:::
+
+### Original Readme
+:::note
+
+
+
+
+
+
+ Fast and Memory-Efficient Mocking Library
+
+
+[](https://github.com/themidnightgospel/Imposter/actions/workflows/build-and-test.yml)
+[](https://www.nuget.org/packages/Imposter)
+
+Imposter is a mocking library that's using roslyn source generators to achieve high performance and low memory footprint.
+
+Visit the [Docs](https://themidnightgospel.github.io/Imposter/) for more information
+
+## 🚀 Quick Start
+
+Add nuget package reference:
+
+```bash
+dotnet add package Imposter
+```
+
+Pick an interface or non-sealed class that you would like to generate an imposter for.
+
+Say we have a below interface
+
+```csharp
+
+namespace Application.Domain;
+
+public interface ICalculator
+{
+ int Add(int a, int b);
+}
+```
+
+Use `[GenerateImposter]` attribute in your **tests** project, this will generate an imoster
+
+```csharp
+[assembly: GenerateImposter(typeof(Application.Domain.ICalculator))]
+```
+
+Then use can use the generated imposter in your tests
+
+```csharp
+using System.Threading.Tasks;
+using Imposter.Abstractions;
+
+// c# 14
+var imposter = ICalculator.Imposter();
+
+// c# 9 - 13
+// var imposter = new ICalculatorImposter();
+
+imposter.Add(Arg.Any(), Arg.Any())
+ .Returns(1)
+ .Then()
+ .Returns(2);
+
+var calculator = imposter.Instance();
+
+calculator.Add(1, 2); // 1
+calculator.Add(1, 2); // 2
+```
+
+Learn more: https://themidnightgospel.github.io/Imposter/
+
+## ✨ Feature-Rich
+
+ - [Method Impersonation](https://themidnightgospel.github.io/Imposter/latest/methods/)
+ - [Property Impersonation](https://themidnightgospel.github.io/Imposter/latest/properties/)
+ - [Indexer Impersonation](https://themidnightgospel.github.io/Imposter/latest/indexers/)
+ - [Event Impersonation](https://themidnightgospel.github.io/Imposter/latest/events/)
+ - [Class Impersonation](https://themidnightgospel.github.io/Imposter/latest/base-implementation/)
+ - [Generics](https://themidnightgospel.github.io/Imposter/latest/generics/)
+ - [Implicit & Explicit Modes](https://themidnightgospel.github.io/Imposter/latest/implicit-vs-explicit/)
+ - [Use Base implementation](https://themidnightgospel.github.io/Imposter/latest/base-implementation/)
+ - [Async Support](https://themidnightgospel.github.io/Imposter/latest/methods/#async-methods)
+ - [Protected members Impersonation](https://themidnightgospel.github.io/Imposter/latest/methods/protected-members/)
+
+## ⏱️ Benchmark
+
+We benchmarked the simple method-impersonation scenario: we set up a `Square` method to return `input * input` and ran it for 1, 10, 100, and 1000 iterations.
+
+```csharp
+public interface ICalculator
+{
+ int Square(int input);
+}
+```
+
+Mean execution time
+
+| Method | Iteration | Mean |
+|-------------|-----------|----------------:|
+| Moq | 1 | 69,346.1 ns |
+| NSubstitute | 1 | 1,976.2 ns |
+| FakItEasy | 1 | 2,006.7 ns |
+| Imposter | 1 | **194.3 ns** |
+| Moq | 10 | 686,282.9 ns |
+| NSubstitute | 10 | 11,201.6 ns |
+| FakItEasy | 10 | 12,399.0 ns |
+| Imposter | 10 | **1,896.7 ns** |
+| Moq | 100 | 6,804,897.3 ns |
+| NSubstitute | 100 | 335,390.6 ns |
+| FakItEasy | 100 | 258,220.2 ns |
+| Imposter | 100 | **34,011.7 ns** |
+| Moq | 1000 | 99,710,929.5 ns |
+| NSubstitute | 1000 | 26,986,939.0 ns |
+| FakItEasy | 1000 | 18,997,374.5 ns |
+| Imposter | 1000 | **2,452,970.7 ns** |
+
+
+Allocated Memory
+
+| Method | Iteration | Allocated |
+|-------------|-----------|------------:|
+| Moq | 1 | 13.05 KB |
+| NSubstitute | 1 | 7.84 KB |
+| FakeItEasy | 1 | 5.84 KB |
+| Imposter | 1 | **2.4 KB** |
+| Moq | 10 | 115.73 KB |
+| NSubstitute | 10 | 29.29 KB |
+| FakeItEasy | 10 | 38.81 KB |
+| Imposter | 10 | **22.37 KB** |
+| Moq | 100 | 1416.91 KB |
+| NSubstitute | 100 | 247.26 KB |
+| FakeItEasy | 100 | 1033.38 KB |
+| Imposter | 100 | **222.05 KB** |
+| Moq | 1000 | 42275.19 KB |
+| NSubstitute | 1000 | 2420.82 KB |
+| FakeItEasy | 1000 | 77101.74 KB |
+| Imposter | 1000 | **2218.93 KB** |
+
+
+Benchmark Environment
+
+```
+BenchmarkDotNet v0.15.6, Windows 11 (10.0.26200.6899)
+13th Gen Intel Core i9-13900HX 2.20GHz, 1 CPU, 32 logical and 24 physical cores
+.NET SDK 10.0.100
+[Host] : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3
+DefaultJob : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3
+```
+
+See other benchmarks [benchmark](https://github.com/themidnightgospel/Imposter/blob/3172c333603fd2d76031b20be39753a9b62f31c3/benchmarks/Imposter.Benchmarks/ImposterVsMoqVsNSubstitute/SimpleMethodMockingBenchmarks.cs#L12)
+
+## Docs
+Docs: https://themidnightgospel.github.io/Imposter/
+
+## License
+
+Licensed under the MIT License. See LICENSE.txt for details.
+
+
+:::
+
+### About
+:::note
+
+Generate classes from interfaces and allows return of mock data.
+
+
+Useful for testing and prototyping.
+
+
+:::
+
+## How to use
+
+### Example (source csproj, source files)
+
+
+
+
+
+This is the CSharp Project that references **Imposter**
+```xml showLineNumbers {23}
+
+
+
+ net10.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```
+
+
+
+
+
+ This is the use of **Imposter** in *TestClock.cs*
+
+```csharp showLineNumbers
+
+using MockData;
+namespace TestClock;
+
+[TestClass]
+public class TestClock
+{
+ [TestMethod]
+ public void TestMyClock()
+ {
+ var mock = new IMyClockImposter();
+ mock.GetUtcNow().Returns(DateTime.Now.AddYears(-1));
+ mock.GetNow().Returns(DateTime.Now.AddYears(-1));
+ IMyClock clock = mock.Instance();
+ Assert.AreEqual(DateTime.Now.AddYears(-1).Year, clock.GetNow().Year);
+ }
+}
+```
+
+
+
+
+ This is the use of **Imposter** in *Usings.cs*
+
+```csharp showLineNumbers
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
+global using Imposter.Abstractions;
+
+[assembly: GenerateImposter(typeof(MockData.IMyClock))]
+
+
+```
+
+
+
+
+### Generated Files
+
+Those are taken from $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```csharp showLineNumbers
+//
+#nullable enable
+#pragma warning disable
+using global::System;
+using global::System.Linq;
+using global::System.Collections.Generic;
+using global::System.Threading.Tasks;
+using global::System.Diagnostics;
+using global::System.Runtime.CompilerServices;
+using global::Imposter.Abstractions;
+using global::System.Collections.Concurrent;
+
+namespace MockData
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public sealed class IMyClockImposter : global::Imposter.Abstractions.IHaveImposterInstance
+ {
+ private readonly GetNowMethodImposter _getNowMethodImposter;
+ private readonly GetUtcNowMethodImposter _getUtcNowMethodImposter;
+ private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection = new GetNowMethodInvocationHistoryCollection();
+ private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection = new GetUtcNowMethodInvocationHistoryCollection();
+ public IGetNowMethodImposterBuilder GetNow()
+ {
+ return new GetNowMethodImposter.Builder(_getNowMethodImposter, _getNowMethodInvocationHistoryCollection);
+ }
+
+ public IGetUtcNowMethodImposterBuilder GetUtcNow()
+ {
+ return new GetUtcNowMethodImposter.Builder(_getUtcNowMethodImposter, _getUtcNowMethodInvocationHistoryCollection);
+ }
+
+ private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
+ private ImposterTargetInstance _imposterInstance;
+ global::MockData.IMyClock global::Imposter.Abstractions.IHaveImposterInstance.Instance()
+ {
+ return _imposterInstance;
+ }
+
+ public delegate global::System.DateTime GetNowDelegate();
+ public delegate void GetNowCallbackDelegate();
+ public delegate global::System.Exception GetNowExceptionGeneratorDelegate();
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetNowMethodInvocationHistory
+ {
+ bool Matches();
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetNowMethodInvocationHistory : IGetNowMethodInvocationHistory
+ {
+ internal global::System.DateTime? Result;
+ internal global::System.Exception? Exception;
+ public GetNowMethodInvocationHistory(global::System.DateTime? Result, global::System.Exception? Exception)
+ {
+ this.Result = Result;
+ this.Exception = Exception;
+ }
+
+ public bool Matches()
+ {
+ return true;
+ }
+
+ public override string ToString()
+ {
+ return "GetNow(" + "" + ")" + " => " + FormatValue(Result) + (Exception == null ? "" : " threw " + FormatValue(Exception));
+ }
+
+ private static string FormatValue(object? value)
+ {
+ return "<" + (value?.ToString() ?? "null") + ">";
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetNowMethodInvocationHistoryCollection
+ {
+ private readonly global::System.Collections.Concurrent.ConcurrentStack _invocationHistory = new global::System.Collections.Concurrent.ConcurrentStack();
+ internal void Add(IGetNowMethodInvocationHistory invocationHistory)
+ {
+ _invocationHistory.Push(invocationHistory);
+ }
+
+ internal int Count()
+ {
+ return _invocationHistory.Count(it => it.Matches());
+ }
+
+ public override string ToString()
+ {
+ return string.Join(Environment.NewLine, _invocationHistory.Select(invocation => invocation.ToString()));
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ class GetNowMethodInvocationImposterGroup
+ {
+ internal static GetNowMethodInvocationImposterGroup Default = new GetNowMethodInvocationImposterGroup();
+ private readonly global::System.Collections.Concurrent.ConcurrentQueue _invocationImposters = new global::System.Collections.Concurrent.ConcurrentQueue();
+ private MethodInvocationImposter? _lastestInvocationImposter;
+ public GetNowMethodInvocationImposterGroup()
+ {
+ }
+
+ internal MethodInvocationImposter AddInvocationImposter()
+ {
+ MethodInvocationImposter invocationImposter = new MethodInvocationImposter();
+ _invocationImposters.Enqueue(invocationImposter);
+ return invocationImposter;
+ }
+
+ private MethodInvocationImposter? GetInvocationImposter()
+ {
+ if (_invocationImposters.TryDequeue(out var invocationImposter))
+ {
+ if (!invocationImposter.IsEmpty)
+ {
+ _lastestInvocationImposter = invocationImposter;
+ }
+
+ return invocationImposter;
+ }
+
+ return _lastestInvocationImposter;
+ }
+
+ public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
+ {
+ var invocationImposter = GetInvocationImposter();
+ if (invocationImposter == null)
+ {
+ if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
+ }
+
+ invocationImposter = MethodInvocationImposter.Default;
+ }
+
+ return invocationImposter.Invoke(invocationBehavior, methodDisplayName);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class MethodInvocationImposter
+ {
+ internal static MethodInvocationImposter Default;
+ static MethodInvocationImposter()
+ {
+ Default = new MethodInvocationImposter();
+ Default.Returns(DefaultResultGenerator);
+ }
+
+ private GetNowDelegate? _resultGenerator;
+ private readonly global::System.Collections.Concurrent.ConcurrentQueue _callbacks = new global::System.Collections.Concurrent.ConcurrentQueue();
+ internal bool IsEmpty => (_resultGenerator == null) && (_callbacks.Count == 0);
+
+ public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
+ {
+ if (_resultGenerator == null)
+ {
+ if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
+ }
+
+ _resultGenerator = DefaultResultGenerator;
+ }
+
+ global::System.DateTime result = _resultGenerator.Invoke();
+ foreach (var callback in _callbacks)
+ {
+ callback();
+ }
+
+ return result;
+ }
+
+ internal void Callback(GetNowCallbackDelegate callback)
+ {
+ _callbacks.Enqueue(callback);
+ }
+
+ internal void Returns(GetNowDelegate resultGenerator)
+ {
+ _resultGenerator = resultGenerator;
+ }
+
+ internal void Returns(global::System.DateTime value)
+ {
+ _resultGenerator = () =>
+ {
+ return value;
+ };
+ }
+
+ internal void Throws(GetNowExceptionGeneratorDelegate exceptionGenerator)
+ {
+ _resultGenerator = () =>
+ {
+ throw exceptionGenerator();
+ };
+ }
+
+ internal static global::System.DateTime DefaultResultGenerator()
+ {
+ return default !;
+ }
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetNowMethodInvocationImposterGroupCallback
+ {
+ IGetNowMethodInvocationImposterGroupContinuation Callback(GetNowCallbackDelegate callback);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetNowMethodInvocationImposterGroupContinuation : IGetNowMethodInvocationImposterGroupCallback
+ {
+ IGetNowMethodInvocationImposterGroup Then();
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetNowMethodInvocationImposterGroup : IGetNowMethodInvocationImposterGroupCallback
+ {
+ IGetNowMethodInvocationImposterGroupContinuation Throws()
+ where TException : global::System.Exception, new();
+ IGetNowMethodInvocationImposterGroupContinuation Throws(global::System.Exception exception);
+ IGetNowMethodInvocationImposterGroupContinuation Throws(GetNowExceptionGeneratorDelegate exceptionGenerator);
+ IGetNowMethodInvocationImposterGroupContinuation Returns(GetNowDelegate resultGenerator);
+ IGetNowMethodInvocationImposterGroupContinuation Returns(global::System.DateTime value);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface GetNowInvocationVerifier
+ {
+ void Called(Count count);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetNowMethodImposterBuilder : IGetNowMethodInvocationImposterGroup, IGetNowMethodInvocationImposterGroupCallback, GetNowInvocationVerifier
+ {
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetNowMethodImposter
+ {
+ private readonly global::System.Collections.Concurrent.ConcurrentStack _invocationImposters = new global::System.Collections.Concurrent.ConcurrentStack();
+ private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection;
+ private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
+ public GetNowMethodImposter(GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection, global::Imposter.Abstractions.ImposterMode _invocationBehavior)
+ {
+ this._getNowMethodInvocationHistoryCollection = _getNowMethodInvocationHistoryCollection;
+ this._invocationBehavior = _invocationBehavior;
+ }
+
+ public bool HasMatchingInvocationImposterGroup()
+ {
+ return FindMatchingInvocationImposterGroup() != null;
+ }
+
+ private GetNowMethodInvocationImposterGroup? FindMatchingInvocationImposterGroup()
+ {
+ if (_invocationImposters.TryPeek(out var invocationImposterGroup))
+ return invocationImposterGroup;
+ else
+ return null;
+ }
+
+ public global::System.DateTime Invoke()
+ {
+ var matchingInvocationImposterGroup = FindMatchingInvocationImposterGroup();
+ if (matchingInvocationImposterGroup == default)
+ {
+ if (_invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException("DateTime IMyClock.GetNow()");
+ }
+
+ matchingInvocationImposterGroup = GetNowMethodInvocationImposterGroup.Default;
+ }
+
+ try
+ {
+ var result = matchingInvocationImposterGroup.Invoke(_invocationBehavior, "DateTime IMyClock.GetNow()");
+ _getNowMethodInvocationHistoryCollection.Add(new GetNowMethodInvocationHistory(result, default));
+ return result;
+ }
+ catch (global::System.Exception ex)
+ {
+ _getNowMethodInvocationHistoryCollection.Add(new GetNowMethodInvocationHistory(default !, ex));
+ throw;
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class Builder : IGetNowMethodImposterBuilder, IGetNowMethodInvocationImposterGroupContinuation
+ {
+ private readonly GetNowMethodImposter _imposter;
+ private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection;
+ private readonly GetNowMethodInvocationImposterGroup _invocationImposterGroup;
+ private GetNowMethodInvocationImposterGroup.MethodInvocationImposter _currentInvocationImposter;
+ public Builder(GetNowMethodImposter _imposter, GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection)
+ {
+ this._imposter = _imposter;
+ this._getNowMethodInvocationHistoryCollection = _getNowMethodInvocationHistoryCollection;
+ this._invocationImposterGroup = new GetNowMethodInvocationImposterGroup();
+ _imposter._invocationImposters.Push(_invocationImposterGroup);
+ this._currentInvocationImposter = this._invocationImposterGroup.AddInvocationImposter();
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws()
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw new TException();
+ });
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws(global::System.Exception exception)
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw exception;
+ });
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws(GetNowExceptionGeneratorDelegate exceptionGenerator)
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw exceptionGenerator.Invoke();
+ });
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroupCallback.Callback(GetNowCallbackDelegate callback)
+ {
+ _currentInvocationImposter.Callback(callback);
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Returns(GetNowDelegate resultGenerator)
+ {
+ _currentInvocationImposter.Returns(resultGenerator);
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Returns(global::System.DateTime value)
+ {
+ _currentInvocationImposter.Returns(value);
+ return this;
+ }
+
+ IGetNowMethodInvocationImposterGroup IGetNowMethodInvocationImposterGroupContinuation.Then()
+ {
+ this._currentInvocationImposter = _invocationImposterGroup.AddInvocationImposter();
+ return this;
+ }
+
+ void GetNowInvocationVerifier.Called(global::Imposter.Abstractions.Count count)
+ {
+ var invocationCount = _getNowMethodInvocationHistoryCollection.Count();
+ if (!count.Matches(invocationCount))
+ {
+ throw new global::Imposter.Abstractions.VerificationFailedException(count, invocationCount, _getNowMethodInvocationHistoryCollection.ToString());
+ }
+ }
+ }
+ }
+
+ public delegate global::System.DateTime GetUtcNowDelegate();
+ public delegate void GetUtcNowCallbackDelegate();
+ public delegate global::System.Exception GetUtcNowExceptionGeneratorDelegate();
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetUtcNowMethodInvocationHistory
+ {
+ bool Matches();
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetUtcNowMethodInvocationHistory : IGetUtcNowMethodInvocationHistory
+ {
+ internal global::System.DateTime? Result;
+ internal global::System.Exception? Exception;
+ public GetUtcNowMethodInvocationHistory(global::System.DateTime? Result, global::System.Exception? Exception)
+ {
+ this.Result = Result;
+ this.Exception = Exception;
+ }
+
+ public bool Matches()
+ {
+ return true;
+ }
+
+ public override string ToString()
+ {
+ return "GetUtcNow(" + "" + ")" + " => " + FormatValue(Result) + (Exception == null ? "" : " threw " + FormatValue(Exception));
+ }
+
+ private static string FormatValue(object? value)
+ {
+ return "<" + (value?.ToString() ?? "null") + ">";
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetUtcNowMethodInvocationHistoryCollection
+ {
+ private readonly global::System.Collections.Concurrent.ConcurrentStack _invocationHistory = new global::System.Collections.Concurrent.ConcurrentStack();
+ internal void Add(IGetUtcNowMethodInvocationHistory invocationHistory)
+ {
+ _invocationHistory.Push(invocationHistory);
+ }
+
+ internal int Count()
+ {
+ return _invocationHistory.Count(it => it.Matches());
+ }
+
+ public override string ToString()
+ {
+ return string.Join(Environment.NewLine, _invocationHistory.Select(invocation => invocation.ToString()));
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ class GetUtcNowMethodInvocationImposterGroup
+ {
+ internal static GetUtcNowMethodInvocationImposterGroup Default = new GetUtcNowMethodInvocationImposterGroup();
+ private readonly global::System.Collections.Concurrent.ConcurrentQueue _invocationImposters = new global::System.Collections.Concurrent.ConcurrentQueue();
+ private MethodInvocationImposter? _lastestInvocationImposter;
+ public GetUtcNowMethodInvocationImposterGroup()
+ {
+ }
+
+ internal MethodInvocationImposter AddInvocationImposter()
+ {
+ MethodInvocationImposter invocationImposter = new MethodInvocationImposter();
+ _invocationImposters.Enqueue(invocationImposter);
+ return invocationImposter;
+ }
+
+ private MethodInvocationImposter? GetInvocationImposter()
+ {
+ if (_invocationImposters.TryDequeue(out var invocationImposter))
+ {
+ if (!invocationImposter.IsEmpty)
+ {
+ _lastestInvocationImposter = invocationImposter;
+ }
+
+ return invocationImposter;
+ }
+
+ return _lastestInvocationImposter;
+ }
+
+ public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
+ {
+ var invocationImposter = GetInvocationImposter();
+ if (invocationImposter == null)
+ {
+ if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
+ }
+
+ invocationImposter = MethodInvocationImposter.Default;
+ }
+
+ return invocationImposter.Invoke(invocationBehavior, methodDisplayName);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class MethodInvocationImposter
+ {
+ internal static MethodInvocationImposter Default;
+ static MethodInvocationImposter()
+ {
+ Default = new MethodInvocationImposter();
+ Default.Returns(DefaultResultGenerator);
+ }
+
+ private GetUtcNowDelegate? _resultGenerator;
+ private readonly global::System.Collections.Concurrent.ConcurrentQueue _callbacks = new global::System.Collections.Concurrent.ConcurrentQueue();
+ internal bool IsEmpty => (_resultGenerator == null) && (_callbacks.Count == 0);
+
+ public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
+ {
+ if (_resultGenerator == null)
+ {
+ if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
+ }
+
+ _resultGenerator = DefaultResultGenerator;
+ }
+
+ global::System.DateTime result = _resultGenerator.Invoke();
+ foreach (var callback in _callbacks)
+ {
+ callback();
+ }
+
+ return result;
+ }
+
+ internal void Callback(GetUtcNowCallbackDelegate callback)
+ {
+ _callbacks.Enqueue(callback);
+ }
+
+ internal void Returns(GetUtcNowDelegate resultGenerator)
+ {
+ _resultGenerator = resultGenerator;
+ }
+
+ internal void Returns(global::System.DateTime value)
+ {
+ _resultGenerator = () =>
+ {
+ return value;
+ };
+ }
+
+ internal void Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator)
+ {
+ _resultGenerator = () =>
+ {
+ throw exceptionGenerator();
+ };
+ }
+
+ internal static global::System.DateTime DefaultResultGenerator()
+ {
+ return default !;
+ }
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetUtcNowMethodInvocationImposterGroupCallback
+ {
+ IGetUtcNowMethodInvocationImposterGroupContinuation Callback(GetUtcNowCallbackDelegate callback);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetUtcNowMethodInvocationImposterGroupContinuation : IGetUtcNowMethodInvocationImposterGroupCallback
+ {
+ IGetUtcNowMethodInvocationImposterGroup Then();
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetUtcNowMethodInvocationImposterGroup : IGetUtcNowMethodInvocationImposterGroupCallback
+ {
+ IGetUtcNowMethodInvocationImposterGroupContinuation Throws()
+ where TException : global::System.Exception, new();
+ IGetUtcNowMethodInvocationImposterGroupContinuation Throws(global::System.Exception exception);
+ IGetUtcNowMethodInvocationImposterGroupContinuation Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator);
+ IGetUtcNowMethodInvocationImposterGroupContinuation Returns(GetUtcNowDelegate resultGenerator);
+ IGetUtcNowMethodInvocationImposterGroupContinuation Returns(global::System.DateTime value);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface GetUtcNowInvocationVerifier
+ {
+ void Called(Count count);
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public interface IGetUtcNowMethodImposterBuilder : IGetUtcNowMethodInvocationImposterGroup, IGetUtcNowMethodInvocationImposterGroupCallback, GetUtcNowInvocationVerifier
+ {
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class GetUtcNowMethodImposter
+ {
+ private readonly global::System.Collections.Concurrent.ConcurrentStack _invocationImposters = new global::System.Collections.Concurrent.ConcurrentStack();
+ private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection;
+ private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
+ public GetUtcNowMethodImposter(GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection, global::Imposter.Abstractions.ImposterMode _invocationBehavior)
+ {
+ this._getUtcNowMethodInvocationHistoryCollection = _getUtcNowMethodInvocationHistoryCollection;
+ this._invocationBehavior = _invocationBehavior;
+ }
+
+ public bool HasMatchingInvocationImposterGroup()
+ {
+ return FindMatchingInvocationImposterGroup() != null;
+ }
+
+ private GetUtcNowMethodInvocationImposterGroup? FindMatchingInvocationImposterGroup()
+ {
+ if (_invocationImposters.TryPeek(out var invocationImposterGroup))
+ return invocationImposterGroup;
+ else
+ return null;
+ }
+
+ public global::System.DateTime Invoke()
+ {
+ var matchingInvocationImposterGroup = FindMatchingInvocationImposterGroup();
+ if (matchingInvocationImposterGroup == default)
+ {
+ if (_invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
+ {
+ throw new global::Imposter.Abstractions.MissingImposterException("DateTime IMyClock.GetUtcNow()");
+ }
+
+ matchingInvocationImposterGroup = GetUtcNowMethodInvocationImposterGroup.Default;
+ }
+
+ try
+ {
+ var result = matchingInvocationImposterGroup.Invoke(_invocationBehavior, "DateTime IMyClock.GetUtcNow()");
+ _getUtcNowMethodInvocationHistoryCollection.Add(new GetUtcNowMethodInvocationHistory(result, default));
+ return result;
+ }
+ catch (global::System.Exception ex)
+ {
+ _getUtcNowMethodInvocationHistoryCollection.Add(new GetUtcNowMethodInvocationHistory(default !, ex));
+ throw;
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ internal class Builder : IGetUtcNowMethodImposterBuilder, IGetUtcNowMethodInvocationImposterGroupContinuation
+ {
+ private readonly GetUtcNowMethodImposter _imposter;
+ private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection;
+ private readonly GetUtcNowMethodInvocationImposterGroup _invocationImposterGroup;
+ private GetUtcNowMethodInvocationImposterGroup.MethodInvocationImposter _currentInvocationImposter;
+ public Builder(GetUtcNowMethodImposter _imposter, GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection)
+ {
+ this._imposter = _imposter;
+ this._getUtcNowMethodInvocationHistoryCollection = _getUtcNowMethodInvocationHistoryCollection;
+ this._invocationImposterGroup = new GetUtcNowMethodInvocationImposterGroup();
+ _imposter._invocationImposters.Push(_invocationImposterGroup);
+ this._currentInvocationImposter = this._invocationImposterGroup.AddInvocationImposter();
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws()
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw new TException();
+ });
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws(global::System.Exception exception)
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw exception;
+ });
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator)
+ {
+ _currentInvocationImposter.Throws(() =>
+ {
+ throw exceptionGenerator.Invoke();
+ });
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroupCallback.Callback(GetUtcNowCallbackDelegate callback)
+ {
+ _currentInvocationImposter.Callback(callback);
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Returns(GetUtcNowDelegate resultGenerator)
+ {
+ _currentInvocationImposter.Returns(resultGenerator);
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Returns(global::System.DateTime value)
+ {
+ _currentInvocationImposter.Returns(value);
+ return this;
+ }
+
+ IGetUtcNowMethodInvocationImposterGroup IGetUtcNowMethodInvocationImposterGroupContinuation.Then()
+ {
+ this._currentInvocationImposter = _invocationImposterGroup.AddInvocationImposter();
+ return this;
+ }
+
+ void GetUtcNowInvocationVerifier.Called(global::Imposter.Abstractions.Count count)
+ {
+ var invocationCount = _getUtcNowMethodInvocationHistoryCollection.Count();
+ if (!count.Matches(invocationCount))
+ {
+ throw new global::Imposter.Abstractions.VerificationFailedException(count, invocationCount, _getUtcNowMethodInvocationHistoryCollection.ToString());
+ }
+ }
+ }
+ }
+
+ public IMyClockImposter(global::Imposter.Abstractions.ImposterMode invocationBehavior = global::Imposter.Abstractions.ImposterMode.Implicit)
+ {
+ this._getNowMethodImposter = new GetNowMethodImposter(_getNowMethodInvocationHistoryCollection, invocationBehavior);
+ this._getUtcNowMethodImposter = new GetUtcNowMethodImposter(_getUtcNowMethodInvocationHistoryCollection, invocationBehavior);
+ this._imposterInstance = new ImposterTargetInstance(this);
+ this._invocationBehavior = invocationBehavior;
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ class ImposterTargetInstance : global::MockData.IMyClock
+ {
+ private readonly IMyClockImposter _imposter;
+ public ImposterTargetInstance(IMyClockImposter _imposter)
+ {
+ this._imposter = _imposter;
+ }
+
+ public global::System.DateTime GetNow()
+ {
+ return _imposter._getNowMethodImposter.Invoke();
+ }
+
+ public global::System.DateTime GetUtcNow()
+ {
+ return _imposter._getUtcNowMethodImposter.Invoke();
+ }
+ }
+ }
+
+ [global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
+ public static class IMyClockImposterExtensions
+ {
+ extension(global::MockData.IMyClock imposter)
+ {
+ public static global::MockData.IMyClockImposter Imposter(global::Imposter.Abstractions.ImposterMode invocationBehavior = global::Imposter.Abstractions.ImposterMode.Implicit) => new global::MockData.IMyClockImposter(invocationBehavior);
+ }
+ }
+}
+#nullable restore
+#pragma warning restore
+
+```
+
+
+
+
+## Useful
+
+### Download Example (.NET C#)
+
+:::tip
+
+[Download Example project Imposter ](/sources/Imposter.zip)
+
+:::
+
+
+### Share Imposter
+
+
+
+https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter
+
+
+
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md
index f47c84c99..9dccad6d4 100644
--- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md
@@ -1,7 +1,7 @@
---
sidebar_position: 30
-title: 245 RSCG list by category
-description: 245 RSCG list by category
+title: 246 RSCG list by category
+description: 246 RSCG list by category
slug: /rscg-examples
---
@@ -1468,7 +1468,7 @@ import DocCardList from '@theme/DocCardList';
## Tests
- Expand Tests =>examples:6
+ Expand Tests =>examples:7
@@ -1499,6 +1499,11 @@ import DocCardList from '@theme/DocCardList';
[TUnit](/docs/TUnit)
+
+
+
+[Imposter](/docs/Imposter)
+
@@ -2023,6 +2028,8 @@ flowchart LR;
Tests--> TUnit((TUnit))
+ Tests--> Imposter((Imposter))
+
Validator--> validly((validly))
WinAPI--> Com((Com))
diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md
index 904a77709..740ac833a 100644
--- a/v2/rscg_examples_site/docs/about.md
+++ b/v2/rscg_examples_site/docs/about.md
@@ -6,7 +6,7 @@ title: About
## Content
You will find here code examples
-of 245 Roslyn Source Code Generator (RSCG)
+of 246 Roslyn Source Code Generator (RSCG)
that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look.
## Are those examples ready for production?
diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md
index 6da998423..f18c9f45b 100644
--- a/v2/rscg_examples_site/docs/indexRSCG.md
+++ b/v2/rscg_examples_site/docs/indexRSCG.md
@@ -7,9 +7,9 @@ slug: /List-of-RSCG
import useBaseUrl from '@docusaurus/useBaseUrl';
-## 245 RSCG with examples in descending chronological order
+## 246 RSCG with examples in descending chronological order
-This is the list of 245 ( 16 from Microsoft) RSCG with examples
+This is the list of 246 ( 16 from Microsoft) RSCG with examples
[See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx)
@@ -20,6 +20,7 @@ This is the list of 245 ( 16 from Microsoft) RSCG with examples
| No | Name | Date | Category |
| --------- | ----- | ---- | -------- |
+|246| [Imposter by Bitchiko Tchelidze ](/docs/Imposter)|2025-12-13 => 13 December 2025 | [Tests](/docs/Categories/Tests) |
|245| [Monify by Paul Martin ](/docs/Monify)|2025-12-12 => 12 December 2025 | [PrimitiveObsession](/docs/Categories/PrimitiveObsession) |
|244| [BoolParameterGenerator by Justin Buchanan ](/docs/BoolParameterGenerator)|2025-12-11 => 11 December 2025 | [Bool](/docs/Categories/Bool) |
|243| [RSCG_MCP2File by Ignat Andrei ](/docs/RSCG_MCP2File)|2025-11-15 => 15 November 2025 | [MCP](/docs/Categories/MCP) |
diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
index 3a4920621..42d50ed24 100644
--- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
+++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
@@ -4,7 +4,7 @@ import styles from './styles.module.css';
const FeatureList = [
{
-title: '245 Examples (16 from MSFT)',
+title: '246 Examples (16 from MSFT)',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json
index b799df359..6149353ad 100644
--- a/v2/rscg_examples_site/static/exports/RSCG.json
+++ b/v2/rscg_examples_site/static/exports/RSCG.json
@@ -1961,6 +1961,14 @@
"Source": "https://github.com/MooVC/monify",
"Category": "PrimitiveObsession",
"AddedOn": "2025-12-12T00:00:00"
+ },
+ {
+ "Name": "Imposter",
+ "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter",
+ "NuGet": "https://www.nuget.org/packages/Imposter/",
+ "Source": "https://github.com/themidnightgospel/Imposter",
+ "Category": "Tests",
+ "AddedOn": "2025-12-13T00:00:00"
}
]
}
\ No newline at end of file
diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx
index 126eb4dd9..4431d5710 100644
Binary files a/v2/rscg_examples_site/static/exports/RSCG.xlsx and b/v2/rscg_examples_site/static/exports/RSCG.xlsx differ
diff --git a/v2/rscg_examples_site/static/sources/Imposter.zip b/v2/rscg_examples_site/static/sources/Imposter.zip
new file mode 100644
index 000000000..33007020e
Binary files /dev/null and b/v2/rscg_examples_site/static/sources/Imposter.zip differ