Skip to content

Commit

Permalink
Release 0.11.0 (#37)
Browse files Browse the repository at this point in the history
* Added interface builder
* Changed method builder so it add a semicolon if you set body to null
  • Loading branch information
MilleBo authored Aug 6, 2019
1 parent b69021c commit a55df75
Show file tree
Hide file tree
Showing 11 changed files with 380 additions and 219 deletions.
1 change: 0 additions & 1 deletion src/Testura.Code.Tests/Builders/ClassBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public void Build_WhenGivenModifiers_CodeShouldContainModifiers()
[Test]
public void Build_WhenGivenInheritance_CodeShouldContainInheritance()
{
var o = _classBuilder.ThatInheritFrom(typeof(int)).Build().ToString();
Assert.IsTrue(_classBuilder.ThatInheritFrom(typeof(int)).Build().ToString().Contains("TestClass:int"));
}
}
Expand Down
64 changes: 64 additions & 0 deletions src/Testura.Code.Tests/Builders/InterfaceBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using NUnit.Framework;
using Testura.Code.Builders;
using Testura.Code.Models;
using Testura.Code.Models.Properties;

namespace Testura.Code.Tests.Builders
{
[TestFixture]
public class InterfaceBuilderTests
{
private InterfaceBuilder _interfaceBuilder;

[SetUp]
public void SetUp()
{
_interfaceBuilder = new InterfaceBuilder("TestInterface", "MyNamespace");
}

[Test]
public void Build_WhenGivenClassName_CodeShouldContainClassName()
{
Assert.IsTrue(_interfaceBuilder.Build().ToString().Contains("TestInterface"));
}

[Test]
public void Build_WhenGivenNamespace_CodeShouldContainNamespace()
{
Assert.IsTrue(_interfaceBuilder.Build().ToString().Contains("MyNamespace"));
}

[Test]
public void Build_WhenGivenAttributes_CodeShouldContainAttributes()
{
Assert.IsTrue(_interfaceBuilder.WithAttributes(new Attribute("MyAttribute")).Build().ToString().Contains("[MyAttribute]"));
}


[Test]
public void Build_WhenGivenProperty_CodeShouldContainProperty()
{
Assert.IsTrue(_interfaceBuilder.WithProperties(new AutoProperty("MyProperty", typeof(int), PropertyTypes.GetAndSet)).Build().ToString().Contains("intMyProperty{get;set;}"));
}

[Test]
public void Build_WhenGivenUsing_CodeShouldContainUsing()
{
Assert.IsTrue(_interfaceBuilder.WithUsings("some.namespace").Build().ToString().Contains("some.namespace"));
}


[Test]
public void Build_WhenGivenModifiers_CodeShouldContainModifiers()
{
Assert.IsTrue(_interfaceBuilder.WithModifiers(Modifiers.Public, Modifiers.Abstract).Build().ToString().Contains("publicabstractinterfaceTestInterface"));
}

[Test]
public void Build_WhenGivenInheritance_CodeShouldContainInheritance()
{
var o = _interfaceBuilder.ThatInheritFrom(typeof(int)).Build().ToString();
Assert.IsTrue(_interfaceBuilder.ThatInheritFrom(typeof(int)).Build().ToString().Contains("TestInterface:int"));
}
}
}
19 changes: 15 additions & 4 deletions src/Testura.Code.Tests/Builders/MethodBuildersTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,32 @@ public void Build_WhenGivingMethodName_CodeShouldContainName()
public void Build_WhenGivingAttribute_CodeShouldContainAttribute()
{
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithAttributes(new Attribute("MyAttribute")).Build().ToString().Contains("[MyAttribute]"));
Assert.IsTrue(builder.WithAttributes(new Attribute("MyAttribute")).Build().ToString()
.Contains("[MyAttribute]"));
}

[Test]
public void Build_WhenGivingModifier_CodeShouldContainModifiers()
{
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithModifiers(Modifiers.Public, Modifiers.Abstract).Build().ToString().Contains("publicabstract"));
Assert.IsTrue(builder.WithModifiers(Modifiers.Public, Modifiers.Abstract).Build().ToString()
.Contains("publicabstract"));
}

[Test]
public void Build_WhenGivingParameters_CodeShouldContainParamters()
{
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithParameters(new Parameter("myParamter", typeof(int))).Build().ToString().Contains("intmyParamter"));
Assert.IsTrue(builder.WithParameters(new Parameter("myParamter", typeof(int))).Build().ToString()
.Contains("intmyParamter"));
}

[Test]
public void Build_WhenGivingParameterWithModifier_CodeShouldContainParamters()
{
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithParameters(new Parameter("myParamter", typeof(int), ParameterModifiers.This)).Build().ToString().Contains("thisintmyParamter"));
Assert.IsTrue(builder.WithParameters(new Parameter("myParamter", typeof(int), ParameterModifiers.This))
.Build().ToString().Contains("thisintmyParamter"));
}

[Test]
Expand All @@ -48,5 +52,12 @@ public void Build_WhenGivingReturnType_CodeShouldContainReturn()
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithReturnType(typeof(int)).Build().ToString().Contains("intMyMethod()"));
}

[Test]
public void Build_WhenGivingNullBody_CodeShouldContainMethodWithSemicolonAtTheEnd()
{
var builder = new MethodBuilder("MyMethod");
Assert.IsTrue(builder.WithBody(null).Build().ToString().Contains("MyMethod();"));
}
}
}
1 change: 1 addition & 0 deletions src/Testura.Code.Tests/Testura.Code.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AppDomains\AppDomainCodeGeneratorTests.cs" />
<Compile Include="Builders\InterfaceBuilderTests.cs" />
<Compile Include="Builders\ClassBuilderTests.cs" />
<Compile Include="Builders\MethodBuildersTest.cs" />
<Compile Include="Compilation\CompilerTests.cs" />
Expand Down
207 changes: 7 additions & 200 deletions src/Testura.Code/Builders/ClassBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,117 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Generators.Class;
using Testura.Code.Generators.Common;
using Testura.Code.Models;
using Testura.Code.Models.Properties;
using Attribute = Testura.Code.Models.Attribute;

namespace Testura.Code.Builders
{
/// <summary>
/// Provides a builder to generate a class
/// </summary>
public class ClassBuilder
public class ClassBuilder : TypeBuilderBase<ClassBuilder>
{
private readonly string _name;
private readonly string _namespace;
private readonly List<string> _usings;
private readonly List<Modifiers> _modifiers;
private readonly List<MethodDeclarationSyntax> _methods;
private readonly List<Type> _inheritance;
private readonly List<FieldDeclarationSyntax> _fields;
private readonly List<PropertyDeclarationSyntax> _properties;
private ConstructorDeclarationSyntax _constructor;

private SyntaxList<AttributeListSyntax> _attributes;

/// <summary>
/// Initializes a new instance of the <see cref="ClassBuilder"/> class.
/// </summary>
/// <param name="name">Name of the class.</param>
/// <param name="namespace">Name of the class namespace.</param>
public ClassBuilder(string name, string @namespace)
: base(name, @namespace)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("Value cannot be null or empty.", nameof(name));
}

if (string.IsNullOrEmpty(@namespace))
{
throw new ArgumentException("Value cannot be null or empty.", nameof(@namespace));
}

_name = name.Replace(" ", "_");
_namespace = @namespace;
_methods = new List<MethodDeclarationSyntax>();
_inheritance = new List<Type>();
_modifiers = new List<Modifiers> { Modifiers.Public };
_fields = new List<FieldDeclarationSyntax>();
_properties = new List<PropertyDeclarationSyntax>();
_usings = new List<string>();
}

/// <summary>
/// Set the using directives.
/// </summary>
/// <param name="usings">A set of wanted using directive names.</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithUsings(params string[] usings)
{
_usings.Clear();
_usings.AddRange(usings);
return this;
}

/// <summary>
/// Set class modifiers
/// </summary>
/// <param name="modifier">A set of wanted modifiers.</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithModifiers(params Modifiers[] modifier)
{
_modifiers.Clear();
_modifiers.AddRange(modifier);
return this;
}

/// <summary>
/// Set type(s) that the generated class should inherit from.
/// </summary>
/// <param name="types">A set of types to inherit from.</param>
/// <returns>The current class builder</returns>
public ClassBuilder ThatInheritFrom(params Type[] types)
{
_inheritance.Clear();
_inheritance.AddRange(types);
return this;
}

/// <summary>
/// Set class attributes.
/// </summary>
/// <param name="attributes">A set of wanted attributes.</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithAttributes(params Attribute[] attributes)
{
_attributes = AttributeGenerator.Create(attributes);
return this;
}

/// <summary>
/// Set class attributes.
/// </summary>
/// <param name="attributes">A syntax list of already generated attributes.</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithAttributes(SyntaxList<AttributeListSyntax> attributes)
{
_attributes = attributes;
return this;
}

/// <summary>
Expand Down Expand Up @@ -153,46 +65,6 @@ public ClassBuilder WithConstructor(ConstructorDeclarationSyntax constructor)
return this;
}

/// <summary>
/// Set class methods.
/// </summary>
/// <param name="methods">A set of already generated methods</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithMethods(params MethodDeclarationSyntax[] methods)
{
_methods.Clear();
_methods.AddRange(methods);
return this;
}

/// <summary>
/// Set class properties.
/// </summary>
/// <param name="properties">A set of wanted properties.</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithProperties(params Property[] properties)
{
_properties.Clear();
foreach (var property in properties)
{
_properties.Add(PropertyGenerator.Create(property));
}

return this;
}

/// <summary>
/// A class properties.
/// </summary>
/// <param name="properties">A sete of already generated properties</param>
/// <returns>The current class builder</returns>
public ClassBuilder WithProperties(params PropertyDeclarationSyntax[] properties)
{
_properties.Clear();
_properties.AddRange(properties);
return this;
}

/// <summary>
/// Build the class and return the generated code.
/// </summary>
Expand All @@ -208,67 +80,16 @@ public CompilationUnitSyntax Build()
@class = BuildAttributes(@class);
@class = @class.WithMembers(members);
var @base = SyntaxFactory.CompilationUnit();
@base = BuildUsing(@base);
@base = @base.AddMembers(SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(_namespace)).AddMembers(@class));
@base = BuildUsings(@base);
@base = BuildNamespace(@base, @class);
return @base;
}

private CompilationUnitSyntax BuildUsing(CompilationUnitSyntax @base)
{
var usingSyntaxes = default(SyntaxList<UsingDirectiveSyntax>);
foreach (var @using in _usings)
{
if (@using == null)
{
continue;
}

usingSyntaxes = usingSyntaxes.Add(SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(@using)));
}

foreach (var @using in usingSyntaxes)
{
@base = @base.AddUsings(@using);
}

return @base;
}

private ClassDeclarationSyntax BuildClassBase()
{
if (_inheritance.Any())
{
var syntaxNodeOrToken = new SyntaxNodeOrToken[(_inheritance.Count * 2) - 1];
for (int n = 0; n < (_inheritance.Count * 2) - 1; n += 2)
{
syntaxNodeOrToken[n] = SyntaxFactory.SimpleBaseType(TypeGenerator.Create(_inheritance[n]));
if (n + 1 < _inheritance.Count - 1)
{
syntaxNodeOrToken[n + 1] = SyntaxFactory.Token(SyntaxKind.CommaToken);
}
}

return SyntaxFactory.ClassDeclaration(_name).WithBaseList(SyntaxFactory.BaseList(SyntaxFactory.SeparatedList<BaseTypeSyntax>(syntaxNodeOrToken))).WithModifiers(ModifierGenerator.Create(_modifiers.ToArray()));
}

return SyntaxFactory.ClassDeclaration(_name).WithModifiers(ModifierGenerator.Create(_modifiers.ToArray()));
}

private ClassDeclarationSyntax BuildAttributes(ClassDeclarationSyntax @class)
{
return @class.WithAttributeLists(_attributes);
}

private SyntaxList<MemberDeclarationSyntax> BuildFields(SyntaxList<MemberDeclarationSyntax> members)
{
return AddMembers(members, _fields);
}

private SyntaxList<MemberDeclarationSyntax> BuildProperties(SyntaxList<MemberDeclarationSyntax> members)
{
return AddMembers(members, _properties);
}

private SyntaxList<MemberDeclarationSyntax> BuildConstructor(SyntaxList<MemberDeclarationSyntax> members)
{
if (_constructor == null)
Expand All @@ -279,24 +100,10 @@ private SyntaxList<MemberDeclarationSyntax> BuildConstructor(SyntaxList<MemberDe
return members.AddRange(SyntaxFactory.SingletonList<MemberDeclarationSyntax>(_constructor));
}

private SyntaxList<MemberDeclarationSyntax> BuildMethods(SyntaxList<MemberDeclarationSyntax> members)
{
return AddMembers(members, _methods);
}

private SyntaxList<MemberDeclarationSyntax> AddMembers(SyntaxList<MemberDeclarationSyntax> members, IEnumerable<MemberDeclarationSyntax> memberDeclarationSyntaxs)
private TypeDeclarationSyntax BuildClassBase()
{
if (!memberDeclarationSyntaxs.Any())
{
return members;
}

foreach (var memberDeclarationSyntax in memberDeclarationSyntaxs)
{
members = members.Add(memberDeclarationSyntax);
}

return members;
return SyntaxFactory.ClassDeclaration(Name).WithBaseList(CreateBaseList()).WithModifiers(CreateModifiers());
}
}
}
Loading

0 comments on commit a55df75

Please sign in to comment.