EasyTdd.Generators
0.5.2
dotnet add package EasyTdd.Generators --version 0.5.2
NuGet\Install-Package EasyTdd.Generators -Version 0.5.2
<PackageReference Include="EasyTdd.Generators" Version="0.5.2" />
<PackageVersion Include="EasyTdd.Generators" Version="0.5.2" />
<PackageReference Include="EasyTdd.Generators" />
paket add EasyTdd.Generators --version 0.5.2
#r "nuget: EasyTdd.Generators, 0.5.2"
#:package EasyTdd.Generators@0.5.2
#addin nuget:?package=EasyTdd.Generators&version=0.5.2
#tool nuget:?package=EasyTdd.Generators&version=0.5.2
EasyTdd.Generators
EasyTdd.Generators works in tandem with EasyTdd, a Visual Studio extension that enhances test-driven development (available at Visual Studio Marketplace). This package leverages a .NET incremental source generator to create builders and FluentMock classes from templates used by the EasyTdd extension. The builder generator handles property setters, constructor parameters, and a combination of both. It also supports generic parameters. The FluentMock generator is a wrapper for the well-known mocking framework Moq. It generates specific Setup and Verify methods for each method and property of the target type, allowing setup and verification with less code and less pain. If the EasyTdd settings are not available, it uses default settings. For more information, visit easytdd.dev.
Release notes
0.5.2
Updated generator to be independent of settings in .easyTdd. It now uses default settings if .easyTdd is missing. Fixed issues in builder and fluentMock regarding inheritance chain, properties with the new
keyword, and indexers.
0.5.0.4
Bug fix. Resolved an issue in the builder where code was being generated for properties that do not have a public setter.
0.5.0.3
Bug fix. Resolved an issue in builder and test generation where a derived class overriding a member would result in code being generated for both the base class member and the overridden member of the derived class.
0.5.0.1
Updated to maintain backward compatibility with version 0.4.0.5.
0.5.0.0
Implemented an incremental source generator for FluentMock.
0.4.0.5
Fixed a bug where generation failed when the incremental builder was generated for two classes in different namespaces but with the same.
0.4.0.3
Fixed a bug where generation failed if the settings used a template from the root .easyTdd directory and a template with the same name existed in a subdirectory.
0.4.0.0
The first release. Version numbering starts from 0.4.0.0 to align with the corresponding version of EasyTdd, a Visual Studio extension that enhances test-driven development. This version includes an incremental source generator for a builder.
How it works?
The EasyTdd.Generators package, implemented as an analyzer that includes an IIncrementalGenerator, accesses the .easyTdd folder containing configurations created by the EasyTdd Visual Studio extension. Utilizing templates and settings within this folder, the generator efficiently produces the builder and fluentMock classes.
Examples
Incremental builder
Target class SampleClass.cs
public class SampleClass<T>
where T : class
{
public SampleClass(T value, int id)
{
Value = value;
Id = id;
}
public T Value { get; }
public int Id { get; }
public string Name { get; set; }
public string Description { get; set; }
}
Builder class SampleClassBuilder.cs
[BuilderFor(typeof(SampleClass<>))]
public partial class SampleClassBuilder<T>
{
public SampleClassBuilder<T> Default()
{
return new SampleClassBuilder<T>(
default,
1,
"Jovaras",
"Augalas"
);
}
}
Generated class SampleClassBuilder.g.cs
public partial class SampleClassBuilder<T>
where T : class
{
private Func<T> _value;
private Func<int> _id;
private Func<string> _name;
private Func<string> _description;
public static implicit operator EasyTdd.Generators.ForTestingByNugetPackageReference.SampleClass<T>(SampleClassBuilder<T> builder) => builder.Build();
public SampleClassBuilder(
Func<T> value,
Func<int> id,
Func<string> name,
Func<string> description)
{
_value = value;
_id = id;
_name = name;
_description = description;
}
public SampleClassBuilder(
T value,
int id,
string name,
string description)
{
_value = () => value;
_id = () => id;
_name = () => name;
_description = () => description;
}
public EasyTdd.Generators.ForTestingByNugetPackageReference.SampleClass<T> Build()
{
return new EasyTdd.Generators.ForTestingByNugetPackageReference.SampleClass<T>(
_value(),
_id())
{
Name = _name(),
Description = _description()
};
}
public SampleClassBuilder<T> WithValue(Func<T> value)
{
_value = value;
return this;
}
public SampleClassBuilder<T> WithValue(T value)
{
return WithValue(() => value);
}
public SampleClassBuilder<T> WithId(Func<int> value)
{
_id = value;
return this;
}
public SampleClassBuilder<T> WithId(int value)
{
return WithId(() => value);
}
public SampleClassBuilder<T> WithName(Func<string> value)
{
_name = value;
return this;
}
public SampleClassBuilder<T> WithName(string value)
{
return WithName(() => value);
}
public SampleClassBuilder<T> WithDescription(Func<string> value)
{
_description = value;
return this;
}
public SampleClassBuilder<T> WithDescription(string value)
{
return WithDescription(() => value);
}
}
Incremental FluentMock
Target interface ISomeInterface.cs
public interface ISomeInterface
{
SomeResultType Resolve(int id, string value, SomeOtherResultType someOtherResultType);
}
FluentMock class SomeInterfaceMock.cs
[EasyTdd.Generators.FluentMockFor(typeof(ISomeInterface))]
public partial class SomeInterfaceMock
{
public static SomeInterfaceMock Create()
{
return new SomeInterfaceMock();
}
}
Generated FluentMock class SomeInterfaceMock.g.cs
// <auto-generated>
// This code was generated by EasyTdd.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. Use a partial class for additional behavior.
// </auto-generated>
#nullable enable
using Moq;
using System;
namespace EasyTdd.Generators.ForTestingByProjectReference.ForDebug
{
public partial class SomeInterfaceMock : Mock<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.ISomeInterface>
{
public SomeInterfaceMock() : base(MockBehavior.Strict)
{ }
public SomeInterfaceMock SetupResolve(
Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeResultType> result,
Func<int, bool>? isId = null,
Func<string, bool>? isValue = null,
Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType, bool>? isSomeOtherResultType = null,
bool verifiable = true)
{
var setup = Setup(
x => x.Resolve(
It.Is<int>(fromMock => isId == null || isId(fromMock)),
It.Is<string>(fromMock => isValue == null || isValue(fromMock)),
It.Is<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType>(fromMock => isSomeOtherResultType == null || isSomeOtherResultType(fromMock))
)
)
.Returns(result);
if (verifiable)
{
setup.Verifiable();
}
return this;
}
public SomeInterfaceMock SetupResolve(
Func<int, string, EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType, EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeResultType> result,
Func<int, bool>? isId = null,
Func<string, bool>? isValue = null,
Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType, bool>? isSomeOtherResultType = null,
bool verifiable = true)
{
var setup = Setup(
x => x.Resolve(
It.Is<int>(fromMock => isId == null || isId(fromMock)),
It.Is<string>(fromMock => isValue == null || isValue(fromMock)),
It.Is<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType>(fromMock => isSomeOtherResultType == null || isSomeOtherResultType(fromMock))
)
)
.Returns(result);
if (verifiable)
{
setup.Verifiable();
}
return this;
}
public SomeInterfaceMock SetupResolveSequence(
IEnumerable<Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeResultType>> results,
Func<int, bool>? isId = null,
Func<string, bool>? isValue = null,
Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType, bool>? isSomeOtherResultType = null)
{
var sequenceSetup =
SetupSequence(
x => x.Resolve(
It.Is<int>(fromMock => isId == null || isId(fromMock)),
It.Is<string>(fromMock => isValue == null || isValue(fromMock)),
It.Is<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType>(fromMock => isSomeOtherResultType == null || isSomeOtherResultType(fromMock))
)
);
foreach (var result in results)
{
sequenceSetup.Returns(result);
}
return this;
}
public SomeInterfaceMock VerifyResolve(
Func<int, bool>? isId = null,
Func<string, bool>? isValue = null,
Func<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType, bool>? isSomeOtherResultType = null,
Func<Times>? times = null)
{
Verify(
x => x.Resolve(
It.Is<int>(fromMock => isId == null || isId(fromMock)),
It.Is<string>(fromMock => isValue == null || isValue(fromMock)),
It.Is<EasyTdd.Generators.ForTestingByProjectReference.ForDebug.SomeOtherResultType>(fromMock => isSomeOtherResultType == null || isSomeOtherResultType(fromMock))
),
times ?? Times.AtLeastOnce
);
return this;
}
}
}
FluentMock usage
public class UsageTest
{
[Test]
public void Test()
{
var expectedResult1 = new SomeResultType();
var expectedResult2 = new SomeResultType();
var mock = SomeInterfaceMock
.Create()
.SetupResolve(
() => expectedResult1,
isId: x => x == 1
)
.SetupResolve(
() => expectedResult2,
isId: x => x == 2
);
mock
.Object
.Resolve(
1,
"",
new SomeOtherResultType()
)
.Should()
.Be(expectedResult1);
mock
.Object
.Resolve(
2,
"",
new SomeOtherResultType()
)
.Should()
.Be(expectedResult2);
}
}
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 4.9.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
0.5.2 - Updated generator to be independent of settings in .easyTdd. It now uses default settings if .easyTdd is missing. Fixed issues in builder and fluentMock regarding inheritance chain, properties with the `new` keyword, and indexers.