Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/AutoBogus.Tests/AutoConfigBuilderFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ public void Should_Set_Config_TreeDepth_To_Default_If_Null()
}
}

public class WithOnlySimpleTypes
: AutoConfigBuilderFixture
{
[Fact]
public void Should_Set_Config_OnlySimpleTypes()
{
var onlySimpleTypes = _faker.Random.Bool();

_builder.WithOnlySimpleTypes<ITestBuilder>(context => onlySimpleTypes, null);

_config.OnlySimpleTypes.Invoke(null).Should().Be(onlySimpleTypes);
}

[Fact]
public void Should_Set_Config_OnlySimpleTypes_To_Default_If_Null()
{
var onlySimpleTypes = AutoConfig.DefaultOnlySimpleTypes.Invoke(null);

_builder.WithOnlySimpleTypes<ITestBuilder>(null, null);

_config.OnlySimpleTypes.Invoke(null).Should().Be(onlySimpleTypes);
}
}

public class WithBinder
: AutoConfigBuilderFixture
{
Expand Down
23 changes: 23 additions & 0 deletions src/AutoBogus.Tests/AutoFakerFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,29 @@ public void Should_Skip_Configured_Members()
}
}

public class Behaviors_OnlySimpleTypes
: AutoFakerFixture
{
[Fact]
public void Should_Populate_Only_Simple_Types()
{
var instance = AutoFaker.Generate<Order>(builder =>
{
builder
.WithOnlySimpleTypes(true);
});

instance.Id.Should().NotBe(default);
instance.Code.Should().NotBeEmpty();
instance.DateCreated.Should().NotBe(default);

instance.Calculator.Should().BeNull();
instance.Discounts.Should().BeNull();
instance.Items.Should().BeNull();
instance.Comments.Should().BeNull();
}
}

public class Behaviors_Types
: AutoFakerFixture
{
Expand Down
14 changes: 9 additions & 5 deletions src/AutoBogus/AutoBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public virtual void PopulateInstance<TType>(object instance, AutoGenerateContext
}

// Iterate the members and bind a generated value
var autoMembers = GetMembersToPopulate(type, members);
var autoMembers = GetMembersToPopulate(type, members, context);

foreach (var member in autoMembers)
{
Expand Down Expand Up @@ -187,17 +187,21 @@ private IAutoGenerator GetParameterGenerator(Type type, ParameterInfo parameter,
return AutoGeneratorFactory.GetGenerator(context);
}

private IEnumerable<AutoMember> GetMembersToPopulate(Type type, IEnumerable<MemberInfo> members)
private IEnumerable<AutoMember> GetMembersToPopulate(Type type, IEnumerable<MemberInfo> members, AutoGenerateContext context)
{
var onlySimpleTypes = context.Config.OnlySimpleTypes.Invoke(context);

// If a list of members is provided, no others should be populated
if (members != null)
{
return members.Select(member => new AutoMember(member));
return members.Where(m => !onlySimpleTypes || (m is PropertyInfo info && ReflectionHelper.IsSimple(info.PropertyType)))
.Select(member => new AutoMember(member));
}

// Get the baseline members resolved by Bogus
var autoMembers = (from m in GetMembers(type)
select new AutoMember(m.Value)).ToList();
var autoMembers = GetMembers(type)
.Where(m => !onlySimpleTypes || (m.Value is PropertyInfo info && ReflectionHelper.IsSimple(info.PropertyType)))
.Select(m => new AutoMember(m.Value)).ToList();

foreach (var member in type.GetMembers(BindingFlags))
{
Expand Down
4 changes: 4 additions & 0 deletions src/AutoBogus/AutoConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal sealed class AutoConfig
internal static readonly Func<AutoGenerateContext, int> DefaultDataTableRowCount = context => 15;
internal static readonly Func<AutoGenerateContext, int> DefaultRecursiveDepth = context => 2;
internal static readonly Func<AutoGenerateContext, int?> DefaultTreeDepth = context => null;
internal static readonly Func<AutoGenerateContext, bool> DefaultOnlySimpleTypes = context => false;

internal AutoConfig()
{
Expand All @@ -22,6 +23,7 @@ internal AutoConfig()
DataTableRowCount = DefaultDataTableRowCount;
RecursiveDepth = DefaultRecursiveDepth;
TreeDepth = DefaultTreeDepth;
OnlySimpleTypes = DefaultOnlySimpleTypes;
Binder = new AutoBinder();
SkipTypes = new List<Type>();
SkipPaths = new List<string>();
Expand All @@ -34,6 +36,7 @@ internal AutoConfig(AutoConfig config)
RepeatCount = config.RepeatCount;
DataTableRowCount = config.DataTableRowCount;
RecursiveDepth = config.RecursiveDepth;
OnlySimpleTypes = config.OnlySimpleTypes;
TreeDepth = config.TreeDepth;
Binder = config.Binder;
FakerHub = config.FakerHub;
Expand All @@ -46,6 +49,7 @@ internal AutoConfig(AutoConfig config)
internal Func<AutoGenerateContext, int> RepeatCount { get; set; }
internal Func<AutoGenerateContext, int> DataTableRowCount { get; set; }
internal Func<AutoGenerateContext, int> RecursiveDepth { get; set; }
internal Func<AutoGenerateContext, bool> OnlySimpleTypes { get; set; }
internal IAutoBinder Binder { get; set; }
internal Faker FakerHub { get; set; }
internal IList<Type> SkipTypes { get; set; }
Expand Down
12 changes: 12 additions & 0 deletions src/AutoBogus/AutoConfigBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ internal AutoConfigBuilder(AutoConfig config)
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithRecursiveDepth(Func<AutoGenerateContext, int> depth) => WithRecursiveDepth<IAutoFakerDefaultConfigBuilder>(depth, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithTreeDepth(int? depth) => WithTreeDepth<IAutoFakerDefaultConfigBuilder>(context => depth, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithTreeDepth(Func<AutoGenerateContext, int?> depth) => WithTreeDepth<IAutoFakerDefaultConfigBuilder>(depth, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithOnlySimpleTypes(bool onlySimpleTypes) => WithOnlySimpleTypes<IAutoFakerDefaultConfigBuilder>(context => onlySimpleTypes, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithOnlySimpleTypes(Func<AutoGenerateContext, bool> onlySimpleTypes) => WithOnlySimpleTypes<IAutoFakerDefaultConfigBuilder>(onlySimpleTypes, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithBinder(IAutoBinder binder) => WithBinder<IAutoFakerDefaultConfigBuilder>(binder, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithFakerHub(Faker fakerHub) => WithFakerHub<IAutoFakerDefaultConfigBuilder>(fakerHub, this);
IAutoFakerDefaultConfigBuilder IAutoConfigBuilder<IAutoFakerDefaultConfigBuilder>.WithSkip(Type type) => WithSkip<IAutoFakerDefaultConfigBuilder>(type, this);
Expand All @@ -41,6 +43,8 @@ internal AutoConfigBuilder(AutoConfig config)
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithRecursiveDepth(Func<AutoGenerateContext, int> depth) => WithRecursiveDepth<IAutoGenerateConfigBuilder>(depth, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithTreeDepth(int? depth) => WithTreeDepth<IAutoGenerateConfigBuilder>(context => depth, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithTreeDepth(Func<AutoGenerateContext, int?> depth) => WithTreeDepth<IAutoGenerateConfigBuilder>(depth, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithOnlySimpleTypes(bool onlySimpleTypes) => WithOnlySimpleTypes<IAutoGenerateConfigBuilder>(context => onlySimpleTypes, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithOnlySimpleTypes(Func<AutoGenerateContext, bool> onlySimpleTypes) => WithOnlySimpleTypes<IAutoGenerateConfigBuilder>(onlySimpleTypes, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithBinder(IAutoBinder binder) => WithBinder<IAutoGenerateConfigBuilder>(binder, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithFakerHub(Faker fakerHub) => WithFakerHub<IAutoGenerateConfigBuilder>(fakerHub, this);
IAutoGenerateConfigBuilder IAutoConfigBuilder<IAutoGenerateConfigBuilder>.WithSkip(Type type) => WithSkip<IAutoGenerateConfigBuilder>(type, this);
Expand All @@ -57,6 +61,8 @@ internal AutoConfigBuilder(AutoConfig config)
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithRecursiveDepth(Func<AutoGenerateContext, int> depth) => WithRecursiveDepth<IAutoFakerConfigBuilder>(depth, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithTreeDepth(int? depth) => WithTreeDepth<IAutoFakerConfigBuilder>(context => depth, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithTreeDepth(Func<AutoGenerateContext, int?> depth) => WithTreeDepth<IAutoFakerConfigBuilder>(depth, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithOnlySimpleTypes(bool onlySimpleTypes) => WithOnlySimpleTypes<IAutoFakerConfigBuilder>(context => onlySimpleTypes, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithOnlySimpleTypes(Func<AutoGenerateContext, bool> onlySimpleTypes) => WithOnlySimpleTypes<IAutoFakerConfigBuilder>(onlySimpleTypes, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithBinder(IAutoBinder binder) => WithBinder<IAutoFakerConfigBuilder>(binder, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithFakerHub(Faker fakerHub) => WithFakerHub<IAutoFakerConfigBuilder>(fakerHub, this);
IAutoFakerConfigBuilder IAutoConfigBuilder<IAutoFakerConfigBuilder>.WithSkip(Type type) => WithSkip<IAutoFakerConfigBuilder>(type, this);
Expand Down Expand Up @@ -95,6 +101,12 @@ internal TBuilder WithTreeDepth<TBuilder>(Func<AutoGenerateContext, int?> depth,
return builder;
}

internal TBuilder WithOnlySimpleTypes<TBuilder>(Func<AutoGenerateContext, bool> onlySimpleTypes, TBuilder builder)
{
Config.OnlySimpleTypes = onlySimpleTypes ?? AutoConfig.DefaultOnlySimpleTypes;
return builder;
}

internal TBuilder WithBinder<TBuilder>(IAutoBinder binder, TBuilder builder)
{
Config.Binder = binder ?? new AutoBinder();
Expand Down
12 changes: 12 additions & 0 deletions src/AutoBogus/IAutoConfigBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ public interface IAutoConfigBuilder<TBuilder>
/// <returns>The current configuration builder instance.</returns>
TBuilder WithTreeDepth(Func<AutoGenerateContext, int?> depth);

/// <summary>
/// Registers if only simple type members should be populated with values
/// </summary>
/// <returns>The current configuration builder instance.</returns>
TBuilder WithOnlySimpleTypes(bool onlySimpleTypes);

/// <summary>
/// Registers if only simple type members should be populated with values
/// </summary>
/// <returns>The current configuration builder instance.</returns>
TBuilder WithOnlySimpleTypes(Func<AutoGenerateContext, bool> onlySimpleTypes);

/// <summary>
/// Registers a binder instance to use when generating values.
/// </summary>
Expand Down
31 changes: 31 additions & 0 deletions src/AutoBogus/Util/ReflectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,37 @@ internal static bool IsProperty(MemberInfo member)
#endif
}

/// <summary>
/// Return true if the type is a primitive type, date, decimal, string, or GUID
/// </summary>
/// <param name="type">Type for which to check if it is a simple type</param>
internal static bool IsSimple(Type type)
{
if (type == null)
return false;

var typeInfo = type.GetTypeInfo();
if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
#if NETSTANDARD1_3
var genericArgs = type.GetTypeInfo().IsGenericTypeDefinition
? type.GetTypeInfo().GenericTypeParameters
: type.GetTypeInfo().GenericTypeArguments;
return IsSimple(genericArgs[0]);
#else
return IsSimple(typeInfo.GetGenericArguments()[0]);
#endif
}
return typeInfo.IsPrimitive
|| typeInfo.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal))
|| type.Equals(typeof(Guid))
|| type.Equals(typeof(DateTime))
|| type.Equals(typeof(DateTimeOffset));
}

internal static IEnumerable<Type> GetGenericArguments(Type type)
{
return type.GetGenericArguments();
Expand Down