Skip to content

Commit

Permalink
Updated editorconfig and auto-cleaned source (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
MelGrubb authored May 27, 2023
1 parent 2dc859e commit 1f487e9
Show file tree
Hide file tree
Showing 19 changed files with 271 additions and 131 deletions.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# BuilderGenerator

This NuGet package automates the generation of object builders for testing. It generates the repetitive part of creating builders, leaving only the more interesting, hand-curated parts for you to create as partial classes.
This NuGet package automates the generation of object builders for testing. It generates the repetitive part of creating builders, leaving only the more interesting, hand-curated parts for you to implement as partial classes.

With the v2.0 release, the mechanism has changed. Rather than decorating entity classes with the "GenerateBuilder" attribute, as was done in v1.x, you now create a partial builder class and decorate it with the "BuilderFor" attribute. This makes it possible to generate builders anywhere you want rather than always creating them in the same assembly as the entities. Builders can be used as part of normal development, but are most commonly used in testing scenarios and many development teams would prefer not to "pollute" their domain assembly with knowledge of classes created for the benefit of their test assemblies. Of course, if you want to use builders as part of normal business logic, you can simply create and decorate the partial builder classes in the domain assembly and achieve the same effect as in the v1.x releases.

Expand Down
22 changes: 8 additions & 14 deletions src/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,6 @@ csharp_prefer_braces = true:suggestion
csharp_style_namespace_declarations = file_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_expression_bodied_methods = when_on_single_line:none
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_operators = false:none
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_indent_labels = no_change
csharp_style_throw_expression = true:suggestion
csharp_style_prefer_null_check_over_type_check = true:suggestion
Expand Down Expand Up @@ -422,12 +414,14 @@ csharp_style_var_elsewhere=true:suggestion


# Expression-bodied members
csharp_style_expression_bodied_methods=when_on_single_line:none
csharp_style_expression_bodied_constructors=false:none
csharp_style_expression_bodied_operators=false:none
csharp_style_expression_bodied_properties=true:none
csharp_style_expression_bodied_indexers=true:none
csharp_style_expression_bodied_accessors=true:none
csharp_style_expression_bodied_methods = false:none
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_operators = false:none
csharp_style_expression_bodied_properties = false:none
csharp_style_expression_bodied_indexers = false:none
csharp_style_expression_bodied_accessors = false:none
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent


# Pattern matching:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ public void Simple_does_not_populate_Orders()
}

[Test]
public void Simple_returns_a_UserBuilder() => UserBuilder.Simple().ShouldBeOfType<UserBuilder>();
public void Simple_returns_a_UserBuilder()
{
UserBuilder.Simple().ShouldBeOfType<UserBuilder>();
}

[Test]
public void Typical_populates_Orders()
Expand All @@ -35,7 +38,10 @@ public void Typical_populates_Orders()
}

[Test]
public void Typical_returns_a_UserBuilder() => UserBuilder.Typical().ShouldBeOfType<UserBuilder>();
public void Typical_returns_a_UserBuilder()
{
UserBuilder.Typical().ShouldBeOfType<UserBuilder>();
}

[Test]
public void UserBuilder_can_set_properties()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ public void Simple_does_not_populate_Items()
}

[Test]
public void Simple_returns_an_OrderBuilder() => OrderBuilder.Simple().ShouldBeOfType<OrderBuilder>();
public void Simple_returns_an_OrderBuilder()
{
OrderBuilder.Simple().ShouldBeOfType<OrderBuilder>();
}

[Test]
public void Typical_populates_Items()
Expand All @@ -45,7 +48,10 @@ public void Typical_populates_Items()
}

[Test]
public void Typical_returns_an_OrderBuilder() => OrderBuilder.Typical().ShouldBeOfType<OrderBuilder>();
public void Typical_returns_an_OrderBuilder()
{
OrderBuilder.Typical().ShouldBeOfType<OrderBuilder>();
}

[OneTimeSetUp]
public void SetUp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ public void Simple_does_not_populate_Orders()
}

[Test]
public void Simple_returns_a_UserBuilder() => UserBuilder.Simple().ShouldBeOfType<UserBuilder>();
public void Simple_returns_a_UserBuilder()
{
UserBuilder.Simple().ShouldBeOfType<UserBuilder>();
}

[Test]
public void Typical_populates_Orders()
Expand All @@ -35,7 +38,10 @@ public void Typical_populates_Orders()
}

[Test]
public void Typical_returns_a_UserBuilder() => UserBuilder.Typical().ShouldBeOfType<UserBuilder>();
public void Typical_returns_a_UserBuilder()
{
UserBuilder.Typical().ShouldBeOfType<UserBuilder>();
}

[Test]
public void UserBuilder_can_set_properties()
Expand Down
16 changes: 10 additions & 6 deletions src/BuilderGenerator.UnitTests/BuilderGenerator.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
Expand All @@ -8,13 +8,17 @@
</PropertyGroup>

<ItemGroup>
<Compile Remove="Examples\Input.cs" />
<Compile Remove="Examples\Output.cs" />
<Compile Remove="Examples\InputWithInternals.cs" />
<Compile Remove="Examples\InputWithoutInternals.cs" />
<Compile Remove="Examples\OutputWithInternals.cs" />
<Compile Remove="Examples\OutputWithoutInternals.cs" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Examples\Input.cs" />
<EmbeddedResource Include="Examples\Output.cs" />
<EmbeddedResource Include="Examples\InputWithInternals.cs" />
<EmbeddedResource Include="Examples\InputWithoutInternals.cs" />
<EmbeddedResource Include="Examples\OutputWithInternals.cs" />
<EmbeddedResource Include="Examples\OutputWithoutInternals.cs" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -42,4 +46,4 @@
</EmbeddedResource>
</ItemGroup>

</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
internal string InternalString { get; set; }
}

[BuilderFor(typeof(Person))]
public partial class PersonBuilder
[BuilderFor(typeof(Person), true)]
public partial class PersonBuilderWithInternals
{
}
}
16 changes: 16 additions & 0 deletions src/BuilderGenerator.UnitTests/Examples/InputWithoutInternals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using BuilderGenerator;

namespace BuilderGenerator.UnitTests
{
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
internal string InternalString { get; set; }
}

[BuilderFor(typeof(Person), false)]
public partial class PersonBuilderWithoutInternals
{
}
}
87 changes: 87 additions & 0 deletions src/BuilderGenerator.UnitTests/Examples/OutputWithInternals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#nullable disable

using System.CodeDom.Compiler;
using BuilderGenerator;

namespace BuilderGenerator.UnitTests
{
public partial class PersonBuilderWithInternals : BuilderGenerator.Builder<BuilderGenerator.UnitTests.Person>
{
public System.Lazy<string> FirstName = new System.Lazy<string>(() => default(string));
public System.Lazy<string> InternalString = new System.Lazy<string>(() => default(string));
public System.Lazy<string> LastName = new System.Lazy<string>(() => default(string));

public override BuilderGenerator.UnitTests.Person Build()
{
if (Object?.IsValueCreated != true)
{
Object = new System.Lazy<BuilderGenerator.UnitTests.Person>(() =>
{
var result = new BuilderGenerator.UnitTests.Person
{
FirstName = FirstName.Value,
InternalString = InternalString.Value,
LastName = LastName.Value,
};
return result;
});

PostProcess(Object.Value);
}

return Object.Value;
}

public PersonBuilderWithInternals WithFirstName(string value)
{
return WithFirstName(() => value);
}

public PersonBuilderWithInternals WithFirstName(System.Func<string> func)
{
FirstName = new System.Lazy<string>(func);
return this;
}

public PersonBuilderWithInternals WithoutFirstName()
{
FirstName = new System.Lazy<string>(() => default(string));
return this;
}

public PersonBuilderWithInternals WithInternalString(string value)
{
return WithInternalString(() => value);
}

public PersonBuilderWithInternals WithInternalString(System.Func<string> func)
{
InternalString = new System.Lazy<string>(func);
return this;
}

public PersonBuilderWithInternals WithoutInternalString()
{
InternalString = new System.Lazy<string>(() => default(string));
return this;
}

public PersonBuilderWithInternals WithLastName(string value)
{
return WithLastName(() => value);
}

public PersonBuilderWithInternals WithLastName(System.Func<string> func)
{
LastName = new System.Lazy<string>(func);
return this;
}

public PersonBuilderWithInternals WithoutLastName()
{
LastName = new System.Lazy<string>(() => default(string));
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace BuilderGenerator.UnitTests
{
public partial class PersonBuilder : BuilderGenerator.Builder<BuilderGenerator.UnitTests.Person>
public partial class PersonBuilderWithoutInternals : BuilderGenerator.Builder<BuilderGenerator.UnitTests.Person>
{
public System.Lazy<string> FirstName = new System.Lazy<string>(() => default(string));
public System.Lazy<string> LastName = new System.Lazy<string>(() => default(string));
Expand All @@ -31,35 +31,35 @@ public override BuilderGenerator.UnitTests.Person Build()
return Object.Value;
}

public PersonBuilder WithFirstName(string value)
public PersonBuilderWithoutInternals WithFirstName(string value)
{
return WithFirstName(() => value);
}

public PersonBuilder WithFirstName(System.Func<string> func)
public PersonBuilderWithoutInternals WithFirstName(System.Func<string> func)
{
FirstName = new System.Lazy<string>(func);
return this;
}

public PersonBuilder WithoutFirstName()
public PersonBuilderWithoutInternals WithoutFirstName()
{
FirstName = new System.Lazy<string>(() => default(string));
return this;
}

public PersonBuilder WithLastName(string value)
public PersonBuilderWithoutInternals WithLastName(string value)
{
return WithLastName(() => value);
}

public PersonBuilder WithLastName(System.Func<string> func)
public PersonBuilderWithoutInternals WithLastName(System.Func<string> func)
{
LastName = new System.Lazy<string>(func);
return this;
}

public PersonBuilder WithoutLastName()
public PersonBuilderWithoutInternals WithoutLastName()
{
LastName = new System.Lazy<string>(() => default(string));
return this;
Expand Down
42 changes: 7 additions & 35 deletions src/BuilderGenerator.UnitTests/Given_a_BuilderGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,13 @@
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using NUnit.Framework;
using Shouldly;

// ReSharper disable InconsistentNaming

namespace BuilderGenerator.UnitTests;

[TestFixture]
public class GeneratorTests
public abstract class Given_a_BuilderGenerator
{
[Test]
public void SimpleGeneratorTest()
{
var assembly = GetType().Assembly;
var inputCompilation = CreateCompilation(GetResourceAsString(assembly, "Input.cs"));
var expectedOutput = GetResourceAsString(assembly, "Output.cs");
GeneratorDriver driver = CSharpGeneratorDriver.Create(new BuilderGenerator());
driver = driver.RunGeneratorsAndUpdateCompilation(inputCompilation, out var outputCompilation, out var diagnostics);
diagnostics.ShouldBeEmpty();
outputCompilation.SyntaxTrees.Count().ShouldBe(4);

var runResult = driver.GetRunResult();
runResult.Diagnostics.ShouldBeEmpty();
runResult.GeneratedTrees.Length.ShouldBe(3); // The Builder base class, the BuilderFor attribute, and the generated builder.

// TODO: Check for the presence of the Builder base class.
// TODO: Check for the presence of the BuilderForAttribute class.

var generatorResult = runResult.Results[0];
generatorResult.Generator.GetGeneratorType().ShouldBe(new BuilderGenerator().GetType());
generatorResult.Exception.ShouldBeNull();
generatorResult.GeneratedSources.Length.ShouldBe(3);

var sourceText = generatorResult.GeneratedSources[2].SourceText.ToString();

// Since the generation time will keep changing, we'll just compare everything after the first instance of the word "using".
sourceText[sourceText.IndexOf("using", StringComparison.OrdinalIgnoreCase)..].ShouldBe(expectedOutput[expectedOutput.IndexOf("using", StringComparison.OrdinalIgnoreCase)..]);
}

public static string GetResourceAsString(Assembly assembly, string resourceName)
{
var manifestResourceNames = assembly.GetManifestResourceNames();
Expand All @@ -60,10 +30,12 @@ public static string GetResourceAsString(Assembly assembly, string resourceName)
}
}

private static Compilation CreateCompilation(string source)
=> CSharpCompilation.Create(
protected static Compilation CreateCompilation(string source)
{
return CSharpCompilation.Create(
"compilation",
new[] { CSharpSyntaxTree.ParseText(source) },
new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) },
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
}
}
Loading

0 comments on commit 1f487e9

Please sign in to comment.