Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Global SkipRule or Generic BeforeRule preprocessor #178

Closed
anorborg opened this issue Sep 25, 2018 · 3 comments
Closed

Feature: Global SkipRule or Generic BeforeRule preprocessor #178

anorborg opened this issue Sep 25, 2018 · 3 comments

Comments

@anorborg
Copy link

anorborg commented Sep 25, 2018

This is really an amazing tool, but would appreciate some sugar-syntax in my use-case to be able to vary in some null/unset values.

What I do today

new Faker<Test>()
     .RuleFor(x => x.Value1, f => {
          // Randomly set this value with a probability of .1 (10% of the time)
          return (f.Random.Bool(0.1f)) ? f.Random.Int(1, 5) : null;
      })
     .RuleFor(x => x.Value2, f => {
          // Randomly set this value with a probability of .1 (10% of the time)
          return (f.Random.Bool(0.1f)) ? f.Internet.Ip(): null;
      })

Suggested Feature Syntax

new Faker<Test>()
     .SkipRule((f, x) => f.Random.Bool(0.1f))
     .RuleFor(x => x.Value1, f => f.Random.Int(1, 5))
     .RuleFor(x => x.Value2, f => f.Internet.Ip());

I'm not sure if there is a better/current way to accomplish something similar, but generating a dataset with the occasional null value is pretty useful for my in testing scenarios. Again, great tool!

@bchavez
Copy link
Owner

bchavez commented Sep 26, 2018

Hi @anorborg,

Thank you for the complements! I'm really glad you like Bogus! It always makes me happy to hear from people using Bogus. 😎

To answer your question:
Bogus has a nifty .OrNull() helper extension to generate null values randomly; however, the feature is nestled away in an extension namespace called Bogus.Extensions. Below is an example of how to use the .OrNull() extension to generate randomly null values:

using Bogus.Extensions;

void Main()
{
   var fakeTests = new Faker<Test>()
      .RuleFor( x => x.Value1, f => f.Random.Int(1, 5).OrNull(f) )
      .RuleFor( x => x.Value2, f => f.Internet.Ip().OrNull(f) );
      
   fakeTests.Generate(10).Dump();
}

public class Test
{
   public int? Value1 {get; set;}
   public string Value2 {get;set;}
}

linqpad_2187

Currently, .OrNull() doesn't support a weighted probability of generated nulls; but that can be easily fixed by copying the current implementation and making your own extension method like this:

void Main()
{
   var fakeTests = new Faker<Test>()
      .RuleFor( x => x.Value1, f => f.Random.Int(1, 5).OrNull(f, 0.9f) )
      .RuleFor( x => x.Value2, f => f.Internet.Ip().OrNull(f, 0.1f) );
      
   fakeTests.Generate(10).Dump();
}

public static class MyBogusExtensions
{
   public static object OrNull(this object value, Faker f, float nullWeight)
   {
      return f.Random.Float() < nullWeight ? null : value;
   }
}

linqpad_2188

The code above is quite clear, elegant, terse, and very readable IMHO. Perhaps, it might be a good idea to make this change official and allow the user to optionally specify the weight of nullability. 😺

Hope that helps!

Thanks,
Brian

//cc related #124

⏳ 🔍 "But I still haven't found what I'm for..."

bchavez added a commit that referenced this issue Sep 26, 2018
…hod for weighted generation of null values.
bchavez added a commit that referenced this issue Sep 26, 2018
… method for weighted generation of null values.
@anorborg
Copy link
Author

Thanks! A small suggestion: use default instead of null which works for null but value-types as well:

public static object OrDefault(this object value, Faker f, double defaultValueWeight = 0.5f)
{
    if (defaultValueWeight > 1 || defaultValueWeight < 0) throw new ArgumentOutOfRangeException(nameof(defaultValueWeight), $".{nameof(OrDefault)}() {nameof(defaultValueWeight)} of '{defaultValueWeight}' must be between 1.0f and 0.0f. ");
        return f.Random.Float() > defaultValueWeight ? value : default;
   }
}

Although you can define zero in your range in most, if not all cases, since you've added the weight, its a nice option to only select that value with the same probability as null.

@bchavez
Copy link
Owner

bchavez commented Sep 26, 2018

Hi @anorborg,

That's a great idea! Thank you for the suggestion! I've released Bogus v24.1.0 with the latest suggestion and changes!

Hope that helps!

Thanks,
Brian

🚶 😎 "So don't delay... act now supplies are running out..."

@bchavez bchavez closed this as completed Sep 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants