bchavez / Bogus

:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.
Other
8.77k stars 498 forks source link

Merge with AutoBogus #74

Closed bchavez closed 5 years ago

bchavez commented 7 years ago

Lays the foundation for ultimately getting #8 done.

:car: :blue_car: "Let the good times roll..."

nickdodd79 commented 7 years ago

G'day Bogus Fans,

So the foundations are currently being put down to address the auto-magic population of Faker<T> types (see #8). We are at the stage now where we are piecing together a public API to invoke an auto generate and are calling on the community to help shape how this will be useful to you.

Under the hood we are planning on using a 'conventions' concept that will drive the population pipeline and allow for things like mocking of interfaces using your preferred framework (Moq, FakeItEasy, etc.).

So, how do you see this working for you? Options considered so far are:

  1. A separate AutoFaker<T> class, but does this mean 2 models need to be maintained (one for Faker<T> and one for AutoFaker<T>)?

  2. An extension method on Faker<T>, but with the conventions concept seems to put a double responsibility on the method to both configure and generate.

  3. Leverage the design of AutoFixture and have an AutoGenerator class which allows conventions to be registered on a global basis (e.g. the setup process of a unit test). Then expose a Generate() method that can create instances based on a Faker<T> definition or just a generic type (Generate<T>()). The latter would cater for scenarios like Generate<int>() where Faker<T> definitions are not possible. Are we doubling up on the non-generic Faker role though?

That has been our consideration journey so far, each with their own pros/cons. What does the community prefer? Is there another approach that would work well?

Add your comments and help shape the awesome :-)

Nick.

bchavez commented 7 years ago

Hi @nickdodd79,

Replying to your previous post here:

As an example, if I have Faker<Person> and want to generate 2 instances for my unit test I would call Faker<T>.Generate() twice. However, I then want the first to set the manager to be null, but keep the second to have an auto generated manager, so I apply .RuleFor(p => p.Manager, f => null) before calling Generate() on the first. If we use a method of applying these rules through conventions and mutate Faker<T> then the second instance would also have a manager of null. Having said that, a workaround for this is to use the ruleset string parameter of Generate(). Is that an approach a developer would use for this scenario?

You hit the nail on the head, the workaround in today's Bogus release is to use a "RuleSet" as a way to specify additional rules for specific scenarios. I shamelessly copied the concept from FluentValidation's RuleSet.

Using your scenario as a thread for to revive an older idea, I'm starting to think the concept "Cloning" a Faker<T> is something developers are expecting to be part of Bogus API and feature set. Conceptually, I'm seeing "Cloning" as a more pragmatic approach to some scenarios over RuleSets. The issue of "Cloning" came up about a year ago in Issue #28. I thought back then "RuleSets" would solve the issue and "softly" guide developers to write rules in single place. I'm starting to think "Cloning" still can serve as a valuable alternative.

So, a major question for you @nickdodd79: Suppose we had a Faker<T>.Clone() method that completely deep-cloned a Faker<T>.... would that: 1) resolve your specific use-case more elegantly? and 2) make the API implementation of "Conventions" easier?

Conceptually, "Conventions" would still mutate the underlying Faker<T> as we described before with .RuleFors. With Faker<T>'s new ability to "clone" itself, "Convention" mutations would still mutate on Faker<T> except this time, you'd be in specific control of "when" cloning is appropriate (as with your case, loading DB data vs unit tests). And you'd be able to apply various "Conventions" to cloned Faker<T> without having to worry about modifying the original Faker<T>.

Let me know what you think :+1:

Brian

:walking_man: :walking_woman: Missing Persons - Walking in L.A.

generik0 commented 6 years ago

Hi Any update with this? with this feature Bogus can fully replace nbuilder + faker.net combi. I.e. you can make simple type fakes, and randomize properties in an object.

Can't wait.. :-)

dotnetchris commented 5 years ago

Similar bump, status questionmark

bchavez commented 5 years ago

Hi Chris,

Nothing to report at the moment.

Current suggestion is to use AutoBogus separately. AFAIK, AutoBogus still works wonderfully and gets the job done.

Automatic rule generation at runtime is difficult problem to get right for all use cases. We're lucky to have AutoBogus.

But before we add any new features to Bogus, I personally prefer to get it right (more or less) the first time than to trigger a maintenance/support crisis for thousands of users.

MovGP0 commented 5 years ago

I am totally fine with AutoBogus beeing a separate project. When referencing the NuGet, I only reference AutoBogus and get Bogus as a dependency for free. So there should be some technical reason for a merge (ie. easier versioning).

bchavez commented 5 years ago

Hey there everyone!

I'm going to close this issue for now. I think Nick is doing an awesome job of developing and maintaining AutoBogus. He just reached 100K downloads on NuGet!

There doesn't seem to be any issues keeping the projects separate. Right now each library can iterate and bugfix independently. If there's ever an issue regarding incompatibility, we should still be able to work things out.

Someday, if we decide its easier to develop inside the Bogus repository for access to internal types or under the Bogus.Xyz NuGet namespace, merging projects will always be an option!

304NotModified commented 1 year ago

Unfortunately it seems that the development of AutoBogus is stalled. Maybe re-consider this?

For example, DateOnly still doesn't work: https://github.com/nickdodd79/AutoBogus/issues/76

Just closing to keep your issue tracker clean. bchavez/Bogus#74 (comment) The TLDR: merging can always be an option if or when the time is right.

Maybe now it the time right.

bchavez commented 1 year ago

@304NotModified, thinking about it a bit, I think I would probably take a different approach in 2023 and use Source Generators instead of on-the-fly-runtime-reflection and runtime-only-rule generation (which I think AutoBogus still employs); it was a good solution at the time, but we have some new tools at our disposal.

It's probably not very different from how Bogus Premium Tools Analyzer does it; but that's a paid/premium feature for the OSS project.

I think, with Source Generators, a big benefit would be to see what source code is being generated which could help with troubleshooting large object graphs and relations via F12 navigation.

The real trick part to solve would probably be how to weave seed/determinism into source-generated code. That is, how do you not destroy a deterministic sequence just by adding a new Field or Property in the source-generated code?

CaptaiNiveau commented 5 months ago

It's probably not very different from how Bogus Premium Tools Analyzer does it; but that's a paid/premium feature for the OSS project.

Would it be possible to access that code? Not sure how much I can achieve, but I'd like to dabble around with source generation and that would probably provide a good starting point. There's also an error with them, where the indentation of the generated code is off and rules for virtual properties that are overridden in the parent class are generated twice (or more). Maybe I'd be able to fix that, too.

Recently, I've implemented the creation of deterministic test data using Bogus in our application. AutoBogus wasn't really an option because of its extreme slowdown with reflection changes in .net 6+ which are fixable, but AutoBogus isn't maintained anymore. So a built in version based on source generators would be really cool.