Skip to content

Commit

Permalink
Feature/118 cache build capability (#126)
Browse files Browse the repository at this point in the history
* Removed AutoDetectConstructor as it is redundant now that TypeCreator types manage constructor resolution and parameter generation
* Updated BuildHistory to store a cache of build capabilities
* Updated DefaultExecuteStrategy to manage cached build capabilities
  • Loading branch information
roryprimrose authored Jun 15, 2020
1 parent 8558c67 commit 84da591
Show file tree
Hide file tree
Showing 25 changed files with 369 additions and 229 deletions.
34 changes: 0 additions & 34 deletions ModelBuilder.UnitTests/BuildActions/BuildCapabilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,6 @@

public class BuildCapabilityTests
{
[Fact]
public void AutoDetectConstructorReturnsFalseForCreationRule()
{
var creationRule = new DummyCreationRule();

var sut = new BuildCapability(creationRule);

sut.AutoDetectConstructor.Should().BeFalse();
}

[Fact]
public void AutoDetectConstructorReturnsFalseForValueGenerator()
{
var generator = Substitute.For<IValueGenerator>();

var sut = new BuildCapability(generator);

sut.AutoDetectConstructor.Should().BeFalse();
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void AutoDetectConstructorReturnsTypeCreatorValue(bool autoDetectConstructor)
{
var typeCreator = Substitute.For<ITypeCreator>();

typeCreator.AutoDetectConstructor.Returns(autoDetectConstructor);

var sut = new BuildCapability(typeCreator, false, autoDetectConstructor);

sut.AutoDetectConstructor.Should().Be(autoDetectConstructor);
}

[Fact]
public void AutoPopulateReturnsFalseForCreationRule()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Reflection;
using FluentAssertions;
using ModelBuilder.BuildActions;
using ModelBuilder.CreationRules;
using ModelBuilder.UnitTests.Models;
using NSubstitute;
using Xunit;
Expand Down Expand Up @@ -232,7 +231,6 @@ public void GetBuildCapabilityForParameterReturnsCapabilityWhenBuildChainContain
actual.Should().NotBeNull();
actual.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().BeAssignableTo<IBuildCapability>();
}
Expand Down Expand Up @@ -314,7 +312,6 @@ public void GetBuildCapabilityForPropertyReturnsCapabilityWhenBuildChainContains
actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().BeAssignableTo<IBuildCapability>();
}
Expand Down Expand Up @@ -393,7 +390,6 @@ public void GetBuildCapabilityForTypeReturnsCapabilityWhenBuildChainContainsMatc
actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().BeAssignableTo<IBuildCapability>();
}
Expand Down
97 changes: 47 additions & 50 deletions ModelBuilder.UnitTests/BuildActions/CreationRuleBuildActionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -480,12 +480,13 @@ public void BuildThrowsExceptionWhenRuleFails()
}

[Fact]
public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoMatchingRuleFound()
public void GetBuildCapabilityForParameterInfoReturnsCapabilityWhenMatchingRuleFound()
{
var parameterInfo = typeof(Person).GetConstructors()
.First(x => x.GetParameters().FirstOrDefault()?.Name == "firstName").GetParameters().First();
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();
Expand All @@ -494,23 +495,32 @@ public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoMatchingRuleFound

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(parameterInfo).Returns(true);
rule.Create(executeStrategy, parameterInfo).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, parameterInfo);
var actual = sut.GetBuildCapability(buildConfiguration, buildChain, parameterInfo)!;

actual.Should().BeNull();
actual.Should().NotBeNull();
actual.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
}

[Fact]
public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoRulesExist()
public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoMatchingRuleFound()
{
var parameterInfo = typeof(Person).GetConstructors()
.First(x => x.GetParameters().FirstOrDefault()?.Name == "firstName").GetParameters().First();
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
Expand All @@ -523,34 +533,23 @@ public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoRulesExist()
}

[Fact]
public void GetBuildCapabilityForParameterInfoReturnsCapabilityWhenMatchingRuleFound()
public void GetBuildCapabilityForParameterInfoReturnsNullWhenNoRulesExist()
{
var parameterInfo = typeof(Person).GetConstructors()
.First(x => x.GetParameters().FirstOrDefault()?.Name == "firstName").GetParameters().First();
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(parameterInfo).Returns(true);
rule.Create(executeStrategy, parameterInfo).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, parameterInfo)!;
var actual = sut.GetBuildCapability(buildConfiguration, buildChain, parameterInfo);

actual.Should().NotBeNull();
actual.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
actual.Should().BeNull();
}

[Fact]
Expand Down Expand Up @@ -595,11 +594,12 @@ public void GetBuildCapabilityForParameterInfoThrowsExceptionWithNullParameterIn
}

[Fact]
public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoMatchingRuleFound()
public void GetBuildCapabilityForPropertyInfoReturnsCapabilityWhenMatchingRuleFound()
{
var propertyInfo = typeof(Person).GetProperty(nameof(Person.FirstName))!;
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();
Expand All @@ -608,22 +608,31 @@ public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoMatchingRuleFound(

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(propertyInfo).Returns(true);
rule.Create(executeStrategy, propertyInfo).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, propertyInfo);

actual.Should().BeNull();
actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
}

[Fact]
public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoRulesExist()
public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoMatchingRuleFound()
{
var propertyInfo = typeof(Person).GetProperty(nameof(Person.FirstName))!;
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
Expand All @@ -636,33 +645,22 @@ public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoRulesExist()
}

[Fact]
public void GetBuildCapabilityForPropertyInfoReturnsCapabilityWhenMatchingRuleFound()
public void GetBuildCapabilityForPropertyInfoReturnsNullWhenNoRulesExist()
{
var propertyInfo = typeof(Person).GetProperty(nameof(Person.FirstName))!;
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(propertyInfo).Returns(true);
rule.Create(executeStrategy, propertyInfo).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, propertyInfo);

actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
actual.Should().BeNull();
}

[Fact]
Expand Down Expand Up @@ -705,11 +703,12 @@ public void GetBuildCapabilityForPropertyInfoThrowsExceptionWithNullPropertyInfo
}

[Fact]
public void GetBuildCapabilityForTypeReturnsNullWhenNoMatchingRuleFound()
public void GetBuildCapabilityForTypeReturnsCapabilityWhenMatchingRuleFound()
{
var type = typeof(Person);
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();
Expand All @@ -718,22 +717,31 @@ public void GetBuildCapabilityForTypeReturnsNullWhenNoMatchingRuleFound()

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(type).Returns(true);
rule.Create(executeStrategy, type).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, type);

actual.Should().BeNull();
actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
}

[Fact]
public void GetBuildCapabilityForTypeReturnsNullWhenNoRulesExist()
public void GetBuildCapabilityForTypeReturnsNullWhenNoMatchingRuleFound()
{
var type = typeof(Person);
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
Expand All @@ -746,33 +754,22 @@ public void GetBuildCapabilityForTypeReturnsNullWhenNoRulesExist()
}

[Fact]
public void GetBuildCapabilityForTypeReturnsCapabilityWhenMatchingRuleFound()
public void GetBuildCapabilityForTypeReturnsNullWhenNoRulesExist()
{
var type = typeof(Person);
var buildConfiguration = new BuildConfiguration();
var buildChain = new BuildHistory();
var expected = new Person();

var executeStrategy = Substitute.For<IExecuteStrategy>();
var rule = Substitute.For<ICreationRule>();

buildConfiguration.CreationRules.Add(rule);

executeStrategy.Configuration.Returns(buildConfiguration);
executeStrategy.Log.Returns(_buildLog);
rule.IsMatch(type).Returns(true);
rule.Create(executeStrategy, type).Returns(expected);

var sut = new CreationRuleBuildAction();

var actual = sut.GetBuildCapability(buildConfiguration, buildChain, type);

actual.Should().NotBeNull();
actual!.SupportsCreate.Should().BeTrue();
actual.SupportsPopulate.Should().BeFalse();
actual.AutoDetectConstructor.Should().BeFalse();
actual.AutoPopulate.Should().BeFalse();
actual.ImplementedByType.Should().Be(rule.GetType());
actual.Should().BeNull();
}

[Fact]
Expand Down
Loading

0 comments on commit 84da591

Please sign in to comment.