Skip to content

Commit

Permalink
Added MiddleNameValueGenerator (#99)
Browse files Browse the repository at this point in the history
* Added MiddleNameValueGenerator
* Updated documentation
  • Loading branch information
roryprimrose committed May 11, 2020
1 parent f903cb4 commit f785683
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 87 deletions.
11 changes: 11 additions & 0 deletions ModelBuilder.UnitTests/Models/Names.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ModelBuilder.UnitTests.Models
{
public class Names
{
public string FirstName { get; set; }

public Gender Gender { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
}
}
10 changes: 10 additions & 0 deletions ModelBuilder.UnitTests/Models/NamesWithoutGender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ModelBuilder.UnitTests.Models
{
public class NamesWithoutGender
{
public string FirstName { get; set; }

public string LastName { get; set; }
public string MiddleName { get; set; }
}
}
27 changes: 27 additions & 0 deletions ModelBuilder.UnitTests/NameExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,33 @@ public void PostCodeEvaluatesValueTest(string value, bool expected)
actual.Should().Be(expected);
}

[Theory]
[InlineData("stuff", false)]
[InlineData("secondname", true)]
[InlineData("Secondname", true)]
[InlineData("SecondName", true)]
[InlineData("secondName", true)]
[InlineData("second_name", true)]
[InlineData("Second_name", true)]
[InlineData("Second_Name", true)]
[InlineData("second_Name", true)]
[InlineData("middlename", true)]
[InlineData("Middlename", true)]
[InlineData("MiddleName", true)]
[InlineData("middleName", true)]
[InlineData("middle_name", true)]
[InlineData("Middle_name", true)]
[InlineData("Middle_Name", true)]
[InlineData("middle_Name", true)]
public void SecondNameEvaluatesValueTest(string value, bool expected)
{
var sut = NameExpression.MiddleName;

var actual = sut.IsMatch(value);

actual.Should().Be(expected);
}

[Theory]
[InlineData("stuff", false)]
[InlineData("state", true)]
Expand Down
10 changes: 10 additions & 0 deletions ModelBuilder.UnitTests/Scenarios/ScenarioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ public void CanCreateInstanceWithParameters()
actual.Value.Should().NotBeEmpty();
}

[Fact]
public void CanCreateWithMultipleNames()
{
var actual = Model.Create<Names>();

actual.FirstName.Should().NotBeNullOrWhiteSpace();
actual.MiddleName.Should().NotBeNullOrWhiteSpace();
actual.LastName.Should().NotBeNullOrWhiteSpace();
}

[Fact]
public void CanGenerateUriData()
{
Expand Down
39 changes: 7 additions & 32 deletions ModelBuilder.UnitTests/ValueGenerators/CountValueGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,46 +161,21 @@ public void IsMatchReturnsTrueWhenReferenceNameIsCountTest(Type type, bool isSup
}

[Fact]
public void PriorityReturnsGreaterThanNumericValueGenerator()
public void MaxCountReturnsDefaultValue()
{
var sut = new Wrapper();

var generator = new NumericValueGenerator();
var sut = new CountValueGenerator();

sut.Priority.Should().BeGreaterThan(generator.Priority);
sut.MaxCount.Should().Be(30);
}

[Fact]
public void SettingDefaultMaxCountOnlyAffectsNewInstances()
public void PriorityReturnsGreaterThanNumericValueGenerator()
{
var expected = CountValueGenerator.DefaultMaxCount;

try
{
var first = new CountValueGenerator();

CountValueGenerator.DefaultMaxCount = 11;

var second = new CountValueGenerator();

first.MaxCount.Should().Be(expected);
second.MaxCount.Should().Be(11);
}
finally
{
CountValueGenerator.DefaultMaxCount = expected;
}
}
var sut = new Wrapper();

[Fact]
public void SettingMaxCountShouldNotChangeDefaultMaxCount()
{
var sut = new CountValueGenerator
{
MaxCount = Environment.TickCount
};
var generator = new NumericValueGenerator();

CountValueGenerator.DefaultMaxCount.Should().NotBe(sut.MaxCount);
sut.Priority.Should().BeGreaterThan(generator.Priority);
}

private class Wrapper : CountValueGenerator
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
namespace ModelBuilder.UnitTests.ValueGenerators
{
using System;
using System.IO;
using System.Linq;
using FluentAssertions;
using ModelBuilder.Data;
using ModelBuilder.UnitTests.Models;
using ModelBuilder.ValueGenerators;
using NSubstitute;
using Xunit;

public class MiddleNameValueGeneratorTests
{
[Fact]
public void GeneratorReturnsFemaleNameWhenGenderIsFemale()
{
var person = new Names
{
Gender = Gender.Female
};
var buildChain = new BuildHistory();
var executeStrategy = Substitute.For<IExecuteStrategy>();

executeStrategy.BuildChain.Returns(buildChain);

buildChain.Push(person);

var sut = new Wrapper();

var actual = (string) sut.RunGenerate(typeof(string), "MiddleName", executeStrategy);

TestData.FemaleNames.Any(x => x == actual).Should().BeTrue();
}

[Fact]
public void GeneratorReturnsFemaleNameWhenGenderIsUnknown()
{
var person = new Names
{
Gender = Gender.Unknown
};
var buildChain = new BuildHistory();
var executeStrategy = Substitute.For<IExecuteStrategy>();

executeStrategy.BuildChain.Returns(buildChain);

buildChain.Push(person);

var sut = new Wrapper();

var actual = (string) sut.RunGenerate(typeof(string), "MiddleName", executeStrategy);

TestData.FemaleNames.Any(x => x == actual).Should().BeTrue();
}

[Fact]
public void GeneratorReturnsMaleNameWhenGenderIsMale()
{
var person = new Names
{
Gender = Gender.Male
};
var buildChain = new BuildHistory();
var executeStrategy = Substitute.For<IExecuteStrategy>();

executeStrategy.BuildChain.Returns(buildChain);

buildChain.Push(person);

var sut = new Wrapper();

var actual = (string) sut.RunGenerate(typeof(string), "MiddleName", executeStrategy);

TestData.MaleNames.Any(x => x == actual).Should().BeTrue();
}

[Fact]
public void GeneratorReturnsNameWhenTypeLacksGender()
{
var person = new NamesWithoutGender();
var buildChain = new BuildHistory();
var executeStrategy = Substitute.For<IExecuteStrategy>();

executeStrategy.BuildChain.Returns(buildChain);

buildChain.Push(person);

var sut = new Wrapper();

var actual = (string) sut.RunGenerate(typeof(string), "MiddleName", executeStrategy);

if (TestData.MaleNames.Any(x => x == actual))
{
// This is a match on a male name so all good
}
else
{
// Not a male name so it must be a female name
TestData.FemaleNames.Any(x => x == actual).Should().BeTrue();
}
}

[Theory]
[InlineData(typeof(Stream), "middlename", false)]
[InlineData(typeof(string), null, false)]
[InlineData(typeof(string), "", false)]
[InlineData(typeof(string), "Stuff", false)]
[InlineData(typeof(string), "MiddleName", true)]
[InlineData(typeof(string), "middlename", true)]
[InlineData(typeof(string), "SECONDNAME", true)]
[InlineData(typeof(string), "Middle_Name", true)]
[InlineData(typeof(string), "middle_name", true)]
[InlineData(typeof(string), "SECOND_NAME", true)]
[InlineData(typeof(string), "SecondName", true)]
[InlineData(typeof(string), "secondname", true)]
[InlineData(typeof(string), "MIDDLENAME", true)]
[InlineData(typeof(string), "Second_Name", true)]
[InlineData(typeof(string), "second_name", true)]
[InlineData(typeof(string), "MIDDLE_NAME", true)]
public void IsMatchReturnsWhetherTypeAndNameAreSupportedTest(Type type, string referenceName, bool expected)
{
var person = new Names();
var buildChain = new BuildHistory();

buildChain.Push(person);

var sut = new Wrapper();

var actual = sut.RunIsMatch(type, referenceName, buildChain);

actual.Should().Be(expected);
}

[Fact]
public void PriorityReturnsHigherPriorityThanStringValidator()
{
var sut = new Wrapper();
var other = new StringValueGenerator();

sut.Priority.Should().BeGreaterThan(other.Priority);
}

private class Wrapper : MiddleNameValueGenerator
{
public object RunGenerate(Type type, string referenceName, IExecuteStrategy executeStrategy)
{
return Generate(executeStrategy, type, referenceName);
}

public bool RunIsMatch(Type type, string referenceName, IBuildChain buildChain)
{
return IsMatch(buildChain, type, referenceName);
}
}
}
}
2 changes: 2 additions & 0 deletions ModelBuilder/DefaultConfigurationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ private static void AddExecuteOrderRules(IBuildConfiguration configuration)
// Populate personal properties in a specific order for scenarios where a value generator may use the values in order to set other values
configuration.AddExecuteOrderRule(NameExpression.Gender, 9600);
configuration.AddExecuteOrderRule(NameExpression.FirstName, 9580);
configuration.AddExecuteOrderRule(NameExpression.MiddleName, 9570);
configuration.AddExecuteOrderRule(NameExpression.LastName, 9560);
configuration.AddExecuteOrderRule(NameExpression.Domain, 9550);
configuration.AddExecuteOrderRule(NameExpression.Email, 9540);
Expand Down Expand Up @@ -79,6 +80,7 @@ private static void AddValueGenerators(IBuildConfiguration configuration)
configuration.AddValueGenerator<GuidValueGenerator>();
configuration.AddValueGenerator<IPAddressValueGenerator>();
configuration.AddValueGenerator<LastNameValueGenerator>();
configuration.AddValueGenerator<MiddleNameValueGenerator>();
configuration.AddValueGenerator<NumericValueGenerator>();
configuration.AddValueGenerator<PhoneValueGenerator>();
configuration.AddValueGenerator<PostCodeValueGenerator>();
Expand Down
5 changes: 5 additions & 0 deletions ModelBuilder/NameExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public static class NameExpression
/// </summary>
public static readonly Regex LastName = new Regex("Surname|(Last[_]?Name)", RegexOptions.IgnoreCase);

/// <summary>
/// Defines the expression for matching middle name properties.
/// </summary>
public static readonly Regex MiddleName = new Regex("(Middle|Second)[_]?Name", RegexOptions.IgnoreCase);

/// <summary>
/// Defines the expression for matching postcode properties.
/// </summary>
Expand Down
7 changes: 1 addition & 6 deletions ModelBuilder/ValueGenerators/CountValueGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,10 @@ protected override object GetMinimum(Type type, string referenceName, object con
return 1;
}

/// <summary>
/// Gets or sets the default maximum count that can be generated.
/// </summary>
public static int DefaultMaxCount { get; set; } = 30;

/// <summary>
/// Gets or sets the maximum count generated by this instance.
/// </summary>
public int MaxCount { get; set; } = DefaultMaxCount;
public int MaxCount { get; set; } = 30;

/// <inheritdoc />
public override int Priority { get; } = 1000;
Expand Down
35 changes: 35 additions & 0 deletions ModelBuilder/ValueGenerators/MIddleNameValueGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace ModelBuilder.ValueGenerators
{
using System;
using ModelBuilder.Data;

/// <summary>
/// The <see cref="MiddleNameValueGenerator" />
/// class is used to generate random middle name values.
/// </summary>
public class MiddleNameValueGenerator : RelativeValueGenerator
{
/// <summary>
/// Initializes a new instance of the <see cref="MiddleNameValueGenerator" />.
/// </summary>
public MiddleNameValueGenerator() : base(NameExpression.MiddleName, typeof(string))
{
}

/// <inheritdoc />
protected override object Generate(IExecuteStrategy executeStrategy, Type type, string referenceName)
{
if (IsMale(executeStrategy))
{
// Use a male first name
return TestData.MaleNames.Next();
}

// Use a female name
return TestData.FemaleNames.Next();
}

/// <inheritdoc />
public override int Priority { get; } = 1000;
}
}
2 changes: 1 addition & 1 deletion ModelBuilder/ValueGenerators/NumericValueGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected override object Generate(IExecuteStrategy executeStrategy, Type type,
generateType = type.GetGenericArguments()[0];
}

var context = executeStrategy?.BuildChain?.Last;
var context = executeStrategy.BuildChain?.Last;
var min = GetMinimum(generateType, referenceName, context);
var max = GetMaximum(generateType, referenceName, context);

Expand Down

0 comments on commit f785683

Please sign in to comment.